summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-10-19 20:38:59 +0200
committerSergei Golubchik <sergii@pisem.net>2012-10-19 20:38:59 +0200
commite1f681c99b3e5462c033aaafa94ac295e626cde2 (patch)
tree2da5eff1a0d03831c2d85b32a7bc3df6ec37b522 /storage
parent52c84d144d3b07966d9b3bab8694eb012eef69ce (diff)
parent807fef40fffbbb8e92564a52b902b504ba8cfcdc (diff)
downloadmariadb-git-e1f681c99b3e5462c033aaafa94ac295e626cde2.tar.gz
10.0-base -> 10.0-monty
Diffstat (limited to 'storage')
-rw-r--r--storage/archive/azio.c27
-rw-r--r--storage/archive/ha_archive.cc27
-rw-r--r--storage/example/ha_example.cc5
-rw-r--r--storage/example/mysql-test/mtr/suite.pm8
-rw-r--r--storage/heap/hp_block.c23
-rw-r--r--storage/heap/hp_create.c23
-rw-r--r--storage/heap/hp_hash.c9
-rw-r--r--storage/innobase/btr/btr0btr.cc2
-rw-r--r--storage/innobase/buf/buf0buf.cc9
-rw-r--r--storage/innobase/buf/buf0lru.cc14
-rw-r--r--storage/innobase/buf/buf0rea.cc47
-rw-r--r--storage/innobase/dict/dict0dict.cc37
-rw-r--r--storage/innobase/ha/ha0ha.cc12
-rw-r--r--storage/innobase/handler/ha_innodb.cc191
-rw-r--r--storage/innobase/handler/handler0alter.cc18
-rw-r--r--storage/innobase/include/btr0btr.h3
-rw-r--r--storage/innobase/include/btr0types.h4
-rw-r--r--storage/innobase/include/buf0buf.h21
-rw-r--r--storage/innobase/include/dict0dict.h6
-rw-r--r--storage/innobase/include/trx0sys.h2
-rw-r--r--storage/innobase/log/log0recv.cc2
-rw-r--r--storage/innobase/mysql-test/storage_engine/alter_tablespace.opt2
-rw-r--r--storage/innobase/mysql-test/storage_engine/autoinc_secondary.rdiff30
-rw-r--r--storage/innobase/mysql-test/storage_engine/cache_index.rdiff71
-rw-r--r--storage/innobase/mysql-test/storage_engine/checksum_table_live.rdiff13
-rw-r--r--storage/innobase/mysql-test/storage_engine/define_engine.inc45
-rw-r--r--storage/innobase/mysql-test/storage_engine/disabled.def9
-rw-r--r--storage/innobase/mysql-test/storage_engine/fulltext_search.rdiff150
-rw-r--r--storage/innobase/mysql-test/storage_engine/index_enable_disable.rdiff33
-rw-r--r--storage/innobase/mysql-test/storage_engine/index_type_hash.rdiff60
-rw-r--r--storage/innobase/mysql-test/storage_engine/insert_delayed.rdiff26
-rw-r--r--storage/innobase/mysql-test/storage_engine/lock_concurrent.rdiff22
-rw-r--r--storage/innobase/mysql-test/storage_engine/optimize_table.rdiff37
-rw-r--r--storage/innobase/mysql-test/storage_engine/parts/checksum_table.rdiff22
-rw-r--r--storage/innobase/mysql-test/storage_engine/parts/create_table.rdiff20
-rw-r--r--storage/innobase/mysql-test/storage_engine/parts/optimize_table.rdiff58
-rw-r--r--storage/innobase/mysql-test/storage_engine/parts/repair_table.rdiff228
-rw-r--r--storage/innobase/mysql-test/storage_engine/parts/suite.opt4
-rw-r--r--storage/innobase/mysql-test/storage_engine/repair_table.rdiff129
-rw-r--r--storage/innobase/mysql-test/storage_engine/suite.opt4
-rw-r--r--storage/innobase/mysql-test/storage_engine/tbl_opt_data_index_dir.rdiff18
-rw-r--r--storage/innobase/mysql-test/storage_engine/tbl_opt_insert_method.rdiff11
-rw-r--r--storage/innobase/mysql-test/storage_engine/tbl_opt_key_block_size.opt3
-rw-r--r--storage/innobase/mysql-test/storage_engine/tbl_opt_row_format.opt3
-rw-r--r--storage/innobase/mysql-test/storage_engine/tbl_opt_row_format.rdiff10
-rw-r--r--storage/innobase/mysql-test/storage_engine/tbl_opt_union.rdiff16
-rw-r--r--storage/innobase/mysql-test/storage_engine/trx/disabled.def2
-rw-r--r--storage/innobase/mysql-test/storage_engine/trx/suite.opt5
-rw-r--r--storage/innobase/mysql-test/storage_engine/type_char_indexes.rdiff20
-rw-r--r--storage/innobase/mysql-test/storage_engine/type_float_indexes.rdiff11
-rw-r--r--storage/innobase/mysql-test/storage_engine/type_spatial_indexes.rdiff712
-rw-r--r--storage/innobase/mysql-test/storage_engine/vcol.rdiff82
-rw-r--r--storage/innobase/row/row0ins.cc6
-rw-r--r--storage/innobase/row/row0vers.cc12
-rw-r--r--storage/innobase/trx/trx0trx.cc11
-rw-r--r--storage/maria/CMakeLists.txt2
-rw-r--r--storage/maria/ha_maria.cc24
-rw-r--r--storage/maria/ha_maria.h7
-rw-r--r--storage/maria/ma_blockrec.c2
-rw-r--r--storage/maria/ma_ft_nlq_search.c2
-rw-r--r--storage/maria/ma_key_recover.c6
-rw-r--r--storage/maria/ma_pagecache.c1
-rw-r--r--storage/maria/ma_search.c4
-rwxr-xr-xstorage/maria/ma_test_all.sh13
-rw-r--r--storage/maria/maria_chk.c3
-rw-r--r--storage/myisam/CMakeLists.txt2
-rw-r--r--storage/myisam/ft_boolean_search.c16
-rw-r--r--storage/myisam/ft_nlq_search.c19
-rw-r--r--storage/myisam/ha_myisam.cc22
-rw-r--r--storage/myisam/ha_myisam.h7
-rw-r--r--storage/myisam/mi_extra.c2
-rwxr-xr-xstorage/myisam/mi_test_all.sh2
-rw-r--r--storage/myisam/myisamchk.c3
-rw-r--r--storage/myisam/mysql-test/mtr2/suite.pm9
-rw-r--r--storage/myisam/mysql-test/storage_engine/alter_tablespace.rdiff32
-rw-r--r--storage/myisam/mysql-test/storage_engine/check_table.rdiff20
-rw-r--r--storage/myisam/mysql-test/storage_engine/define_engine.inc45
-rw-r--r--storage/myisam/mysql-test/storage_engine/foreign_keys.rdiff145
-rw-r--r--storage/myisam/mysql-test/storage_engine/index_type_hash.rdiff60
-rw-r--r--storage/myisam/mysql-test/storage_engine/show_engine.rdiff10
-rw-r--r--storage/myisam/mysql-test/storage_engine/tbl_opt_insert_method.rdiff11
-rw-r--r--storage/myisam/mysql-test/storage_engine/tbl_opt_union.rdiff16
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/cons_snapshot_repeatable_read.rdiff9
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/cons_snapshot_serializable.rdiff9
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/delete.rdiff50
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/insert.rdiff65
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/level_read_committed.rdiff44
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/level_read_uncommitted.rdiff7
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/level_repeatable_read.rdiff53
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/level_serializable.rdiff69
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/select_for_update.rdiff50
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/select_lock_in_share_mode.rdiff37
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/update.rdiff58
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/xa.rdiff89
-rw-r--r--storage/myisam/mysql-test/storage_engine/trx/xa_recovery.rdiff33
-rw-r--r--storage/myisammrg/ha_myisammrg.cc41
-rw-r--r--storage/myisammrg/ha_myisammrg.h6
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/alter_table.inc116
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/alter_table.rdiff68
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/alter_tablespace.rdiff27
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/analyze_table.rdiff22
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/autoincrement.rdiff34
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/cache_index.rdiff46
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/char_indexes.rdiff0
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/checksum_table_live.rdiff6
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/cleanup_engine.inc16
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/create_table.inc208
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/create_table.rdiff37
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/define_engine.inc49
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/disabled.def2
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/foreign_keys.rdiff138
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/fulltext_search.rdiff142
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/handler.rdiff79
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/index.rdiff6
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/index_enable_disable.rdiff17
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/index_type_btree.rdiff6
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/index_type_hash.rdiff34
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/insert_delayed.rdiff14
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/lock.rdiff62
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/optimize_table.rdiff24
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/parts/alter_table.rdiff63
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/parts/analyze_table.rdiff83
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/parts/check_table.rdiff172
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/parts/checksum_table.rdiff81
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/parts/create_table.rdiff156
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/parts/optimize_table.rdiff91
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/parts/repair_table.rdiff295
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/parts/truncate_table.rdiff100
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/repair_table.rdiff103
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/show_engine.rdiff2
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_ai.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_avg_row_length.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_checksum.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_connection.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_data_index_dir.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_delay_key_write.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_insert_method.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_key_block_size.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_max_rows.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_min_rows.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_pack_keys.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_password.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_row_format.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_opt_union.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_standard_opts.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/tbl_temporary.rdiff4
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/truncate_table.rdiff35
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/cons_snapshot_repeatable_read.rdiff9
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/cons_snapshot_serializable.rdiff9
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/delete.rdiff34
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/insert.rdiff32
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/level_read_committed.rdiff44
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/level_read_uncommitted.rdiff7
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/level_repeatable_read.rdiff53
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/level_serializable.rdiff69
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/select_for_update.rdiff40
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/select_lock_in_share_mode.rdiff26
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/update.rdiff41
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/xa.rdiff34
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/trx/xa_recovery.rdiff22
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/type_char_indexes.rdiff8
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/type_float_indexes.rdiff4
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/type_spatial.rdiff706
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/type_spatial_indexes.rdiff1412
-rw-r--r--storage/myisammrg/mysql-test/storage_engine/vcol.rdiff79
-rw-r--r--storage/oqgraph/CMakeLists.txt22
-rw-r--r--storage/sphinx/ha_sphinx.cc12
-rw-r--r--storage/xtradb/btr/btr0btr.c6
-rw-r--r--storage/xtradb/btr/btr0cur.c2
-rw-r--r--storage/xtradb/buf/buf0buf.c11
-rw-r--r--storage/xtradb/buf/buf0flu.c9
-rw-r--r--storage/xtradb/buf/buf0lru.c51
-rw-r--r--storage/xtradb/buf/buf0rea.c47
-rw-r--r--storage/xtradb/dict/dict0dict.c42
-rw-r--r--storage/xtradb/dict/dict0load.c4
-rw-r--r--storage/xtradb/dict/dict0mem.c4
-rw-r--r--storage/xtradb/fil/fil0fil.c9
-rw-r--r--storage/xtradb/ha/ha0ha.c16
-rw-r--r--storage/xtradb/handler/ha_innodb.cc157
-rw-r--r--storage/xtradb/handler/ha_innodb.h1
-rw-r--r--storage/xtradb/handler/handler0alter.cc18
-rw-r--r--storage/xtradb/handler/i_s.cc312
-rw-r--r--storage/xtradb/handler/i_s.h2
-rw-r--r--storage/xtradb/include/btr0btr.h3
-rw-r--r--storage/xtradb/include/btr0types.h4
-rw-r--r--storage/xtradb/include/buf0buf.h23
-rw-r--r--storage/xtradb/include/buf0buf.ic2
-rw-r--r--storage/xtradb/include/dict0dict.h5
-rw-r--r--storage/xtradb/include/dict0dict.ic2
-rw-r--r--storage/xtradb/include/ha_prototypes.h11
-rw-r--r--storage/xtradb/include/log0log.h2
-rw-r--r--storage/xtradb/include/os0file.h2
-rw-r--r--storage/xtradb/include/srv0srv.h3
-rw-r--r--storage/xtradb/include/trx0sys.h4
-rw-r--r--storage/xtradb/include/trx0trx.h1
-rw-r--r--storage/xtradb/include/univ.i5
-rw-r--r--storage/xtradb/log/log0recv.c2
-rw-r--r--storage/xtradb/mem/mem0dbg.c4
-rw-r--r--storage/xtradb/os/os0file.c2
-rw-r--r--storage/xtradb/page/page0zip.c2
-rw-r--r--storage/xtradb/row/row0ins.c6
-rw-r--r--storage/xtradb/row/row0merge.c188
-rw-r--r--storage/xtradb/row/row0vers.c11
-rw-r--r--storage/xtradb/srv/srv0start.c3
-rw-r--r--storage/xtradb/sync/sync0arr.c5
-rw-r--r--storage/xtradb/trx/trx0sys.c2
-rw-r--r--storage/xtradb/trx/trx0trx.c11
-rw-r--r--storage/xtradb/ut/ut0dbg.c6
-rw-r--r--storage/xtradb/ut/ut0ut.c8
209 files changed, 9220 insertions, 389 deletions
diff --git a/storage/archive/azio.c b/storage/archive/azio.c
index 8fc85965cf0..92d7ad70344 100644
--- a/storage/archive/azio.c
+++ b/storage/archive/azio.c
@@ -39,6 +39,10 @@ void putLong(File file, uLong x);
uLong getLong(azio_stream *s);
void read_header(azio_stream *s, unsigned char *buffer);
+#ifdef HAVE_PSI_INTERFACE
+extern PSI_file_key arch_key_file_data;
+#endif
+
/* ===========================================================================
Opens a gzip (.gz) file for reading or writing. The mode parameter
is as in fopen ("rb" or "wb"). The file is given either by file descriptor
@@ -115,7 +119,7 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd)
s->stream.avail_out = AZ_BUFSIZE_WRITE;
errno = 0;
- s->file = fd < 0 ? my_open(path, Flags, MYF(0)) : fd;
+ s->file = fd < 0 ? mysql_file_open(arch_key_file_data, path, Flags, MYF(0)) : fd;
DBUG_EXECUTE_IF("simulate_archive_open_failure",
{
if (s->file >= 0)
@@ -248,8 +252,8 @@ int get_byte(s)
if (s->stream.avail_in == 0)
{
errno = 0;
- s->stream.avail_in= (uInt) my_read(s->file, (uchar *)s->inbuf,
- AZ_BUFSIZE_READ, MYF(0));
+ s->stream.avail_in= (uInt) mysql_file_read(s->file, (uchar *)s->inbuf,
+ AZ_BUFSIZE_READ, MYF(0));
if (s->stream.avail_in == 0)
{
s->z_eof = 1;
@@ -290,7 +294,8 @@ void check_header(azio_stream *s)
if (len < 2) {
if (len) s->inbuf[0] = s->stream.next_in[0];
errno = 0;
- len = (uInt)my_read(s->file, (uchar *)s->inbuf + len, AZ_BUFSIZE_READ >> len, MYF(0));
+ len = (uInt)mysql_file_read(s->file, (uchar *)s->inbuf + len,
+ AZ_BUFSIZE_READ >> len, MYF(0));
if (len == (uInt)-1) s->z_err = Z_ERRNO;
s->stream.avail_in += len;
s->stream.next_in = s->inbuf;
@@ -481,7 +486,8 @@ unsigned int ZEXPORT azread ( azio_stream *s, voidp buf, size_t len, int *error)
if (s->stream.avail_out > 0)
{
s->stream.avail_out -=
- (uInt)my_read(s->file, (uchar *)next_out, s->stream.avail_out, MYF(0));
+ (uInt)mysql_file_read(s->file, (uchar *)next_out,
+ s->stream.avail_out, MYF(0));
}
len -= s->stream.avail_out;
s->in += len;
@@ -494,7 +500,8 @@ unsigned int ZEXPORT azread ( azio_stream *s, voidp buf, size_t len, int *error)
if (s->stream.avail_in == 0 && !s->z_eof) {
errno = 0;
- s->stream.avail_in = (uInt)my_read(s->file, (uchar *)s->inbuf, AZ_BUFSIZE_READ, MYF(0));
+ s->stream.avail_in = (uInt)mysql_file_read(s->file, (uchar *)s->inbuf,
+ AZ_BUFSIZE_READ, MYF(0));
if (s->stream.avail_in == 0)
{
s->z_eof = 1;
@@ -561,8 +568,8 @@ unsigned int azwrite (azio_stream *s, const voidp buf, unsigned int len)
{
s->stream.next_out = s->outbuf;
- if (my_write(s->file, (uchar *)s->outbuf, AZ_BUFSIZE_WRITE,
- MYF(0)) != AZ_BUFSIZE_WRITE)
+ if (mysql_file_write(s->file, (uchar *)s->outbuf, AZ_BUFSIZE_WRITE,
+ MYF(0)) != AZ_BUFSIZE_WRITE)
{
s->z_err = Z_ERRNO;
break;
@@ -609,7 +616,7 @@ int do_flush (azio_stream *s, int flush)
if (len != 0)
{
s->check_point= my_tell(s->file, MYF(0));
- if ((uInt)my_write(s->file, (uchar *)s->outbuf, len, MYF(0)) != len)
+ if ((uInt)mysql_file_write(s->file, (uchar *)s->outbuf, len, MYF(0)) != len)
{
s->z_err = Z_ERRNO;
return Z_ERRNO;
@@ -796,7 +803,7 @@ void putLong (File file, uLong x)
for (n = 0; n < 4; n++)
{
buffer[0]= (int)(x & 0xff);
- my_write(file, buffer, 1, MYF(0));
+ mysql_file_write(file, buffer, 1, MYF(0));
x >>= 8;
}
}
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 430f0373919..8376ebc9826 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -112,6 +112,10 @@ static HASH archive_open_tables;
#define DATA_BUFFER_SIZE 2 // Size of the data used in the data file
#define ARCHIVE_CHECK_HEADER 254 // The number we use to determine corruption
+#ifdef HAVE_PSI_INTERFACE
+extern "C" PSI_file_key arch_key_file_data;
+#endif
+
/* Static declarations for handerton */
static handler *archive_create_handler(handlerton *hton,
TABLE_SHARE *table,
@@ -157,6 +161,14 @@ static PSI_mutex_info all_archive_mutexes[]=
{ &az_key_mutex_ARCHIVE_SHARE_mutex, "ARCHIVE_SHARE::mutex", 0}
};
+PSI_file_key arch_key_file_metadata, arch_key_file_data, arch_key_file_frm;
+static PSI_file_info all_archive_files[]=
+{
+ { &arch_key_file_metadata, "metadata", 0},
+ { &arch_key_file_data, "data", 0},
+ { &arch_key_file_frm, "FRM", 0}
+};
+
static void init_archive_psi_keys(void)
{
const char* category= "archive";
@@ -167,6 +179,9 @@ static void init_archive_psi_keys(void)
count= array_elements(all_archive_mutexes);
PSI_server->register_mutex(category, all_archive_mutexes, count);
+
+ count= array_elements(all_archive_files);
+ PSI_server->register_file(category, all_archive_files, count);
}
#endif /* HAVE_PSI_INTERFACE */
@@ -260,7 +275,7 @@ int archive_discover(handlerton *hton, THD* thd, const char *db,
build_table_filename(az_file, sizeof(az_file) - 1, db, name, ARZ, 0);
- if (!(my_stat(az_file, &file_stat, MYF(0))))
+ if (!(mysql_file_stat(arch_key_file_data, az_file, &file_stat, MYF(0))))
goto err;
if (!(azopen(&frm_stream, az_file, O_RDONLY|O_BINARY)))
@@ -723,7 +738,7 @@ int ha_archive::create(const char *name, TABLE *table_arg,
There is a chance that the file was "discovered". In this case
just use whatever file is there.
*/
- if (!(my_stat(name_buff, &file_stat, MYF(0))))
+ if (!(mysql_file_stat(arch_key_file_data, name_buff, &file_stat, MYF(0))))
{
my_errno= 0;
if (!(azopen(&create_stream, name_buff, O_CREAT|O_RDWR|O_BINARY)))
@@ -740,19 +755,19 @@ int ha_archive::create(const char *name, TABLE *table_arg,
/*
Here is where we open up the frm and pass it to archive to store
*/
- if ((frm_file= my_open(name_buff, O_RDONLY, MYF(0))) > 0)
+ if ((frm_file= mysql_file_open(arch_key_file_frm, name_buff, O_RDONLY, MYF(0))) >= 0)
{
if (!mysql_file_fstat(frm_file, &file_stat, MYF(MY_WME)))
{
frm_ptr= (uchar *)my_malloc(sizeof(uchar) * (size_t)file_stat.st_size, MYF(0));
if (frm_ptr)
{
- my_read(frm_file, frm_ptr, (size_t)file_stat.st_size, MYF(0));
+ mysql_file_read(frm_file, frm_ptr, (size_t)file_stat.st_size, MYF(0));
azwrite_frm(&create_stream, (char *)frm_ptr, (size_t)file_stat.st_size);
my_free(frm_ptr);
}
}
- my_close(frm_file, MYF(0));
+ mysql_file_close(frm_file, MYF(0));
}
if (create_info->comment.str)
@@ -1610,7 +1625,7 @@ int ha_archive::info(uint flag)
{
MY_STAT file_stat; // Stat information for the data file
- (void) my_stat(share->data_file_name, &file_stat, MYF(MY_WME));
+ (void) mysql_file_stat(arch_key_file_data, share->data_file_name, &file_stat, MYF(MY_WME));
if (flag & HA_STATUS_TIME)
stats.update_time= (ulong) file_stat.st_mtime;
diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc
index 91ead36fcea..98968d0b5b5 100644
--- a/storage/example/ha_example.cc
+++ b/storage/example/ha_example.cc
@@ -1095,7 +1095,8 @@ static struct st_mysql_sys_var* example_system_variables[]= {
NULL
};
-// this is an example of SHOW_FUNC and of my_snprintf() service
+// this is an example of SHOW_SIMPLE_FUNC and of my_snprintf() service
+// If this function would return an array, one should use SHOW_FUNC
static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var,
char *buf)
{
@@ -1109,7 +1110,7 @@ static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var,
static struct st_mysql_show_var func_status[]=
{
- {"example_func_example", (char *)show_func_example, SHOW_FUNC},
+ {"example_func_example", (char *)show_func_example, SHOW_SIMPLE_FUNC},
{0,0,SHOW_UNDEF}
};
diff --git a/storage/example/mysql-test/mtr/suite.pm b/storage/example/mysql-test/mtr/suite.pm
new file mode 100644
index 00000000000..f7ff42241fe
--- /dev/null
+++ b/storage/example/mysql-test/mtr/suite.pm
@@ -0,0 +1,8 @@
+package My::Suite::MTR::Example;
+
+@ISA = qw(My::Suite);
+
+sub skip_combinations {(
+ 't/combs.combinations' => [ 'c1' ],
+)}
+bless { };
diff --git a/storage/heap/hp_block.c b/storage/heap/hp_block.c
index 90efeeb7924..01978e2b4e8 100644
--- a/storage/heap/hp_block.c
+++ b/storage/heap/hp_block.c
@@ -64,18 +64,19 @@ int hp_get_new_block(HP_BLOCK *block, size_t *alloc_length)
break;
/*
- Allocate space for leaf block plus space for upper level blocks up to
- first level that has a free slot to put the pointer.
- In some cases we actually allocate more then we need:
- Consider e.g. a situation where we have one level 1 block and one level 0
- block, the level 0 block is full and this function is called. We only
- need a leaf block in this case. Nevertheless, we will get here with i=1
- and will also allocate sizeof(HP_PTRS) for non-leaf block and will never
- use this space.
- This doesn't add much overhead - with current values of sizeof(HP_PTRS)
- and my_default_record_cache_size we get about 1/128 unused memory.
+ Allocate space for leaf block (data) plus space for upper level blocks
+ up to first level that has a free slot to put the pointer.
+ If this is a new level, we have to allocate pointers to all future
+ lower levels.
+
+ For example, for level 0, we allocate data for X rows.
+ When level 0 is full, we allocate data for HPTRS_IN_NODE + X rows.
+ Next time we allocate data for X rows.
+ When level 1 is full, we allocate data for HPTRS_IN_NODE at level 2 and 1
+ + X rows at level 0.
*/
- *alloc_length=sizeof(HP_PTRS)*i+block->records_in_block* block->recbuffer;
+ *alloc_length= (sizeof(HP_PTRS)* ((i == block->levels) ? i : i - 1) +
+ block->records_in_block* block->recbuffer);
if (!(root=(HP_PTRS*) my_malloc(*alloc_length,MYF(MY_WME))))
return 1;
diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c
index 22ab9b54a85..d170d1abc65 100644
--- a/storage/heap/hp_create.c
+++ b/storage/heap/hp_create.c
@@ -245,21 +245,32 @@ static void init_block(HP_BLOCK *block, uint reclength, ulong min_records,
{
uint i,recbuffer,records_in_block;
- max_records= max(min_records,max_records);
+ /*
+ If not min_records and max_records are given, optimize for 1000 rows
+ */
+ if (!min_records)
+ min_records= min(1000, max_records);
if (!max_records)
- max_records= 1000; /* As good as quess as anything */
- recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
- records_in_block= max_records / 10;
+ max_records= max(min_records, 1000);
/*
We don't want too few records_in_block as otherwise the overhead of
of the HP_PTRS block will be too notable
*/
- records_in_block= min(1000, max_records);
+ records_in_block= max(1000, min_records);
+ records_in_block= min(records_in_block, max_records);
+ /* If big max_records is given, allocate bigger blocks */
+ records_in_block= max(records_in_block, max_records / 10);
+ /* We don't want too few blocks per row either */
if (records_in_block < 10)
records_in_block= 10;
- /* The + 1 is there to ensure that we get at least 1 row per level */
+ recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
+ /*
+ Don't allocate more than my_default_record_cache_size per level.
+ The + 1 is there to ensure that we get at least 1 row per level (for
+ the exceptional case of very long rows)
+ */
if (records_in_block*recbuffer >
(my_default_record_cache_size-sizeof(HP_PTRS)*HP_MAX_LEVELS))
records_in_block= (my_default_record_cache_size - sizeof(HP_PTRS) *
diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c
index d44726ba762..2abed55459c 100644
--- a/storage/heap/hp_hash.c
+++ b/storage/heap/hp_hash.c
@@ -348,6 +348,8 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const uchar *rec)
seg->length/cs->mbmaxlen);
set_if_smaller(length, char_length);
}
+ else
+ set_if_smaller(length, seg->length);
cs->coll->hash_sort(cs, pos+pack_length, length, &nr, &nr2);
}
else
@@ -593,6 +595,11 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const uchar *rec1, const uchar *rec2,
char_length2= my_charpos(cs, pos2, pos2 + char_length2, char_length);
set_if_smaller(char_length2, safe_length2);
}
+ else
+ {
+ set_if_smaller(char_length1, seg->length);
+ set_if_smaller(char_length2, seg->length);
+ }
if (cs->coll->strnncollsp(seg->charset,
pos1, char_length1,
@@ -689,6 +696,8 @@ int hp_key_cmp(HP_KEYDEF *keydef, const uchar *rec, const uchar *key)
char_length2= my_charpos(cs, pos, pos + char_length_rec, char_length2);
set_if_smaller(char_length_rec, char_length2);
}
+ else
+ set_if_smaller(char_length_rec, seg->length);
if (cs->coll->strnncollsp(seg->charset,
(uchar*) pos, char_length_rec,
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc
index 60babcb3b74..760bed8de8c 100644
--- a/storage/innobase/btr/btr0btr.cc
+++ b/storage/innobase/btr/btr0btr.cc
@@ -43,6 +43,7 @@ Created 6/2/1994 Heikki Tuuri
#include "trx0trx.h"
#include "srv0mon.h"
+#endif /* UNIV_HOTBACKUP */
/**************************************************************//**
Report that an index page is corrupted. */
UNIV_INTERN
@@ -65,6 +66,7 @@ btr_corruption_report(
buf_page_print(buf_block_get_frame(block), 0, 0);
}
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_BLOB_DEBUG
# include "srv0srv.h"
# include "ut0rbt.h"
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 2ae668ace50..2b543d8d1cf 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -3866,9 +3866,10 @@ buf_mark_space_corrupt(
/********************************************************************//**
Completes an asynchronous read or write request of a file page to or from
-the buffer pool. */
+the buffer pool.
+@return TRUE if successful */
UNIV_INTERN
-void
+ibool
buf_page_io_complete(
/*=================*/
buf_page_t* bpage) /*!< in: pointer to the block in question */
@@ -3995,7 +3996,7 @@ corrupt:
table as corrupted instead of crashing server */
if (bpage->space > TRX_SYS_SPACE
&& buf_mark_space_corrupt(bpage)) {
- return;
+ return(FALSE);
} else {
fputs("InnoDB: Ending processing"
" because of"
@@ -4087,6 +4088,8 @@ corrupt:
mutex_exit(buf_page_get_mutex(bpage));
buf_pool_mutex_exit(buf_pool);
+
+ return(TRUE);
}
/*********************************************************************//**
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 92883269d42..1e2c15f969f 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -1993,9 +1993,23 @@ buf_LRU_free_one_page(
be in a state where it can be freed; there
may or may not be a hash index to the page */
{
+#ifdef UNIV_DEBUG
+ buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+#endif
+ mutex_t* block_mutex = buf_page_get_mutex(bpage);
+
+ ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(block_mutex));
+
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
!= BUF_BLOCK_ZIP_FREE) {
buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
+ } else {
+ /* The block_mutex should have been released by
+ buf_LRU_block_remove_hashed_page() when it returns
+ BUF_BLOCK_ZIP_FREE. */
+ ut_ad(block_mutex == &buf_pool->zip_mutex);
+ mutex_enter(block_mutex);
}
}
diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc
index 1b3e5deed05..227cb083725 100644
--- a/storage/innobase/buf/buf0rea.cc
+++ b/storage/innobase/buf/buf0rea.cc
@@ -52,6 +52,44 @@ i/o-fixed buffer blocks */
#define BUF_READ_AHEAD_PEND_LIMIT 2
/********************************************************************//**
+Unfixes the pages, unlatches the page,
+removes it from page_hash and removes it from LRU. */
+static
+void
+buf_read_page_handle_error(
+/*=======================*/
+ buf_page_t* bpage) /*!< in: pointer to the block */
+{
+ buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+ const ibool uncompressed = (buf_page_get_state(bpage)
+ == BUF_BLOCK_FILE_PAGE);
+
+ /* First unfix and release lock on the bpage */
+ buf_pool_mutex_enter(buf_pool);
+ mutex_enter(buf_page_get_mutex(bpage));
+ ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ);
+ ut_ad(bpage->buf_fix_count == 0);
+
+ /* Set BUF_IO_NONE before we remove the block from LRU list */
+ buf_page_set_io_fix(bpage, BUF_IO_NONE);
+
+ if (uncompressed) {
+ rw_lock_x_unlock_gen(
+ &((buf_block_t*) bpage)->lock,
+ BUF_IO_READ);
+ }
+
+ /* remove the block from LRU list */
+ buf_LRU_free_one_page(bpage);
+
+ ut_ad(buf_pool->n_pend_reads > 0);
+ buf_pool->n_pend_reads--;
+
+ mutex_exit(buf_page_get_mutex(bpage));
+ buf_pool_mutex_exit(buf_pool);
+}
+
+/********************************************************************//**
Low-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there, in which case does nothing.
Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
@@ -154,6 +192,11 @@ buf_read_page_low(
}
thd_wait_end(NULL);
+ if (*err == DB_TABLESPACE_DELETED) {
+ buf_read_page_handle_error(bpage);
+ return(0);
+ }
+
if (*err != DB_SUCCESS) {
if (ignore_nonexistent_pages) {
return(0);
@@ -165,7 +208,9 @@ buf_read_page_low(
if (sync) {
/* The i/o is already completed when we arrive from
fil_read */
- buf_page_io_complete(bpage);
+ if (!buf_page_io_complete(bpage)) {
+ return(0);
+ }
}
return(1);
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index c97207c92be..5871281e1b9 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -185,6 +185,7 @@ void
dict_field_print_low(
/*=================*/
const dict_field_t* field); /*!< in: field */
+#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Frees a foreign key struct. */
static
@@ -242,7 +243,7 @@ and unique key errors */
UNIV_INTERN FILE* dict_foreign_err_file = NULL;
/* mutex protecting the foreign and unique error buffers */
UNIV_INTERN mutex_t dict_foreign_err_mutex;
-
+#endif /* !UNIV_HOTBACKUP */
/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
UNIV_INTERN
@@ -2808,6 +2809,8 @@ dict_index_build_internal_fts(
return(new_index);
}
+
+#ifndef UNIV_HOTBACKUP
/*====================== FOREIGN KEY PROCESSING ========================*/
/*********************************************************************//**
@@ -3071,6 +3074,7 @@ dict_foreign_find_equiv_index(
FALSE/* allow columns to be NULL */));
}
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Returns an index object by matching on the name and column names and
if more than one index matches return the index with the max id
@@ -3130,6 +3134,7 @@ dict_table_get_index_by_max_id(
return(found);
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Report an error in a foreign key definition. */
static
@@ -3308,6 +3313,7 @@ dict_foreign_add_to_cache(
return(DB_SUCCESS);
}
+#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
Scans from pointer onwards. Stops if is at the start of a copy of
'string' where characters are compared without case sensitivity, and
@@ -3792,6 +3798,7 @@ end_of_string:
}
}
+#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Finds the highest [number] for foreign key constraints of the table. Looks
only at the >= 4.0.18-format id's, which are of the form
@@ -4649,7 +4656,7 @@ syntax_error:
}
/*==================== END OF FOREIGN KEY PROCESSING ====================*/
-
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Returns an index object if it is found in the dictionary cache.
Assumes that dict_sys->mutex is already being held.
@@ -4889,6 +4896,7 @@ dict_index_calc_min_rec_len(
return(sum);
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Prints info of a foreign key constraint. */
static
@@ -4919,6 +4927,7 @@ dict_foreign_print_low(
fputs(" )\n", stderr);
}
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Prints a table data. */
UNIV_INTERN
@@ -5100,6 +5109,7 @@ dict_field_print_low(
}
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Outputs info on a foreign key of a table in a format suitable for
CREATE TABLE. */
@@ -5288,6 +5298,7 @@ dict_print_info_on_foreign_keys(
mutex_exit(&(dict_sys->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Displays the names of the index and the table. */
UNIV_INTERN
@@ -5608,6 +5619,28 @@ dict_table_replace_index_in_foreign_list(
foreign->foreign_index = new_index;
}
}
+
+
+ for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
+ foreign;
+ foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
+
+ dict_index_t* new_index;
+
+ if (foreign->referenced_index == index) {
+ ut_ad(foreign->referenced_table == index->table);
+
+ new_index = dict_foreign_find_index(
+ foreign->referenced_table,
+ foreign->referenced_col_names,
+ foreign->n_fields, index,
+ /*check_charsets=*/TRUE, /*check_null=*/FALSE);
+ ut_ad(new_index || !trx->check_foreigns);
+ ut_ad(!new_index || new_index->table == index->table);
+
+ foreign->referenced_index = new_index;
+ }
+ }
}
/**********************************************************************//**
diff --git a/storage/innobase/ha/ha0ha.cc b/storage/innobase/ha/ha0ha.cc
index dd99e3afae5..b58dc486cfa 100644
--- a/storage/innobase/ha/ha0ha.cc
+++ b/storage/innobase/ha/ha0ha.cc
@@ -28,6 +28,7 @@ Created 8/22/1994 Heikki Tuuri
#include "ha0ha.ic"
#endif
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_DEBUG
# include "buf0buf.h"
#endif /* UNIV_DEBUG */
@@ -59,9 +60,7 @@ ha_create_func(
MEM_HEAP_FOR_PAGE_HASH */
{
hash_table_t* table;
-#ifndef UNIV_HOTBACKUP
ulint i;
-#endif /* !UNIV_HOTBACKUP */
ut_a(type == MEM_HEAP_FOR_BTR_SEARCH
|| type == MEM_HEAP_FOR_PAGE_HASH);
@@ -205,7 +204,6 @@ ha_insert_for_fold_func(
while (prev_node != NULL) {
if (prev_node->fold == fold) {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
buf_block_t* prev_block = prev_node->block;
ut_a(prev_block->frame
@@ -214,7 +212,6 @@ ha_insert_for_fold_func(
prev_block->n_pointers--;
block->n_pointers++;
}
-# endif /* !UNIV_HOTBACKUP */
prev_node->block = block;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -243,11 +240,9 @@ ha_insert_for_fold_func(
ha_node_set_data(node, block, (rec_t*) data);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
block->n_pointers++;
}
-# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
node->fold = fold;
@@ -289,13 +284,11 @@ ha_delete_hash_node(
#endif /* UNIV_SYNC_DEBUG */
ut_ad(btr_search_enabled);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
ut_a(del_node->block->frame = page_align(del_node->data));
ut_a(del_node->block->n_pointers > 0);
del_node->block->n_pointers--;
}
-# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node);
@@ -337,13 +330,11 @@ ha_search_and_update_if_found_func(
if (node) {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
ut_a(node->block->n_pointers > 0);
node->block->n_pointers--;
new_block->n_pointers++;
}
-# endif /* !UNIV_HOTBACKUP */
node->block = new_block;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -355,7 +346,6 @@ ha_search_and_update_if_found_func(
return(FALSE);
}
-#ifndef UNIV_HOTBACKUP
/*****************************************************************//**
Removes from the chain determined by fold all nodes whose data pointer
points to the page given. */
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 9d8658e861c..5b3aa15a9a2 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -678,6 +678,15 @@ innobase_release_savepoint(
savepoint should be released */
void* savepoint); /*!< in: savepoint data */
+/*****************************************************************//**
+Handle a commit checkpoint request from server layer.
+We simply flush the redo log immediately and do the notify call.*/
+static
+void
+innobase_checkpoint_request(
+ handlerton *hton,
+ void *cookie);
+
/************************************************************************//**
Function for constructing an InnoDB table handler instance. */
static
@@ -1829,28 +1838,85 @@ ulonglong
innobase_next_autoinc(
/*==================*/
ulonglong current, /*!< in: Current value */
- ulonglong increment, /*!< in: increment current by */
+ ulonglong need, /*!< in: count of values needed */
+ ulonglong step, /*!< in: AUTOINC increment step */
ulonglong offset, /*!< in: AUTOINC offset */
- ulonglong max_value, /*!< in: max value for type */
- ulonglong reserve) /*!< in: how many values to reserve */
+ ulonglong max_value) /*!< in: max value for type */
{
ulonglong next_value;
+ ulonglong block = need * step;
/* Should never be 0. */
- ut_a(increment > 0);
+ ut_a(need > 0);
+ ut_a(block > 0);
+ ut_a(max_value > 0);
+
+ /*
+ Allow auto_increment to go over max_value up to max ulonglong.
+ This allows us to detect that all values are exhausted.
+ If we don't do this, we will return max_value several times
+ and get duplicate key errors instead of auto increment value
+ out of range.
+ */
+ max_value= (~(ulonglong) 0);
/* According to MySQL documentation, if the offset is greater than
- the increment then the offset is ignored. */
- if (offset >= increment)
+ the step then the offset is ignored. */
+ if (offset > block) {
offset = 0;
+ }
+
+ /* Check for overflow. */
+ if (block >= max_value
+ || offset > max_value
+ || current >= max_value
+ || max_value - offset <= offset) {
+
+ next_value = max_value;
+ } else {
+ ut_a(max_value > current);
+
+ ulonglong free = max_value - current;
+
+ if (free < offset || free - offset <= block) {
+ next_value = max_value;
+ } else {
+ next_value = 0;
+ }
+ }
+
+ if (next_value == 0) {
+ ulonglong next;
+
+ if (current > offset) {
+ next = (current - offset) / step;
+ } else {
+ next = (offset - current) / step;
+ }
+
+ ut_a(max_value > next);
+ next_value = next * step;
+ /* Check for multiplication overflow. */
+ ut_a(next_value >= next);
+ ut_a(max_value > next_value);
+
+ /* Check for overflow */
+ if (max_value - next_value >= block) {
- if (max_value <= current)
- return max_value;
- next_value = (current / increment) + reserve;
- next_value = next_value * increment + offset;
- /* Check for overflow. */
- if (next_value < current || next_value > max_value)
- next_value = max_value;
+ next_value += block;
+
+ if (max_value - next_value >= offset) {
+ next_value += offset;
+ } else {
+ next_value = max_value;
+ }
+ } else {
+ next_value = max_value;
+ }
+ }
+
+ ut_a(next_value != 0);
+ ut_a(next_value <= max_value);
return(next_value);
}
@@ -2585,6 +2651,7 @@ innobase_init(
innobase_hton->recover = innobase_xa_recover;
innobase_hton->commit_by_xid = innobase_commit_by_xid;
innobase_hton->rollback_by_xid = innobase_rollback_by_xid;
+ innobase_hton->commit_checkpoint_request=innobase_checkpoint_request;
innobase_hton->create_cursor_read_view = innobase_create_cursor_view;
innobase_hton->set_cursor_read_view = innobase_set_cursor_view;
innobase_hton->close_cursor_read_view = innobase_close_cursor_view;
@@ -3447,6 +3514,19 @@ innobase_rollback_trx(
}
/*****************************************************************//**
+Handle a commit checkpoint request from server layer.
+We simply flush the redo log immediately and do the notify call.*/
+static
+void
+innobase_checkpoint_request(
+ handlerton *hton,
+ void *cookie)
+{
+ log_buffer_flush_to_disk();
+ commit_checkpoint_notify_ha(hton, cookie);
+}
+
+/*****************************************************************//**
Rolls back a transaction to a savepoint.
@return 0 if success, HA_ERR_NO_SAVEPOINT if no savepoint with the
given name */
@@ -4290,7 +4370,7 @@ ha_innobase::innobase_initialize_autoinc()
nor the offset, so use a default increment of 1. */
auto_inc = innobase_next_autoinc(
- read_auto_inc, 1, 1, col_max_value, 1);
+ read_auto_inc, 1, 1, 0, col_max_value);
break;
}
case DB_RECORD_NOT_FOUND:
@@ -6201,7 +6281,10 @@ no_commit:
goto report_error;
}
- /* MySQL errors are passed straight back. */
+ /* MySQL errors are passed straight back. except for
+ HA_ERR_AUTO_INC_READ_FAILED. This can only happen
+ for values out of range.
+ */
error_result = (int) error;
goto func_exit;
}
@@ -6284,15 +6367,16 @@ set_max_autoinc:
if (auto_inc <= col_max_value) {
ut_a(prebuilt->autoinc_increment > 0);
- ulonglong need;
ulonglong offset;
+ ulonglong increment;
offset = prebuilt->autoinc_offset;
- need = prebuilt->autoinc_increment;
+ increment = prebuilt->autoinc_increment;
auto_inc = innobase_next_autoinc(
auto_inc,
- need, offset, col_max_value, 1);
+ 1, increment, offset,
+ col_max_value);
err = innobase_set_max_autoinc(
auto_inc);
@@ -6697,14 +6781,14 @@ ha_innobase::update_row(
if (auto_inc <= col_max_value && auto_inc != 0) {
- ulonglong need;
ulonglong offset;
+ ulonglong increment;
offset = prebuilt->autoinc_offset;
- need = prebuilt->autoinc_increment;
+ increment = prebuilt->autoinc_increment;
auto_inc = innobase_next_autoinc(
- auto_inc, need, offset, col_max_value, 1);
+ auto_inc, 1, increment, offset, col_max_value);
error = innobase_set_max_autoinc(auto_inc);
}
@@ -7014,6 +7098,7 @@ ha_innobase::index_read(
ulint ret;
DBUG_ENTER("index_read");
+ DEBUG_SYNC_C("ha_innobase_index_read_begin");
ut_a(prebuilt->trx == thd_to_trx(user_thd));
@@ -9814,10 +9899,15 @@ innobase_get_mysql_key_number_for_index(
}
}
- /* Print an error message if we cannot find the index
- ** in the "index translation table". */
- sql_print_error("Cannot find index %s in InnoDB index "
- "translation table.", index->name);
+ /* If index_count in translation table is set to 0, it
+ is possible we are in the process of rebuilding table,
+ do not spit error in this case */
+ if (share->idx_trans_tbl.index_count) {
+ /* Print an error message if we cannot find the index
+ ** in the "index translation table". */
+ sql_print_error("Cannot find index %s in InnoDB index "
+ "translation table.", index->name);
+ }
}
/* If we do not have an "index translation table", or not able
@@ -10220,9 +10310,10 @@ ha_innobase::info_low(
}
else if (rec_per_key > 1) {
rec_per_key =
- k_rec_per_key *
- (double)rec_per_key /
- n_rows;
+ (ha_rows)
+ (k_rec_per_key *
+ (double)rec_per_key /
+ n_rows);
}
key_info->rec_per_key[k++]=
@@ -11454,6 +11545,7 @@ innodb_show_status(
const long MAX_STATUS_SIZE = 1048576;
ulint trx_list_start = ULINT_UNDEFINED;
ulint trx_list_end = ULINT_UNDEFINED;
+ bool res;
DBUG_ENTER("innodb_show_status");
DBUG_ASSERT(hton == innodb_hton_ptr);
@@ -11523,12 +11615,13 @@ innodb_show_status(
mutex_exit(&srv_monitor_file_mutex);
- stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name),
- STRING_WITH_LEN(""), str, flen);
+ res= stat_print(thd, innobase_hton_name,
+ (uint) strlen(innobase_hton_name),
+ STRING_WITH_LEN(""), str, flen);
my_free(str);
- DBUG_RETURN(0);
+ DBUG_RETURN(res);
}
/************************************************************************//**
@@ -12188,13 +12281,17 @@ ha_innobase::get_auto_increment(
/* Not in the middle of a mult-row INSERT. */
} else if (prebuilt->autoinc_last_value == 0) {
set_if_bigger(*first_value, autoinc);
- /* Check for -ve values. */
- } else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) {
- /* Set to next logical value. */
- ut_a(autoinc > trx->n_autoinc_rows);
- *first_value = (autoinc - trx->n_autoinc_rows) - 1;
}
+ if (*first_value > col_max_value)
+ {
+ /* Out of range number. Let handler::update_auto_increment()
+ take care of this */
+ prebuilt->autoinc_last_value = 0;
+ dict_table_autoinc_unlock(prebuilt->table);
+ *nb_reserved_values= 0;
+ return;
+ }
*nb_reserved_values = trx->n_autoinc_rows;
/* With old style AUTOINC locking we only update the table's
@@ -12203,11 +12300,12 @@ ha_innobase::get_auto_increment(
ulonglong current;
ulonglong next_value;
- current = *first_value > col_max_value ? autoinc : *first_value;
-
+ current = *first_value;
+
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
- current, increment, offset, col_max_value, *nb_reserved_values);
+ current, *nb_reserved_values, increment, offset,
+ col_max_value);
prebuilt->autoinc_last_value = next_value;
@@ -14422,10 +14520,17 @@ static MYSQL_SYSVAR_STR(ft_server_stopword_table, innobase_server_stopword_table
static MYSQL_SYSVAR_ULONG(flush_log_at_trx_commit, srv_flush_log_at_trx_commit,
PLUGIN_VAR_OPCMDARG,
- "Set to 0 (write and flush once per second),"
- " 1 (write and flush at each commit)"
- " or 2 (write at commit, flush once per second).",
- NULL, NULL, 1, 0, 2, 0);
+ "Controls the durability/speed trade-off for commits."
+ " Set to 0 (write and flush redo log to disk only once per second),"
+ " 1 (flush to disk at each commit),"
+ " 2 (write to log at commit but flush to disk only once per second)"
+ " or 3 (flush to disk at prepare and at commit, slower and usually redundant)."
+ " 1 and 3 guarantees that after a crash, committed transactions will"
+ " not be lost and will be consistent with the binlog and other transactional"
+ " engines. 2 can get inconsistent and lose transactions if there is a"
+ " power failure or kernel crash but not if mysqld crashes. 0 has no"
+ " guarantees in case of crash. 0 and 2 can be faster than 1 or 3.",
+ NULL, NULL, 1, 0, 3, 0);
static MYSQL_SYSVAR_STR(flush_method, innobase_file_flush_method,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 32501299630..9de45527ec7 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -1061,6 +1061,10 @@ ha_innobase::add_index(
ut_a(indexed_table == prebuilt->table);
+ if (indexed_table->tablespace_discarded) {
+ DBUG_RETURN(-1);
+ }
+
/* Check that index keys are sensible */
error = innobase_check_index_keys(key_info, num_of_keys, prebuilt->table);
@@ -1162,7 +1166,7 @@ ha_innobase::add_index(
row_mysql_lock_data_dictionary(trx);
dict_locked = TRUE;
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
/* If a new primary key is defined for the table we need
to drop the original table and rebuild all indexes. */
@@ -1199,7 +1203,7 @@ ha_innobase::add_index(
}
ut_d(dict_table_check_for_dup_indexes(prebuilt->table,
- FALSE));
+ TRUE));
row_mysql_unlock_data_dictionary(trx);
mem_heap_free(heap);
@@ -1553,7 +1557,7 @@ ha_innobase::final_add_index(
trx_commit_for_mysql(prebuilt->trx);
}
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
ut_a(fts_check_cached_index(prebuilt->table));
@@ -1598,7 +1602,7 @@ ha_innobase::prepare_drop_index(
/* Test and mark all the indexes to be dropped */
row_mysql_lock_data_dictionary(trx);
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
/* Check that none of the indexes have previously been flagged
for deletion. */
@@ -1769,7 +1773,7 @@ func_exit:
} while (index);
}
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
row_mysql_unlock_data_dictionary(trx);
DBUG_RETURN(err);
@@ -1847,7 +1851,7 @@ ha_innobase::final_drop_index(
}
row_mysql_lock_data_dictionary(trx);
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
if (UNIV_UNLIKELY(err)) {
@@ -1890,7 +1894,7 @@ ha_innobase::final_drop_index(
share->idx_trans_tbl.index_count = 0;
func_exit:
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
ut_a(fts_check_cached_index(prebuilt->table));
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h
index f531b785786..5592995d4b2 100644
--- a/storage/innobase/include/btr0btr.h
+++ b/storage/innobase/include/btr0btr.h
@@ -92,6 +92,8 @@ insert/delete buffer when the record is not in the buffer pool. */
buffer when the record is not in the buffer pool. */
#define BTR_DELETE 8192
+#endif /* UNIV_HOTBACKUP */
+
/**************************************************************//**
Report that an index page is corrupted. */
UNIV_INTERN
@@ -112,6 +114,7 @@ btr_corruption_report(
ut_error; \
}
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_BLOB_DEBUG
# include "ut0rbt.h"
/** An index->blobs entry for keeping track of off-page column references */
diff --git a/storage/innobase/include/btr0types.h b/storage/innobase/include/btr0types.h
index 62b7868b419..09f97b3cabd 100644
--- a/storage/innobase/include/btr0types.h
+++ b/storage/innobase/include/btr0types.h
@@ -39,6 +39,8 @@ typedef struct btr_cur_struct btr_cur_t;
/** B-tree search information for the adaptive hash index */
typedef struct btr_search_struct btr_search_t;
+#ifndef UNIV_HOTBACKUP
+
/** @brief The latch protecting the adaptive search system
This latch protects the
@@ -54,6 +56,8 @@ Bear in mind (3) and (4) when using the hash index.
*/
extern rw_lock_t* btr_search_latch_temp;
+#endif /* UNIV_HOTBACKUP */
+
/** The latch protecting the adaptive search system */
#define btr_search_latch (*btr_search_latch_temp)
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 08e61c08004..2284f21e3ab 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -594,34 +594,34 @@ ib_uint64_t
buf_block_get_modify_clock(
/*=======================*/
buf_block_t* block); /*!< in: block */
-#else /* !UNIV_HOTBACKUP */
-# define buf_block_modify_clock_inc(block) ((void) 0)
-#endif /* !UNIV_HOTBACKUP */
/*******************************************************************//**
Increments the bufferfix count. */
UNIV_INLINE
void
buf_block_buf_fix_inc_func(
/*=======================*/
-#ifdef UNIV_SYNC_DEBUG
+# ifdef UNIV_SYNC_DEBUG
const char* file, /*!< in: file name */
ulint line, /*!< in: line */
-#endif /* UNIV_SYNC_DEBUG */
+# endif /* UNIV_SYNC_DEBUG */
buf_block_t* block) /*!< in/out: block to bufferfix */
__attribute__((nonnull));
-#ifdef UNIV_SYNC_DEBUG
+# ifdef UNIV_SYNC_DEBUG
/** Increments the bufferfix count.
@param b in/out: block to bufferfix
@param f in: file name where requested
@param l in: line number where requested */
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
-#else /* UNIV_SYNC_DEBUG */
+# else /* UNIV_SYNC_DEBUG */
/** Increments the bufferfix count.
@param b in/out: block to bufferfix
@param f in: file name where requested
@param l in: line number where requested */
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
-#endif /* UNIV_SYNC_DEBUG */
+# endif /* UNIV_SYNC_DEBUG */
+#else /* !UNIV_HOTBACKUP */
+# define buf_block_modify_clock_inc(block) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Checks if a page is corrupt.
@return TRUE if corrupted */
@@ -1163,9 +1163,10 @@ buf_page_init_for_read(
ulint offset);/*!< in: page number */
/********************************************************************//**
Completes an asynchronous read or write request of a file page to or from
-the buffer pool. */
+the buffer pool.
+@return TRUE if successful */
UNIV_INTERN
-void
+ibool
buf_page_io_complete(
/*=================*/
buf_page_t* bpage); /*!< in: pointer to the block in question */
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 073b68c26ad..68008f95c2f 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -797,6 +797,7 @@ void
dict_table_x_unlock_indexes(
/*========================*/
dict_table_t* table); /*!< in: table */
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Checks if a column is in the ordering columns of the clustered index of a
table. Column prefixes are treated like whole columns.
@@ -908,7 +909,7 @@ dict_index_remove_from_cache(
/*=========================*/
dict_table_t* table, /*!< in/out: table */
dict_index_t* index); /*!< in, own: index */
-#endif /* !UNIV_HOTBACKUP */
+
/********************************************************************//**
Gets the number of fields in the internal representation of an index,
including fields added by the dictionary system.
@@ -1427,7 +1428,7 @@ UNIV_INTERN
void
dict_close(void);
/*============*/
-
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Check whether the table is corrupted.
@return nonzero for corrupted table, zero for valid tables */
@@ -1448,6 +1449,7 @@ dict_index_is_corrupted(
const dict_index_t* index) /*!< in: index */
__attribute__((nonnull, pure, warn_unused_result));
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Flags an index and table corrupted both in the data dictionary cache
and in the system table SYS_INDEXES. */
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index a454c682f89..b1aa3d2224c 100644
--- a/storage/innobase/include/trx0sys.h
+++ b/storage/innobase/include/trx0sys.h
@@ -183,7 +183,6 @@ UNIV_INLINE
trx_id_t
trx_sys_get_max_trx_id(void);
/*========================*/
-#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
@@ -200,7 +199,6 @@ trx_write_trx_id(
/*=============*/
byte* ptr, /*!< in: pointer to memory where written */
trx_id_t id); /*!< in: id */
-#ifndef UNIV_HOTBACKUP
/*****************************************************************//**
Reads a trx id from an index page. In case that the id size changes in
some future version, this function should be used instead of
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 9919ec2a80a..a360d05f056 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -2896,7 +2896,7 @@ recv_recovery_from_checkpoint_start_func(
lsn_t checkpoint_lsn;
ib_uint64_t checkpoint_no;
lsn_t old_scanned_lsn;
- lsn_t group_scanned_lsn;
+ lsn_t group_scanned_lsn = 0;
lsn_t contiguous_lsn;
#ifdef UNIV_LOG_ARCHIVE
lsn_t archived_lsn;
diff --git a/storage/innobase/mysql-test/storage_engine/alter_tablespace.opt b/storage/innobase/mysql-test/storage_engine/alter_tablespace.opt
new file mode 100644
index 00000000000..cf4b117e1b1
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/alter_tablespace.opt
@@ -0,0 +1,2 @@
+--innodb-file-per-table=1
+
diff --git a/storage/innobase/mysql-test/storage_engine/autoinc_secondary.rdiff b/storage/innobase/mysql-test/storage_engine/autoinc_secondary.rdiff
new file mode 100644
index 00000000000..c24594c5024
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/autoinc_secondary.rdiff
@@ -0,0 +1,30 @@
+--- suite/storage_engine/autoinc_secondary.result 2012-07-12 04:34:18.153885986 +0400
++++ suite/storage_engine/autoinc_secondary.reject 2012-07-15 17:47:03.937703666 +0400
+@@ -13,18 +13,15 @@
+ 5 a
+ DROP TABLE t1;
+ CREATE TABLE t1 (a <CHAR_COLUMN>, b <INT_COLUMN> AUTO_INCREMENT, PRIMARY KEY (a,b)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-INSERT INTO t1 (a) VALUES ('a'),('b'),('b'),('c'),('a');
+-SELECT LAST_INSERT_ID();
+-LAST_INSERT_ID()
+-1
+-SELECT * FROM t1;
+-a b
+-a 1
+-a 2
+-b 1
+-b 2
+-c 1
+-DROP TABLE t1;
++ERROR 42000: Incorrect table definition; there can be only one auto column and it must be defined as a key
++# ERROR: Statement ended with errno 1075, errname ER_WRONG_AUTO_KEY (expected to succeed)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_WRONG_AUTO_KEY.
++# Multi-part keys or PK or AUTO_INCREMENT (on a secondary column) or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ CREATE TABLE t1 (a <CHAR_COLUMN>, b <INT_COLUMN> AUTO_INCREMENT, PRIMARY KEY (a,b), <CUSTOM_INDEX>(b)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ INSERT INTO t1 (a) VALUES ('a'),('b'),('b'),('c'),('a');
+ SELECT LAST_INSERT_ID();
diff --git a/storage/innobase/mysql-test/storage_engine/cache_index.rdiff b/storage/innobase/mysql-test/storage_engine/cache_index.rdiff
new file mode 100644
index 00000000000..e04df87aa34
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/cache_index.rdiff
@@ -0,0 +1,71 @@
+--- suite/storage_engine/cache_index.result 2012-07-15 00:22:19.822493731 +0400
++++ suite/storage_engine/cache_index.reject 2012-07-15 17:47:18.321522834 +0400
+@@ -12,31 +12,31 @@
+ SET GLOBAL <CACHE_NAME>.key_buffer_size=128*1024;
+ CACHE INDEX t1 INDEX (a), t2 IN <CACHE_NAME>;
+ Table Op Msg_type Msg_text
+-test.t1 assign_to_keycache status OK
+-test.t2 assign_to_keycache status OK
++test.t1 assign_to_keycache note The storage engine for the table doesn't support assign_to_keycache
++test.t2 assign_to_keycache note The storage engine for the table doesn't support assign_to_keycache
+ LOAD INDEX INTO CACHE t1, t2;
+ Table Op Msg_type Msg_text
+-test.t1 preload_keys status OK
+-test.t2 preload_keys status OK
++test.t1 preload_keys note The storage engine for the table doesn't support preload_keys
++test.t2 preload_keys note The storage engine for the table doesn't support preload_keys
+ INSERT INTO t1 (a,b) VALUES (3,'c'),(4,'d');
+ SET GLOBAL <CACHE_NAME>.key_buffer_size=8*1024;
+ LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES;
+ Table Op Msg_type Msg_text
+-test.t1 preload_keys status OK
+-test.t2 preload_keys status OK
++test.t1 preload_keys note The storage engine for the table doesn't support preload_keys
++test.t2 preload_keys note The storage engine for the table doesn't support preload_keys
+ SET GLOBAL <CACHE_NAME>.key_cache_age_threshold = 100, <CACHE_NAME>.key_cache_block_size = 512, <CACHE_NAME>.key_cache_division_limit = 1, <CACHE_NAME>.key_cache_segments=2;
+ INSERT INTO t1 (a,b) VALUES (5,'e'),(6,'f');
+ LOAD INDEX INTO CACHE t1;
+ Table Op Msg_type Msg_text
+-test.t1 preload_keys status OK
++test.t1 preload_keys note The storage engine for the table doesn't support preload_keys
+ SET GLOBAL new_<CACHE_NAME>.key_buffer_size=128*1024;
+ CACHE INDEX t1 IN new_<CACHE_NAME>;
+ Table Op Msg_type Msg_text
+-test.t1 assign_to_keycache status OK
++test.t1 assign_to_keycache note The storage engine for the table doesn't support assign_to_keycache
+ INSERT INTO t1 (a,b) VALUES (7,'g'),(8,'h');
+ LOAD INDEX INTO CACHE t1 IGNORE LEAVES;
+ Table Op Msg_type Msg_text
+-test.t1 preload_keys status OK
++test.t1 preload_keys note The storage engine for the table doesn't support preload_keys
+ INSERT INTO t1 (a,b) VALUES (9,'i');
+ DROP TABLE t2;
+ DROP TABLE t1;
+@@ -47,11 +47,11 @@
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ CACHE INDEX t1 IN <CACHE_NAME>;
+ Table Op Msg_type Msg_text
+-test.t1 assign_to_keycache status OK
++test.t1 assign_to_keycache note The storage engine for the table doesn't support assign_to_keycache
+ INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+ LOAD INDEX INTO CACHE t1;
+ Table Op Msg_type Msg_text
+-test.t1 preload_keys status OK
++test.t1 preload_keys note The storage engine for the table doesn't support preload_keys
+ DROP TABLE t1;
+ CREATE TABLE t1 (a <INT_COLUMN>,
+ b <CHAR_COLUMN>,
+@@ -59,11 +59,11 @@
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ CACHE INDEX t1 IN <CACHE_NAME>;
+ Table Op Msg_type Msg_text
+-test.t1 assign_to_keycache status OK
++test.t1 assign_to_keycache note The storage engine for the table doesn't support assign_to_keycache
+ INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+ LOAD INDEX INTO CACHE t1;
+ Table Op Msg_type Msg_text
+-test.t1 preload_keys status OK
++test.t1 preload_keys note The storage engine for the table doesn't support preload_keys
+ DROP TABLE t1;
+ SET GLOBAL <CACHE_NAME>.key_buffer_size=0;
+ SET GLOBAL new_<CACHE_NAME>.key_buffer_size=0;
diff --git a/storage/innobase/mysql-test/storage_engine/checksum_table_live.rdiff b/storage/innobase/mysql-test/storage_engine/checksum_table_live.rdiff
new file mode 100644
index 00000000000..71c782848a6
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/checksum_table_live.rdiff
@@ -0,0 +1,13 @@
+--- suite/storage_engine/checksum_table_live.result 2012-07-12 21:05:44.497062968 +0400
++++ suite/storage_engine/checksum_table_live.reject 2012-07-15 17:47:28.105399836 +0400
+@@ -11,8 +11,8 @@
+ test.t1 4272806499
+ CHECKSUM TABLE t1, t2 QUICK;
+ Table Checksum
+-test.t1 4272806499
+-test.t2 0
++test.t1 NULL
++test.t2 NULL
+ CHECKSUM TABLE t1, t2 EXTENDED;
+ Table Checksum
+ test.t1 4272806499
diff --git a/storage/innobase/mysql-test/storage_engine/define_engine.inc b/storage/innobase/mysql-test/storage_engine/define_engine.inc
new file mode 100644
index 00000000000..7d7b0c7407a
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/define_engine.inc
@@ -0,0 +1,45 @@
+###########################################
+#
+# This is a template of the include file define_engine.inc which
+# should be placed in storage/<engine>/mysql-test/storage_engine folder.
+#
+################################
+#
+# The name of the engine under test must be defined in $ENGINE variable.
+# You can set it either here (uncomment and edit) or in your environment.
+#
+let $ENGINE = InnoDB;
+#
+################################
+#
+# The following three variables define specific options for columns and tables.
+# Normally there should be none needed, but for some engines it can be different.
+# If the engine requires specific column option for all or indexed columns,
+# set them inside the comment, e.g. /*!NOT NULL*/.
+# Do the same for table options if needed, e.g. /*!INSERT_METHOD=LAST*/
+
+let $default_col_opts = /*!*/;
+let $default_col_indexed_opts = /*!*/;
+let $default_tbl_opts = /*!*/;
+
+# INDEX, UNIQUE INDEX, PRIMARY KEY, special index type - choose the fist that the engine allows,
+# or set it to /*!*/ if none is supported
+
+let $default_index = /*!INDEX*/;
+
+# If the engine does not support the following types, replace them with the closest possible
+
+let $default_int_type = INT(11);
+let $default_char_type = CHAR(8);
+
+################################
+
+--disable_query_log
+--disable_result_log
+
+# Here you can place your custom MTR code which needs to be executed before each test,
+# e.g. creation of an additional schema or table, etc.
+# The cleanup part should be defined in cleanup_engine.inc
+
+--enable_query_log
+--enable_result_log
diff --git a/storage/innobase/mysql-test/storage_engine/disabled.def b/storage/innobase/mysql-test/storage_engine/disabled.def
new file mode 100644
index 00000000000..3849170a7b8
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/disabled.def
@@ -0,0 +1,9 @@
+alter_table_online : MDEV-397 (Changing a column name via ALTER ONLINE does not work for InnoDB)
+autoinc_vars : MySQL:65225 (InnoDB miscalculates auto-increment)
+tbl_opt_ai : MySQL:65901 (AUTO_INCREMENT option on InnoDB table is ignored if added before autoinc column)
+delete_low_prio : InnoDB does not use table-level locking
+insert_high_prio : InnoDB does not use table-level locking
+insert_low_prio : InnoDB does not use table-level locking
+select_high_prio : InnoDB does not use table-level locking
+update_low_prio : InnoDB does not use table-level locking
+
diff --git a/storage/innobase/mysql-test/storage_engine/fulltext_search.rdiff b/storage/innobase/mysql-test/storage_engine/fulltext_search.rdiff
new file mode 100644
index 00000000000..f668e44109c
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/fulltext_search.rdiff
@@ -0,0 +1,150 @@
+--- suite/storage_engine/fulltext_search.result 2012-07-12 20:03:26.664053893 +0400
++++ suite/storage_engine/fulltext_search.reject 2012-07-15 17:49:03.616199102 +0400
+@@ -4,129 +4,27 @@
+ v2 TEXT <CUSTOM_COL_OPTIONS>,
+ FULLTEXT v1 (v1)
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-SHOW INDEXES IN t1;
+-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 1 v1 1 v1 # # NULL NULL YES FULLTEXT
+-INSERT INTO t1 (v0,v1,v2) VALUES ('text1','Here is a list of recommended books on MariaDB and MySQL. We\'ve provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+-If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+-For developers who want to code on MariaDB or MySQL
+-* Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+-o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+-o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic.
+-* MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+-o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB!
+-For MariaDB / MySQL end users
+-* MariaDB Crash Course by Ben Forta
+-o First MariaDB book!
+-o For people who want to learn SQL and the basics of MariaDB.
+-o Now shipping. Purchase at Amazon.com or your favorite bookseller.
+-* SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+-o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+-o Free to read in the Knowledgebase!
+-* MySQL (4th Edition) by Paul DuBois
+-o The \'default\' book to read if you wont to learn to use MySQL / MariaDB.
+-* MySQL Cookbook by Paul DuBois
+-o A lot of examples of how to use MySQL. As with all of Paul\'s books, it\'s worth its weight in gold and even enjoyable reading for such a \'dry\' subject.
+-* High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+-o \"High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL\'s full power.\" (From the book description at O\'Reilly)
+-
+- * MySQL Admin Cookbook
+- o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration
+-
+- * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+- o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. ',
+-'There are several reasons why contributing code is one of the easiest and most rewarding ways to contribute to MariaDB:
+-
+- 1. We are very responsive toward reviews of submitted code and as soon as the review is done, the submitted code is merged into an existing MariaDB tree and made available to everyone, not just select customers.
+- 2. Code reviews are performed by the MariaDB core development team and the quality, detail, and timeliness of our reviews are better than you will find elsewhere.
+- 3. With MariaDB everyone has access to the latest code.
+- 4. If a patch is very safe and/or very useful we are willing to push it into the stable code (as long as it can\'t break any existing applications). We are willing to do this to ensure the freedom to add small, needed fixes on a stable release so users don\'t have to wait a year for something to be added which is critical to their business.
+- 5. If you are an active contributor, you can become a member of maria-captains, even if you aren\'t working for Monty Program Ab. All captains have the same rights as any other captain to accept and reject patches. Our development model is truly open for everyone.
+-The Contributing Code page details many of the actual steps involved in working with the MariaDB source code. It\'s important that you use the same tools and submit patches in the same way as other developers to keep development running smoothly.'
+- ), ('text2','test1','test2');
+-SELECT v0 FROM t1 WHERE MATCH(v1) AGAINST ('contributing' IN NATURAL LANGUAGE MODE);
+-v0
+-INSERT INTO t1 (v0,v1,v2) VALUES ('text3','test','test');
+-SELECT v0, MATCH(v1) AGAINST('contributing' IN NATURAL LANGUAGE MODE) AS rating FROM t1 WHERE MATCH(v1) AGAINST ('contributing' IN NATURAL LANGUAGE MODE);
+-v0 rating
+-INSERT INTO t1 (v0,v1,v2) VALUES ('text4','Contributing more...','...is a good idea'),('text5','test','test');
+-SELECT v0, MATCH(v1) AGAINST('contributing') AS rating FROM t1 WHERE MATCH(v1) AGAINST ('contributing');
+-v0 rating
+-text4 1.3705332279205322
+-SELECT v0 FROM t1 WHERE MATCH(v1,v2) AGAINST ('-test1 +critical +Cook*' IN BOOLEAN MODE);
+-v0
+-text1
+-SELECT v0 FROM t1 WHERE MATCH(v1,v2) AGAINST ('-patch +critical +Cook*' IN BOOLEAN MODE);
+-v0
+-SELECT v0, MATCH(v1) AGAINST('database' WITH QUERY EXPANSION) AS rating FROM t1 WHERE MATCH(v1) AGAINST ('database' WITH QUERY EXPANSION);
+-v0 rating
+-text1 178.11756896972656
+-DROP TABLE t1;
++ERROR HY000: The used table type doesn't support FULLTEXT indexes
++# ERROR: Statement ended with errno 1214, errname ER_TABLE_CANT_HANDLE_FT (expected to succeed)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_TABLE_CANT_HANDLE_FT.
++# FULLTEXT indexes or VARCHAR|TEXT data types or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ CREATE TABLE t1 (v0 VARCHAR(64) <CUSTOM_COL_OPTIONS>,
+ v1 VARCHAR(16384) <CUSTOM_COL_OPTIONS>,
+ v2 TEXT <CUSTOM_COL_OPTIONS>,
+ FULLTEXT v1 (v1),
+ FULLTEXT v1_v2 (v1,v2)
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-SHOW INDEXES IN t1;
+-Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 1 v1 1 v1 # # NULL NULL YES FULLTEXT
+-t1 1 v1_v2 1 v1 # # NULL NULL YES FULLTEXT
+-t1 1 v1_v2 2 v2 # # NULL NULL YES FULLTEXT
+-INSERT INTO t1 (v0,v1,v2) VALUES ('text1','Here is a list of recommended books on MariaDB and MySQL. We\'ve provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+-If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+-For developers who want to code on MariaDB or MySQL
+-* Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+-o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+-o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic.
+-* MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+-o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB!
+-For MariaDB / MySQL end users
+-* MariaDB Crash Course by Ben Forta
+-o First MariaDB book!
+-o For people who want to learn SQL and the basics of MariaDB.
+-o Now shipping. Purchase at Amazon.com or your favorite bookseller.
+-* SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+-o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+-o Free to read in the Knowledgebase!
+-* MySQL (4th Edition) by Paul DuBois
+-o The \'default\' book to read if you wont to learn to use MySQL / MariaDB.
+-* MySQL Cookbook by Paul DuBois
+-o A lot of examples of how to use MySQL. As with all of Paul\'s books, it\'s worth its weight in gold and even enjoyable reading for such a \'dry\' subject.
+-* High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+-o \"High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL\'s full power.\" (From the book description at O\'Reilly)
+-
+- * MySQL Admin Cookbook
+- o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration
+-
+- * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+- o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. ',
+-'There are several reasons why contributing code is one of the easiest and most rewarding ways to contribute to MariaDB:
+-
+- 1. We are very responsive toward reviews of submitted code and as soon as the review is done, the submitted code is merged into an existing MariaDB tree and made available to everyone, not just select customers.
+- 2. Code reviews are performed by the MariaDB core development team and the quality, detail, and timeliness of our reviews are better than you will find elsewhere.
+- 3. With MariaDB everyone has access to the latest code.
+- 4. If a patch is very safe and/or very useful we are willing to push it into the stable code (as long as it can\'t break any existing applications). We are willing to do this to ensure the freedom to add small, needed fixes on a stable release so users don\'t have to wait a year for something to be added which is critical to their business.
+- 5. If you are an active contributor, you can become a member of maria-captains, even if you aren\'t working for Monty Program Ab. All captains have the same rights as any other captain to accept and reject patches. Our development model is truly open for everyone.
+-The Contributing Code page details many of the actual steps involved in working with the MariaDB source code. It\'s important that you use the same tools and submit patches in the same way as other developers to keep development running smoothly.'
+- ), ('text2','test1','test2');
+-SELECT v0 FROM t1 WHERE MATCH(v1,v2) AGAINST ('contributing' IN NATURAL LANGUAGE MODE);
+-v0
+-INSERT INTO t1 (v0,v1,v2) VALUES ('text3','test','test');
+-SELECT v0, MATCH(v1,v2) AGAINST('contributing' IN NATURAL LANGUAGE MODE) AS rating FROM t1 WHERE MATCH(v1,v2) AGAINST ('contributing' IN NATURAL LANGUAGE MODE);
+-v0 rating
+-text1 0.2809644043445587
+-INSERT INTO t1 (v0,v1,v2) VALUES ('text4','Contributing more...','...is a good idea'),('text5','test','test');
+-SELECT v0, MATCH(v1) AGAINST('contributing') AS rating FROM t1 WHERE MATCH(v1) AGAINST ('contributing');
+-v0 rating
+-text4 1.3705332279205322
+-SELECT v0 FROM t1 WHERE MATCH(v1,v2) AGAINST ('-test1 +critical +Cook*' IN BOOLEAN MODE);
+-v0
+-text1
+-SELECT v0 FROM t1 WHERE MATCH(v1,v2) AGAINST ('-patch +critical +Cook*' IN BOOLEAN MODE);
+-v0
+-SELECT v0, MATCH(v1,v2) AGAINST('database' WITH QUERY EXPANSION) AS rating FROM t1 WHERE MATCH(v1,v2) AGAINST ('database' WITH QUERY EXPANSION);
+-v0 rating
+-text1 190.56150817871094
+-text4 1.1758291721343994
+-DROP TABLE t1;
++ERROR HY000: The used table type doesn't support FULLTEXT indexes
++# ERROR: Statement ended with errno 1214, errname ER_TABLE_CANT_HANDLE_FT (expected to succeed)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_TABLE_CANT_HANDLE_FT.
++# FULLTEXT indexes or multiple keys or VARCHAR|TEXT data types or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
diff --git a/storage/innobase/mysql-test/storage_engine/index_enable_disable.rdiff b/storage/innobase/mysql-test/storage_engine/index_enable_disable.rdiff
new file mode 100644
index 00000000000..23aa66d2568
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/index_enable_disable.rdiff
@@ -0,0 +1,33 @@
+--- suite/storage_engine/index_enable_disable.result 2012-07-15 00:30:05.296641931 +0400
++++ suite/storage_engine/index_enable_disable.reject 2012-07-15 17:49:12.988081281 +0400
+@@ -11,15 +11,19 @@
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+ t1 1 a 1 a # # NULL NULL YES BTREE
+ ALTER TABLE t1 DISABLE KEYS;
++Warnings:
++Note 1031 Table storage engine for 't1' doesn't have this option
+ SHOW INDEX IN t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 1 a 1 a # # NULL NULL YES BTREE disabled
++t1 1 a 1 a # # NULL NULL YES BTREE
+ EXPLAIN SELECT a FROM t1 ORDER BY a;
+ id select_type table type possible_keys key key_len ref rows Extra
+-1 SIMPLE t1 ALL NULL NULL NULL NULL 19 Using filesort
++1 SIMPLE t1 index NULL a 5 NULL 19 Using index
+ INSERT INTO t1 (a) VALUES
+ (11),(12),(13),(14),(15),(16),(17),(18),(19),(20);
+ ALTER TABLE t1 ENABLE KEYS;
++Warnings:
++Note 1031 Table storage engine for 't1' doesn't have this option
+ SHOW INDEX IN t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+ t1 1 a 1 a # # NULL NULL YES BTREE
+@@ -32,6 +36,8 @@
+ (1),(2),(3),(4),(5),(6),(7),(8),(9),
+ (21),(22),(23),(24),(25),(26),(27),(28),(29);
+ ALTER TABLE t1 DISABLE KEYS;
++Warnings:
++Note 1031 Table storage engine for 't1' doesn't have this option
+ INSERT INTO t1 (a) VALUES (29);
+ ERROR 23000: Duplicate entry '29' for key 'a'
+ # Statement ended with one of expected results (ER_DUP_ENTRY,ER_DUP_KEY).
diff --git a/storage/innobase/mysql-test/storage_engine/index_type_hash.rdiff b/storage/innobase/mysql-test/storage_engine/index_type_hash.rdiff
new file mode 100644
index 00000000000..02f9d93588f
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/index_type_hash.rdiff
@@ -0,0 +1,60 @@
+--- suite/storage_engine/index_type_hash.result 2012-07-15 01:10:17.919128889 +0400
++++ suite/storage_engine/index_type_hash.reject 2012-07-15 17:49:26.135915989 +0400
+@@ -4,7 +4,7 @@
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ SHOW KEYS IN t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 1 a 1 a # # NULL NULL # HASH
++t1 1 a 1 a # # NULL NULL # BTREE
+ DROP TABLE t1;
+ CREATE TABLE t1 (a <INT_COLUMN>,
+ b <CHAR_COLUMN>,
+@@ -12,8 +12,8 @@
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ SHOW KEYS IN t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 1 a_b 1 a # # NULL NULL # HASH a_b index
+-t1 1 a_b 2 b # # NULL NULL # HASH a_b index
++t1 1 a_b 1 a # # NULL NULL # BTREE a_b index
++t1 1 a_b 2 b # # NULL NULL # BTREE a_b index
+ DROP TABLE t1;
+ CREATE TABLE t1 (a <INT_COLUMN>,
+ b <CHAR_COLUMN>,
+@@ -22,8 +22,8 @@
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ SHOW KEYS IN t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 1 a 1 a # # NULL NULL # HASH
+-t1 1 b 1 b # # NULL NULL # HASH
++t1 1 a 1 a # # NULL NULL # BTREE
++t1 1 b 1 b # # NULL NULL # BTREE
+ DROP TABLE t1;
+ CREATE TABLE t1 (a <INT_COLUMN>,
+ b <CHAR_COLUMN>,
+@@ -31,7 +31,7 @@
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ SHOW KEYS IN t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 0 a 1 a # # NULL NULL # HASH
++t1 0 a 1 a # # NULL NULL # BTREE
+ INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+ INSERT INTO t1 (a,b) VALUES (1,'c');
+ ERROR 23000: Duplicate entry '1' for key 'a'
+@@ -43,7 +43,7 @@
+ ALTER TABLE t1 ADD <CUSTOM_INDEX> (a) USING HASH COMMENT 'simple index on a';
+ SHOW INDEX FROM t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 1 a 1 a # # NULL NULL # HASH simple index on a
++t1 1 a 1 a # # NULL NULL # BTREE simple index on a
+ ALTER TABLE t1 DROP KEY a;
+ DROP TABLE t1;
+ CREATE TABLE t1 (a <INT_COLUMN>,
+@@ -52,7 +52,7 @@
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ SHOW KEYS IN t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 0 a 1 a # # NULL NULL # HASH
++t1 0 a 1 a # # NULL NULL # BTREE
+ INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+ INSERT INTO t1 (a,b) VALUES (1,'c');
+ ERROR 23000: Duplicate entry '1' for key 'a'
diff --git a/storage/innobase/mysql-test/storage_engine/insert_delayed.rdiff b/storage/innobase/mysql-test/storage_engine/insert_delayed.rdiff
new file mode 100644
index 00000000000..62895fa928f
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/insert_delayed.rdiff
@@ -0,0 +1,26 @@
+--- suite/storage_engine/insert_delayed.result 2012-07-12 20:04:07.143544998 +0400
++++ suite/storage_engine/insert_delayed.reject 2012-07-15 17:49:34.551810189 +0400
+@@ -5,7 +5,16 @@
+ connect con0,localhost,root,,;
+ SET lock_wait_timeout = 1;
+ INSERT DELAYED INTO t1 (a,b) VALUES (3,'c');
++ERROR HY000: DELAYED option not supported for table 't1'
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_DELAYED_NOT_SUPPORTED.
++# INSERT DELAYED or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ INSERT DELAYED INTO t1 SET a=4, b='d';
++ERROR HY000: DELAYED option not supported for table 't1'
+ INSERT DELAYED INTO t1 SELECT 5, 'e';
+ ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ disconnect con0;
+@@ -20,6 +29,4 @@
+ a b
+ 1 f
+ 2 b
+-3 c
+-4 d
+ DROP TABLE t1;
diff --git a/storage/innobase/mysql-test/storage_engine/lock_concurrent.rdiff b/storage/innobase/mysql-test/storage_engine/lock_concurrent.rdiff
new file mode 100644
index 00000000000..fe4a0087fa9
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/lock_concurrent.rdiff
@@ -0,0 +1,22 @@
+--- suite/storage_engine/lock_concurrent.result 2012-06-24 23:55:19.539380000 +0400
++++ suite/storage_engine/lock_concurrent.reject 2012-07-15 17:50:21.279222746 +0400
+@@ -3,10 +3,19 @@
+ LOCK TABLES t1 WRITE CONCURRENT, t1 AS t2 READ;
+ SET lock_wait_timeout = 1;
+ LOCK TABLES t1 READ LOCAL;
++ERROR HY000: Lock wait timeout exceeded; try restarting transaction
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_LOCK_WAIT_TIMEOUT.
++# LOCK .. WRITE CONCURRENT or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ UNLOCK TABLES;
+ UNLOCK TABLES;
+ LOCK TABLES t1 READ LOCAL;
+ LOCK TABLES t1 WRITE CONCURRENT, t1 AS t2 READ;
++ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ UNLOCK TABLES;
+ UNLOCK TABLES;
+ DROP TABLE t1;
diff --git a/storage/innobase/mysql-test/storage_engine/optimize_table.rdiff b/storage/innobase/mysql-test/storage_engine/optimize_table.rdiff
new file mode 100644
index 00000000000..54d1f600516
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/optimize_table.rdiff
@@ -0,0 +1,37 @@
+--- suite/storage_engine/optimize_table.result 2012-07-12 19:13:53.741428591 +0400
++++ suite/storage_engine/optimize_table.reject 2012-07-15 17:50:30.843102510 +0400
+@@ -5,25 +5,32 @@
+ INSERT INTO t1 (a,b) VALUES (3,'c'),(4,'d');
+ OPTIMIZE TABLE t1;
+ Table Op Msg_type Msg_text
++test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t1 optimize status OK
+ INSERT INTO t2 (a,b) VALUES (4,'d');
+ OPTIMIZE NO_WRITE_TO_BINLOG TABLE t2;
+ Table Op Msg_type Msg_text
++test.t2 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t2 optimize status OK
+ INSERT INTO t2 (a,b) VALUES (5,'e');
+ INSERT INTO t1 (a,b) VALUES (6,'f');
+ OPTIMIZE LOCAL TABLE t1, t2;
+ Table Op Msg_type Msg_text
++test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t1 optimize status OK
++test.t2 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t2 optimize status OK
+ OPTIMIZE TABLE t1, t2;
+ Table Op Msg_type Msg_text
+-test.t1 optimize status Table is already up to date
+-test.t2 optimize status Table is already up to date
++test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
++test.t1 optimize status OK
++test.t2 optimize note Table does not support optimize, doing recreate + analyze instead
++test.t2 optimize status OK
+ DROP TABLE t1, t2;
+ CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>, <CUSTOM_INDEX> (a)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ INSERT INTO t1 (a,b) VALUES (1,'a'),(100,'b'),(2,'c'),(3,'d');
+ OPTIMIZE TABLE t1;
+ Table Op Msg_type Msg_text
++test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t1 optimize status OK
+ DROP TABLE t1;
diff --git a/storage/innobase/mysql-test/storage_engine/parts/checksum_table.rdiff b/storage/innobase/mysql-test/storage_engine/parts/checksum_table.rdiff
new file mode 100644
index 00000000000..3d4d2a683d9
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/parts/checksum_table.rdiff
@@ -0,0 +1,22 @@
+--- suite/storage_engine/parts/checksum_table.result 2012-07-12 21:41:00.754458011 +0400
++++ suite/storage_engine/parts/checksum_table.reject 2012-07-15 20:04:35.881962676 +0400
+@@ -24,15 +24,15 @@
+ CREATE TABLE t2 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS> CHECKSUM=1 PARTITION BY HASH(a) PARTITIONS 2;
+ CHECKSUM TABLE t1;
+ Table Checksum
+-test.t1 0
++test.t1 4272806499
+ CHECKSUM TABLE t2, t1;
+ Table Checksum
+ test.t2 0
+-test.t1 0
++test.t1 4272806499
+ CHECKSUM TABLE t1, t2 QUICK;
+ Table Checksum
+-test.t1 0
+-test.t2 0
++test.t1 NULL
++test.t2 NULL
+ CHECKSUM TABLE t1, t2 EXTENDED;
+ Table Checksum
+ test.t1 4272806499
diff --git a/storage/innobase/mysql-test/storage_engine/parts/create_table.rdiff b/storage/innobase/mysql-test/storage_engine/parts/create_table.rdiff
new file mode 100644
index 00000000000..0df91c6fc6e
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/parts/create_table.rdiff
@@ -0,0 +1,20 @@
+--- suite/storage_engine/parts/create_table.result 2012-07-12 21:56:38.618667460 +0400
++++ suite/storage_engine/parts/create_table.reject 2012-07-15 20:06:43.496358345 +0400
+@@ -65,7 +65,7 @@
+ 1 SIMPLE t1 abc,def # # # # # # #
+ EXPLAIN PARTITIONS SELECT a FROM t1 WHERE a = 100;
+ id select_type table partitions type possible_keys key key_len ref rows Extra
+-1 SIMPLE NULL NULL # # # # # # #
++1 SIMPLE t1 def # # # # # # #
+ INSERT INTO t1 (a) VALUES (50);
+ ERROR HY000: Table has no partition for value 50
+ DROP TABLE t1;
+@@ -81,7 +81,7 @@
+ 1 SIMPLE t1 abc_abcsp0,def_defsp0 # # # # # # #
+ EXPLAIN PARTITIONS SELECT a FROM t1 WHERE a = 100;
+ id select_type table partitions type possible_keys key key_len ref rows Extra
+-1 SIMPLE NULL NULL # # # # # # #
++1 SIMPLE t1 def_defsp0 # # # # # # #
+ SELECT TABLE_SCHEMA, TABLE_NAME, PARTITION_NAME, SUBPARTITION_NAME, PARTITION_METHOD, SUBPARTITION_METHOD
+ FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1';
+ TABLE_SCHEMA TABLE_NAME PARTITION_NAME SUBPARTITION_NAME PARTITION_METHOD SUBPARTITION_METHOD
diff --git a/storage/innobase/mysql-test/storage_engine/parts/optimize_table.rdiff b/storage/innobase/mysql-test/storage_engine/parts/optimize_table.rdiff
new file mode 100644
index 00000000000..77ee7e2eb31
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/parts/optimize_table.rdiff
@@ -0,0 +1,58 @@
+--- suite/storage_engine/parts/optimize_table.result 2012-07-12 22:16:39.343572304 +0400
++++ suite/storage_engine/parts/optimize_table.reject 2012-07-15 20:07:01.632130348 +0400
+@@ -9,18 +9,22 @@
+ INSERT INTO t1 (a,b) VALUES (3,'c'),(4,'d');
+ ALTER TABLE t1 OPTIMIZE PARTITION p1;
+ Table Op Msg_type Msg_text
++test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t1 optimize status OK
+ INSERT INTO t2 (a,b) VALUES (4,'d');
+ ALTER TABLE t2 OPTIMIZE PARTITION p0 NO_WRITE_TO_BINLOG;
+ Table Op Msg_type Msg_text
++test.t2 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t2 optimize status OK
+ INSERT INTO t1 (a,b) VALUES (6,'f');
+ ALTER TABLE t1 OPTIMIZE PARTITION ALL LOCAL;
+ Table Op Msg_type Msg_text
++test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t1 optimize status OK
+ INSERT INTO t2 (a,b) VALUES (5,'e');
+ ALTER TABLE t2 OPTIMIZE PARTITION p1,p0;
+ Table Op Msg_type Msg_text
++test.t2 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t2 optimize status OK
+ DROP TABLE t1, t2;
+ DROP TABLE IF EXISTS t1,t2;
+@@ -30,25 +34,32 @@
+ INSERT INTO t1 (a,b) VALUES (3,'c'),(4,'d');
+ OPTIMIZE TABLE t1;
+ Table Op Msg_type Msg_text
++test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t1 optimize status OK
+ INSERT INTO t2 (a,b) VALUES (4,'d');
+ OPTIMIZE NO_WRITE_TO_BINLOG TABLE t2;
+ Table Op Msg_type Msg_text
++test.t2 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t2 optimize status OK
+ INSERT INTO t2 (a,b) VALUES (5,'e');
+ INSERT INTO t1 (a,b) VALUES (6,'f');
+ OPTIMIZE LOCAL TABLE t1, t2;
+ Table Op Msg_type Msg_text
++test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t1 optimize status OK
++test.t2 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t2 optimize status OK
+ OPTIMIZE TABLE t1, t2;
+ Table Op Msg_type Msg_text
++test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t1 optimize status OK
++test.t2 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t2 optimize status OK
+ DROP TABLE t1, t2;
+ CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>, <CUSTOM_INDEX> (a)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS> PARTITION BY HASH(a) PARTITIONS 2;
+ INSERT INTO t1 (a,b) VALUES (1,'a'),(100,'b'),(2,'c'),(3,'d');
+ OPTIMIZE TABLE t1;
+ Table Op Msg_type Msg_text
++test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+ test.t1 optimize status OK
+ DROP TABLE t1;
diff --git a/storage/innobase/mysql-test/storage_engine/parts/repair_table.rdiff b/storage/innobase/mysql-test/storage_engine/parts/repair_table.rdiff
new file mode 100644
index 00000000000..aab866fde83
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/parts/repair_table.rdiff
@@ -0,0 +1,228 @@
+--- suite/storage_engine/parts/repair_table.result 2012-07-15 01:22:58.861853325 +0400
++++ suite/storage_engine/parts/repair_table.reject 2012-07-15 20:07:11.268009209 +0400
+@@ -9,27 +9,27 @@
+ INSERT INTO t2 (a,b) SELECT a, b FROM t1;
+ ALTER TABLE t1 REPAIR PARTITION p0;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 VALUES (3,'c');
+ ALTER TABLE t1 REPAIR PARTITION NO_WRITE_TO_BINLOG p0, p1;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t2 (a,b) VALUES (5,'e'),(6,'f');
+ ALTER TABLE t2 REPAIR PARTITION LOCAL p1;
+ Table Op Msg_type Msg_text
+-test.t2 repair status OK
++test.t2 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (7,'g'),(8,'h');
+ ALTER TABLE t1 REPAIR PARTITION LOCAL ALL EXTENDED;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 VALUES (10,'j');
+ ALTER TABLE t1 REPAIR PARTITION p1 QUICK USE_FRM;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t2 (a,b) VALUES (12,'l');
+ ALTER TABLE t2 REPAIR PARTITION NO_WRITE_TO_BINLOG ALL QUICK EXTENDED USE_FRM;
+ Table Op Msg_type Msg_text
+-test.t2 repair status OK
++test.t2 repair note The storage engine for the table doesn't support repair
+ DROP TABLE t1, t2;
+ DROP TABLE IF EXISTS t1,t2;
+ CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS> PARTITION BY HASH(a) PARTITIONS 2;
+@@ -37,35 +37,35 @@
+ CREATE TABLE t2 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS> PARTITION BY HASH(a) PARTITIONS 2;
+ REPAIR TABLE t1;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (3,'c');
+ INSERT INTO t2 (a,b) VALUES (4,'d');
+ REPAIR NO_WRITE_TO_BINLOG TABLE t1, t2;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
+-test.t2 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
++test.t2 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t2 (a,b) VALUES (5,'e'),(6,'f');
+ REPAIR LOCAL TABLE t2;
+ Table Op Msg_type Msg_text
+-test.t2 repair status OK
++test.t2 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (7,'g'),(8,'h');
+ INSERT INTO t2 (a,b) VALUES (9,'i');
+ REPAIR LOCAL TABLE t2, t1 EXTENDED;
+ Table Op Msg_type Msg_text
+-test.t2 repair status OK
+-test.t1 repair status OK
++test.t2 repair note The storage engine for the table doesn't support repair
++test.t1 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (10,'j');
+ INSERT INTO t2 (a,b) VALUES (11,'k');
+ REPAIR TABLE t1, t2 QUICK USE_FRM;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
+-test.t2 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
++test.t2 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (12,'l');
+ INSERT INTO t2 (a,b) VALUES (13,'m');
+ REPAIR NO_WRITE_TO_BINLOG TABLE t1, t2 QUICK EXTENDED USE_FRM;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
+-test.t2 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
++test.t2 repair note The storage engine for the table doesn't support repair
+ FLUSH TABLE t1;
+ INSERT INTO t1 (a,b) VALUES (14,'n');
+ ERROR HY000: Failed to read from the .par file
+@@ -93,127 +93,21 @@
+ CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>, <CUSTOM_INDEX> (a)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS> PARTITION BY HASH(a) PARTITIONS 2;
+ REPAIR TABLE t1;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (7,'g'),(8,'h');
+ REPAIR TABLE t1 EXTENDED;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (10,'j');
+ REPAIR TABLE t1 USE_FRM;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
+-t1#P#p0.MYD
+-t1#P#p0.MYI
+-t1#P#p1.MYD
+-t1#P#p1.MYI
++test.t1 repair note The storage engine for the table doesn't support repair
+ t1.frm
+ t1.par
+ INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+ # Statement ended with one of expected results (0,144).
+ # If you got a difference in error message, just add it to rdiff file
+ FLUSH TABLE t1;
+-Restoring <DATADIR>/test/t1#P#p0.MYD
+-CHECK TABLE t1;
+-Table Op Msg_type Msg_text
+-test.t1 check error Size of datafile is: 26 Should be: 39
+-test.t1 check error Partition p0 returned error
+-test.t1 check error Corrupt
+-SELECT * FROM t1;
+-a b
+-8 h
+-10 j
+-7 g
+-15 o
+-Warnings:
+-Error 145 Table './test/t1#P#p0' is marked as crashed and should be repaired
+-Error 1194 Table 't1' is marked as crashed and should be repaired
+-Error 1034 Number of rows changed from 3 to 2
+-# Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+-# If you got a difference in error message, just add it to rdiff file
+-INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+-# Statement ended with one of expected results (0,144).
+-# If you got a difference in error message, just add it to rdiff file
+-FLUSH TABLE t1;
+-Restoring <DATADIR>/test/t1#P#p0.MYI
+-CHECK TABLE t1;
+-Table Op Msg_type Msg_text
+-test.t1 check warning Size of datafile is: 39 Should be: 26
+-test.t1 check error Record-count is not ok; is 3 Should be: 2
+-test.t1 check warning Found 3 key parts. Should be: 2
+-test.t1 check error Partition p0 returned error
+-test.t1 check error Corrupt
+-SELECT * FROM t1;
+-a b
+-8 h
+-10 j
+-14 n
+-7 g
+-15 o
+-15 o
+-Warnings:
+-Error 145 Table './test/t1#P#p0' is marked as crashed and should be repaired
+-Error 1194 Table 't1' is marked as crashed and should be repaired
+-Error 1034 Number of rows changed from 2 to 3
+-# Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+-# If you got a difference in error message, just add it to rdiff file
+-INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+-# Statement ended with one of expected results (0,144).
+-# If you got a difference in error message, just add it to rdiff file
+-FLUSH TABLE t1;
+-Restoring <DATADIR>/test/t1#P#p1.MYD
+-CHECK TABLE t1;
+-Table Op Msg_type Msg_text
+-test.t1 check error Size of datafile is: 39 Should be: 52
+-test.t1 check error Partition p1 returned error
+-test.t1 check error Corrupt
+-SELECT * FROM t1;
+-a b
+-8 h
+-10 j
+-14 n
+-14 n
+-7 g
+-15 o
+-15 o
+-Warnings:
+-Error 145 Table './test/t1#P#p1' is marked as crashed and should be repaired
+-Error 1194 Table 't1' is marked as crashed and should be repaired
+-Error 1034 Number of rows changed from 4 to 3
+-# Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+-# If you got a difference in error message, just add it to rdiff file
+-INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+-# Statement ended with one of expected results (0,144).
+-# If you got a difference in error message, just add it to rdiff file
+-FLUSH TABLE t1;
+-Restoring <DATADIR>/test/t1#P#p1.MYI
+-CHECK TABLE t1;
+-Table Op Msg_type Msg_text
+-test.t1 check warning Size of datafile is: 52 Should be: 39
+-test.t1 check error Record-count is not ok; is 4 Should be: 3
+-test.t1 check warning Found 4 key parts. Should be: 3
+-test.t1 check error Partition p1 returned error
+-test.t1 check error Corrupt
+-SELECT * FROM t1;
+-a b
+-8 h
+-10 j
+-14 n
+-14 n
+-14 n
+-7 g
+-15 o
+-15 o
+-15 o
+-Warnings:
+-Error 145 Table './test/t1#P#p1' is marked as crashed and should be repaired
+-Error 1194 Table 't1' is marked as crashed and should be repaired
+-Error 1034 Number of rows changed from 3 to 4
+-# Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+-# If you got a difference in error message, just add it to rdiff file
+-INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+-# Statement ended with one of expected results (0,144).
+-# If you got a difference in error message, just add it to rdiff file
+-FLUSH TABLE t1;
+ Restoring <DATADIR>/test/t1.par
+ CHECK TABLE t1;
+ Table Op Msg_type Msg_text
+@@ -223,14 +117,8 @@
+ 8 h
+ 10 j
+ 14 n
+-14 n
+-14 n
+-14 n
+ 7 g
+ 15 o
+-15 o
+-15 o
+-15 o
+ # Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+ # If you got a difference in error message, just add it to rdiff file
+ DROP TABLE t1;
diff --git a/storage/innobase/mysql-test/storage_engine/parts/suite.opt b/storage/innobase/mysql-test/storage_engine/parts/suite.opt
new file mode 100644
index 00000000000..28ae8786144
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/parts/suite.opt
@@ -0,0 +1,4 @@
+--ignore-builtin-innodb
+--plugin-load=ha_innodb
+--innodb
+
diff --git a/storage/innobase/mysql-test/storage_engine/repair_table.rdiff b/storage/innobase/mysql-test/storage_engine/repair_table.rdiff
new file mode 100644
index 00000000000..9c51fea47ff
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/repair_table.rdiff
@@ -0,0 +1,129 @@
+--- suite/storage_engine/repair_table.result 2012-07-15 01:26:44.347708000 +0400
++++ suite/storage_engine/repair_table.reject 2012-07-15 17:50:37.927013454 +0400
+@@ -4,56 +4,57 @@
+ CREATE TABLE t2 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ REPAIR TABLE t1;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (3,'c');
+ INSERT INTO t2 (a,b) VALUES (4,'d');
+ REPAIR NO_WRITE_TO_BINLOG TABLE t1, t2;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
+-test.t2 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
++test.t2 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t2 (a,b) VALUES (5,'e'),(6,'f');
+ REPAIR LOCAL TABLE t2;
+ Table Op Msg_type Msg_text
+-test.t2 repair status OK
++test.t2 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (7,'g'),(8,'h');
+ INSERT INTO t2 (a,b) VALUES (9,'i');
+ REPAIR LOCAL TABLE t2, t1 EXTENDED;
+ Table Op Msg_type Msg_text
+-test.t2 repair status OK
+-test.t1 repair status OK
++test.t2 repair note The storage engine for the table doesn't support repair
++test.t1 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (10,'j');
+ INSERT INTO t2 (a,b) VALUES (11,'k');
+ REPAIR TABLE t1, t2 QUICK USE_FRM;
+ Table Op Msg_type Msg_text
+-test.t1 repair warning Number of rows changed from 0 to 6
+-test.t1 repair status OK
+-test.t2 repair warning Number of rows changed from 0 to 5
+-test.t2 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
++test.t2 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (12,'l');
+ INSERT INTO t2 (a,b) VALUES (13,'m');
+ REPAIR NO_WRITE_TO_BINLOG TABLE t1, t2 QUICK EXTENDED USE_FRM;
+ Table Op Msg_type Msg_text
+-test.t1 repair warning Number of rows changed from 0 to 7
+-test.t1 repair status OK
+-test.t2 repair warning Number of rows changed from 0 to 6
+-test.t2 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
++test.t2 repair note The storage engine for the table doesn't support repair
+ FLUSH TABLE t1;
+ INSERT INTO t1 (a,b) VALUES (14,'n');
+-ERROR HY000: Incorrect file format 't1'
+ # Statement ended with one of expected results (0,130,ER_FAILED_READ_FROM_PAR_FILE,ER_OPEN_AS_READONLY).
+ # If you got a difference in error message, just add it to rdiff file
+ CHECK TABLE t1;
+ Table Op Msg_type Msg_text
+-test.t1 check Error Incorrect file format 't1'
+-test.t1 check error Corrupt
++test.t1 check status OK
+ SELECT * FROM t1;
+-ERROR HY000: Incorrect file format 't1'
++a b
++1 a
++2 b
++3 c
++7 g
++8 h
++10 j
++12 l
++14 n
+ # Statement ended with one of expected results (0,130,ER_FAILED_READ_FROM_PAR_FILE,ER_OPEN_AS_READONLY).
+ # If you got a difference in error message, just add it to rdiff file
+ REPAIR TABLE t1;
+ Table Op Msg_type Msg_text
+-test.t1 repair Error Incorrect file format 't1'
+-test.t1 repair error Corrupt
++test.t1 repair note The storage engine for the table doesn't support repair
+ DROP TABLE t1, t2;
+ call mtr.add_suppression("Got an error from thread_id=.*");
+ call mtr.add_suppression("MySQL thread id .*, query id .* localhost.*root Checking table");
+@@ -62,45 +63,14 @@
+ CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>, <CUSTOM_INDEX> (a)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ REPAIR TABLE t1;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (7,'g'),(8,'h');
+ REPAIR TABLE t1 EXTENDED;
+ Table Op Msg_type Msg_text
+-test.t1 repair status OK
++test.t1 repair note The storage engine for the table doesn't support repair
+ INSERT INTO t1 (a,b) VALUES (10,'j');
+ REPAIR TABLE t1 USE_FRM;
+ Table Op Msg_type Msg_text
+-test.t1 repair warning Number of rows changed from 0 to 3
+-test.t1 repair status OK
+-t1.MYD
+-t1.MYI
++test.t1 repair note The storage engine for the table doesn't support repair
+ t1.frm
+-INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+-# Statement ended with one of expected results (0,144).
+-# If you got a difference in error message, just add it to rdiff file
+-FLUSH TABLE t1;
+-Restoring <DATADIR>/test/t1.MYD
+-CHECK TABLE t1;
+-Table Op Msg_type Msg_text
+-test.t1 check error Size of datafile is: 39 Should be: 65
+-test.t1 check error Corrupt
+-SELECT * FROM t1;
+-ERROR HY000: Incorrect key file for table 't1'; try to repair it
+-# Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+-# If you got a difference in error message, just add it to rdiff file
+-INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+-ERROR HY000: Table './test/t1' is marked as crashed and last (automatic?) repair failed
+-# Statement ended with one of expected results (0,144).
+-# If you got a difference in error message, just add it to rdiff file
+-FLUSH TABLE t1;
+-Restoring <DATADIR>/test/t1.MYI
+-CHECK TABLE t1;
+-Table Op Msg_type Msg_text
+-test.t1 check warning Table is marked as crashed and last repair failed
+-test.t1 check error Size of datafile is: 39 Should be: 65
+-test.t1 check error Corrupt
+-SELECT * FROM t1;
+-ERROR HY000: Table './test/t1' is marked as crashed and last (automatic?) repair failed
+-# Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+-# If you got a difference in error message, just add it to rdiff file
+ DROP TABLE t1;
diff --git a/storage/innobase/mysql-test/storage_engine/suite.opt b/storage/innobase/mysql-test/storage_engine/suite.opt
new file mode 100644
index 00000000000..28ae8786144
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/suite.opt
@@ -0,0 +1,4 @@
+--ignore-builtin-innodb
+--plugin-load=ha_innodb
+--innodb
+
diff --git a/storage/innobase/mysql-test/storage_engine/tbl_opt_data_index_dir.rdiff b/storage/innobase/mysql-test/storage_engine/tbl_opt_data_index_dir.rdiff
new file mode 100644
index 00000000000..47f624c73d9
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/tbl_opt_data_index_dir.rdiff
@@ -0,0 +1,18 @@
+--- suite/storage_engine/tbl_opt_data_index_dir.result 2012-06-24 23:55:19.539380000 +0400
++++ suite/storage_engine/tbl_opt_data_index_dir.reject 2012-07-15 17:51:04.070684784 +0400
+@@ -4,7 +4,7 @@
+ t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` char(8) DEFAULT NULL
+-) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 DATA DIRECTORY='<DATA_DIR>' INDEX DIRECTORY='<INDEX_DIR>'
++) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+ Warnings:
+ Warning 1618 <INDEX DIRECTORY> option ignored
+ SHOW CREATE TABLE t1;
+@@ -12,5 +12,5 @@
+ t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` char(8) DEFAULT NULL
+-) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 DATA DIRECTORY='<DATA_DIR>' INDEX DIRECTORY='<INDEX_DIR>'
++) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+ DROP TABLE t1;
diff --git a/storage/innobase/mysql-test/storage_engine/tbl_opt_insert_method.rdiff b/storage/innobase/mysql-test/storage_engine/tbl_opt_insert_method.rdiff
new file mode 100644
index 00000000000..468b82926f0
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/tbl_opt_insert_method.rdiff
@@ -0,0 +1,11 @@
+--- suite/storage_engine/tbl_opt_insert_method.result 2012-06-24 23:55:19.539380000 +0400
++++ suite/storage_engine/tbl_opt_insert_method.reject 2012-07-15 17:51:09.978610512 +0400
+@@ -5,7 +5,7 @@
+ t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` char(8) DEFAULT NULL
+-) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=FIRST
++) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+ ALTER TABLE t1 INSERT_METHOD=NO;
+ SHOW CREATE TABLE t1;
+ Table Create Table
diff --git a/storage/innobase/mysql-test/storage_engine/tbl_opt_key_block_size.opt b/storage/innobase/mysql-test/storage_engine/tbl_opt_key_block_size.opt
new file mode 100644
index 00000000000..7cd737b2b87
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/tbl_opt_key_block_size.opt
@@ -0,0 +1,3 @@
+--innodb-file-per-table=1
+--innodb-file-format=Barracuda
+
diff --git a/storage/innobase/mysql-test/storage_engine/tbl_opt_row_format.opt b/storage/innobase/mysql-test/storage_engine/tbl_opt_row_format.opt
new file mode 100644
index 00000000000..7cd737b2b87
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/tbl_opt_row_format.opt
@@ -0,0 +1,3 @@
+--innodb-file-per-table=1
+--innodb-file-format=Barracuda
+
diff --git a/storage/innobase/mysql-test/storage_engine/tbl_opt_row_format.rdiff b/storage/innobase/mysql-test/storage_engine/tbl_opt_row_format.rdiff
new file mode 100644
index 00000000000..4c0e0c375f5
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/tbl_opt_row_format.rdiff
@@ -0,0 +1,10 @@
+--- suite/storage_engine/tbl_opt_row_format.result 2012-06-24 23:55:19.539380000 +0400
++++ suite/storage_engine/tbl_opt_row_format.reject 2012-07-15 19:26:02.235049157 +0400
+@@ -1,5 +1,7 @@
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS> ROW_FORMAT=FIXED;
++Warnings:
++Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT.
+ SHOW CREATE TABLE t1;
+ Table Create Table
+ t1 CREATE TABLE `t1` (
diff --git a/storage/innobase/mysql-test/storage_engine/tbl_opt_union.rdiff b/storage/innobase/mysql-test/storage_engine/tbl_opt_union.rdiff
new file mode 100644
index 00000000000..cbdf5818022
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/tbl_opt_union.rdiff
@@ -0,0 +1,16 @@
+--- suite/storage_engine/tbl_opt_union.result 2012-06-24 23:55:19.539380000 +0400
++++ suite/storage_engine/tbl_opt_union.reject 2012-07-15 17:51:31.014346053 +0400
+@@ -4,11 +4,11 @@
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+-) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 UNION=(`child1`)
++) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+ ALTER TABLE t1 UNION = (child1,child2);
+ SHOW CREATE TABLE t1;
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+-) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 UNION=(`child1`,`child2`)
++) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+ DROP TABLE t1, child1, child2;
diff --git a/storage/innobase/mysql-test/storage_engine/trx/disabled.def b/storage/innobase/mysql-test/storage_engine/trx/disabled.def
new file mode 100644
index 00000000000..7b8a16d0b7a
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/trx/disabled.def
@@ -0,0 +1,2 @@
+cons_snapshot_serializable : MySQL:65146 (CONSISTENT SNAPSHOT does not work with SERIALIZABLE)
+
diff --git a/storage/innobase/mysql-test/storage_engine/trx/suite.opt b/storage/innobase/mysql-test/storage_engine/trx/suite.opt
new file mode 100644
index 00000000000..2bf66f067f6
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/trx/suite.opt
@@ -0,0 +1,5 @@
+--ignore-builtin-innodb
+--plugin-load=ha_innodb
+--innodb
+--innodb-lock-wait-timeout=1
+
diff --git a/storage/innobase/mysql-test/storage_engine/type_char_indexes.rdiff b/storage/innobase/mysql-test/storage_engine/type_char_indexes.rdiff
new file mode 100644
index 00000000000..7fce0a108e9
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/type_char_indexes.rdiff
@@ -0,0 +1,20 @@
+--- suite/storage_engine/type_char_indexes.result 2012-07-12 19:27:42.191013570 +0400
++++ suite/storage_engine/type_char_indexes.reject 2012-07-15 17:51:55.810034331 +0400
+@@ -98,7 +98,7 @@
+ SET SESSION optimizer_switch = 'engine_condition_pushdown=on';
+ EXPLAIN SELECT * FROM t1 WHERE c > 'a';
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # range c_v c_v # # # Using index condition
++# # # range c_v c_v # # # Using where
+ SELECT * FROM t1 WHERE c > 'a';
+ c c20 v16 v128
+ b char3 varchar1a varchar1b
+@@ -135,7 +135,7 @@
+ r3a
+ EXPLAIN SELECT * FROM t1 WHERE v16 = 'varchar1a' OR v16 = 'varchar3a' ORDER BY v16;
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # range # v16 # # # #
++# # # ALL # NULL # # # #
+ SELECT * FROM t1 WHERE v16 = 'varchar1a' OR v16 = 'varchar3a' ORDER BY v16;
+ c c20 v16 v128
+ a char1 varchar1a varchar1b
diff --git a/storage/innobase/mysql-test/storage_engine/type_float_indexes.rdiff b/storage/innobase/mysql-test/storage_engine/type_float_indexes.rdiff
new file mode 100644
index 00000000000..6ebfd61d876
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/type_float_indexes.rdiff
@@ -0,0 +1,11 @@
+--- suite/storage_engine/type_float_indexes.result 2012-07-12 19:37:27.031661128 +0400
++++ suite/storage_engine/type_float_indexes.reject 2012-07-15 17:52:12.189828410 +0400
+@@ -60,7 +60,7 @@
+ ALTER TABLE t1 ADD UNIQUE KEY(d);
+ EXPLAIN SELECT d FROM t1 WHERE r > 0 and d > 0 ORDER BY d;
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # # # d # # # #
++# # # # # NULL # # # #
+ SELECT d FROM t1 WHERE r > 0 and d > 0 ORDER BY d;
+ d
+ 1.2345
diff --git a/storage/innobase/mysql-test/storage_engine/type_spatial_indexes.rdiff b/storage/innobase/mysql-test/storage_engine/type_spatial_indexes.rdiff
new file mode 100644
index 00000000000..9a9566deafb
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/type_spatial_indexes.rdiff
@@ -0,0 +1,712 @@
+--- suite/storage_engine/type_spatial_indexes.result 2012-07-12 04:52:40.840023344 +0400
++++ suite/storage_engine/type_spatial_indexes.reject 2012-07-15 19:27:32.761911079 +0400
+@@ -702,699 +702,15 @@
+ DROP DATABASE IF EXISTS gis_ogs;
+ CREATE DATABASE gis_ogs;
+ CREATE TABLE gis_point (fid <INT_COLUMN>, g POINT NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE gis_line (fid <INT_COLUMN>, g LINESTRING NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE gis_polygon (fid <INT_COLUMN>, g POLYGON NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE gis_multi_point (fid <INT_COLUMN>, g MULTIPOINT NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE gis_multi_line (fid <INT_COLUMN>, g MULTILINESTRING NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE gis_multi_polygon (fid <INT_COLUMN>, g MULTIPOLYGON NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE gis_geometrycollection (fid <INT_COLUMN>, g GEOMETRYCOLLECTION NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE gis_geometry (fid <INT_COLUMN>, g GEOMETRY NOT NULL) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-USE gis_ogs;
+-CREATE TABLE lakes (fid INT <CUSTOM_COL_OPTIONS>,
+-name CHAR(64) <CUSTOM_COL_OPTIONS>,
+-shore POLYGON NOT NULL, SPATIAL INDEX s(shore)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE road_segments (fid INT <CUSTOM_COL_OPTIONS>,
+-name CHAR(64) <CUSTOM_COL_OPTIONS>,
+-aliases CHAR(64) <CUSTOM_COL_OPTIONS>,
+-num_lanes INT <CUSTOM_COL_OPTIONS>,
+-centerline LINESTRING NOT NULL, SPATIAL INDEX c(centerline)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE divided_routes (fid INT <CUSTOM_COL_OPTIONS>,
+-name CHAR(64) <CUSTOM_COL_OPTIONS>,
+-num_lanes INT <CUSTOM_COL_OPTIONS>,
+-centerlines MULTILINESTRING NOT NULL, SPATIAL INDEX c(centerlines)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE forests (fid INT <CUSTOM_COL_OPTIONS>,
+-name CHAR(64) <CUSTOM_COL_OPTIONS>,
+-boundary MULTIPOLYGON NOT NULL, SPATIAL INDEX b(boundary)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE bridges (fid INT <CUSTOM_COL_OPTIONS>,
+-name CHAR(64) <CUSTOM_COL_OPTIONS>,
+-position POINT NOT NULL, SPATIAL INDEX p(position)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE streams (fid INT <CUSTOM_COL_OPTIONS>,
+-name CHAR(64) <CUSTOM_COL_OPTIONS>,
+-centerline LINESTRING NOT NULL, SPATIAL INDEX c(centerline)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE buildings (fid INT <CUSTOM_COL_OPTIONS>,
+-name CHAR(64) <CUSTOM_COL_OPTIONS>,
+-position POINT NOT NULL,
+-footprint POLYGON NOT NULL, SPATIAL INDEX p(position), SPATIAL INDEX f(footprint)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE ponds (fid INT <CUSTOM_COL_OPTIONS>,
+-name CHAR(64) <CUSTOM_COL_OPTIONS>,
+-type CHAR(64) <CUSTOM_COL_OPTIONS>,
+-shores MULTIPOLYGON NOT NULL, SPATIAL INDEX s(shores)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE named_places (fid INT <CUSTOM_COL_OPTIONS>,
+-name CHAR(64) <CUSTOM_COL_OPTIONS>,
+-boundary POLYGON NOT NULL, SPATIAL INDEX b(boundary)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-CREATE TABLE map_neatlines (fid INT <CUSTOM_COL_OPTIONS>,
+-neatline POLYGON NOT NULL, SPATIAL INDEX n(neatline)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-USE test;
+-SHOW FIELDS FROM gis_point;
+-Field Type Null Key Default Extra
+-fid int(11) YES NULL
+-g point NO MUL NULL
+-SHOW FIELDS FROM gis_line;
+-Field Type Null Key Default Extra
+-fid int(11) YES NULL
+-g linestring NO MUL NULL
+-SHOW FIELDS FROM gis_polygon;
+-Field Type Null Key Default Extra
+-fid int(11) YES NULL
+-g polygon NO MUL NULL
+-SHOW FIELDS FROM gis_multi_point;
+-Field Type Null Key Default Extra
+-fid int(11) YES NULL
+-g multipoint NO MUL NULL
+-SHOW FIELDS FROM gis_multi_line;
+-Field Type Null Key Default Extra
+-fid int(11) YES NULL
+-g multilinestring NO MUL NULL
+-SHOW FIELDS FROM gis_multi_polygon;
+-Field Type Null Key Default Extra
+-fid int(11) YES NULL
+-g multipolygon NO MUL NULL
+-SHOW FIELDS FROM gis_geometrycollection;
+-Field Type Null Key Default Extra
+-fid int(11) YES NULL
+-g geometrycollection NO MUL NULL
+-SHOW FIELDS FROM gis_geometry;
+-Field Type Null Key Default Extra
+-fid int(11) YES NULL
+-g geometry NO NULL
+-INSERT INTO gis_point VALUES
+-(101, PointFromText('POINT(10 10)')),
+-(102, PointFromText('POINT(20 10)')),
+-(103, PointFromText('POINT(20 20)')),
+-(104, PointFromWKB(AsWKB(PointFromText('POINT(10 20)'))));
+-INSERT INTO gis_line VALUES
+-(105, LineFromText('LINESTRING(0 0,0 10,10 0)')),
+-(106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
+-(107, LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));
+-INSERT INTO gis_polygon VALUES
+-(108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
+-(109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')),
+-(110, PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))));
+-INSERT INTO gis_multi_point VALUES
+-(111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
+-(112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
+-(113, MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));
+-INSERT INTO gis_multi_line VALUES
+-(114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),
+-(115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
+-(116, MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))));
+-INSERT INTO gis_multi_polygon VALUES
+-(117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
+-(118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
+-(119, MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));
+-INSERT INTO gis_geometrycollection VALUES
+-(120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
+-(121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))),
+-(122, GeomFromText('GeometryCollection()')),
+-(123, GeomFromText('GeometryCollection EMPTY'));
+-INSERT into gis_geometry SELECT * FROM gis_point;
+-INSERT into gis_geometry SELECT * FROM gis_line;
+-INSERT into gis_geometry SELECT * FROM gis_polygon;
+-INSERT into gis_geometry SELECT * FROM gis_multi_point;
+-INSERT into gis_geometry SELECT * FROM gis_multi_line;
+-INSERT into gis_geometry SELECT * FROM gis_multi_polygon;
+-INSERT into gis_geometry SELECT * FROM gis_geometrycollection;
+-SELECT fid, AsText(g) FROM gis_point;
+-fid AsText(g)
+-101 POINT(10 10)
+-102 POINT(20 10)
+-103 POINT(20 20)
+-104 POINT(10 20)
+-SELECT fid, AsText(g) FROM gis_line;
+-fid AsText(g)
+-105 LINESTRING(0 0,0 10,10 0)
+-106 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+-107 LINESTRING(10 10,40 10)
+-SELECT fid, AsText(g) FROM gis_polygon;
+-fid AsText(g)
+-108 POLYGON((10 10,20 10,20 20,10 20,10 10))
+-109 POLYGON((0 0,50 0,50 50,0 50,0 0),(10 10,20 10,20 20,10 20,10 10))
+-110 POLYGON((0 0,30 0,30 30,0 0))
+-SELECT fid, AsText(g) FROM gis_multi_point;
+-fid AsText(g)
+-111 MULTIPOINT(0 0,10 10,10 20,20 20)
+-112 MULTIPOINT(1 1,11 11,11 21,21 21)
+-113 MULTIPOINT(3 6,4 10)
+-SELECT fid, AsText(g) FROM gis_multi_line;
+-fid AsText(g)
+-114 MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))
+-115 MULTILINESTRING((10 48,10 21,10 0))
+-116 MULTILINESTRING((1 2,3 5),(2 5,5 8,21 7))
+-SELECT fid, AsText(g) FROM gis_multi_polygon;
+-fid AsText(g)
+-117 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+-118 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+-119 MULTIPOLYGON(((0 3,3 3,3 0,0 3)))
+-SELECT fid, AsText(g) FROM gis_geometrycollection;
+-fid AsText(g)
+-120 GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,10 10))
+-121 GEOMETRYCOLLECTION(POINT(44 6),LINESTRING(3 6,7 9))
+-122 GEOMETRYCOLLECTION EMPTY
+-123 GEOMETRYCOLLECTION EMPTY
+-SELECT fid, AsText(g) FROM gis_geometry;
+-fid AsText(g)
+-101 POINT(10 10)
+-102 POINT(20 10)
+-103 POINT(20 20)
+-104 POINT(10 20)
+-105 LINESTRING(0 0,0 10,10 0)
+-106 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+-107 LINESTRING(10 10,40 10)
+-108 POLYGON((10 10,20 10,20 20,10 20,10 10))
+-109 POLYGON((0 0,50 0,50 50,0 50,0 0),(10 10,20 10,20 20,10 20,10 10))
+-110 POLYGON((0 0,30 0,30 30,0 0))
+-111 MULTIPOINT(0 0,10 10,10 20,20 20)
+-112 MULTIPOINT(1 1,11 11,11 21,21 21)
+-113 MULTIPOINT(3 6,4 10)
+-114 MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))
+-115 MULTILINESTRING((10 48,10 21,10 0))
+-116 MULTILINESTRING((1 2,3 5),(2 5,5 8,21 7))
+-117 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+-118 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+-119 MULTIPOLYGON(((0 3,3 3,3 0,0 3)))
+-120 GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,10 10))
+-121 GEOMETRYCOLLECTION(POINT(44 6),LINESTRING(3 6,7 9))
+-122 GEOMETRYCOLLECTION EMPTY
+-123 GEOMETRYCOLLECTION EMPTY
+-SELECT fid, Dimension(g) FROM gis_geometry;
+-fid Dimension(g)
+-101 0
+-102 0
+-103 0
+-104 0
+-105 1
+-106 1
+-107 1
+-108 2
+-109 2
+-110 2
+-111 0
+-112 0
+-113 0
+-114 1
+-115 1
+-116 1
+-117 2
+-118 2
+-119 2
+-120 1
+-121 1
+-122 0
+-123 0
+-SELECT fid, GeometryType(g) FROM gis_geometry;
+-fid GeometryType(g)
+-101 POINT
+-102 POINT
+-103 POINT
+-104 POINT
+-105 LINESTRING
+-106 LINESTRING
+-107 LINESTRING
+-108 POLYGON
+-109 POLYGON
+-110 POLYGON
+-111 MULTIPOINT
+-112 MULTIPOINT
+-113 MULTIPOINT
+-114 MULTILINESTRING
+-115 MULTILINESTRING
+-116 MULTILINESTRING
+-117 MULTIPOLYGON
+-118 MULTIPOLYGON
+-119 MULTIPOLYGON
+-120 GEOMETRYCOLLECTION
+-121 GEOMETRYCOLLECTION
+-122 GEOMETRYCOLLECTION
+-123 GEOMETRYCOLLECTION
+-SELECT fid, IsEmpty(g) FROM gis_geometry;
+-fid IsEmpty(g)
+-101 0
+-102 0
+-103 0
+-104 0
+-105 0
+-106 0
+-107 0
+-108 0
+-109 0
+-110 0
+-111 0
+-112 0
+-113 0
+-114 0
+-115 0
+-116 0
+-117 0
+-118 0
+-119 0
+-120 0
+-121 0
+-122 0
+-123 0
+-SELECT fid, AsText(Envelope(g)) FROM gis_geometry;
+-fid AsText(Envelope(g))
+-101 POLYGON((10 10,10 10,10 10,10 10,10 10))
+-102 POLYGON((20 10,20 10,20 10,20 10,20 10))
+-103 POLYGON((20 20,20 20,20 20,20 20,20 20))
+-104 POLYGON((10 20,10 20,10 20,10 20,10 20))
+-105 POLYGON((0 0,10 0,10 10,0 10,0 0))
+-106 POLYGON((10 10,20 10,20 20,10 20,10 10))
+-107 POLYGON((10 10,40 10,40 10,10 10,10 10))
+-108 POLYGON((10 10,20 10,20 20,10 20,10 10))
+-109 POLYGON((0 0,50 0,50 50,0 50,0 0))
+-110 POLYGON((0 0,30 0,30 30,0 30,0 0))
+-111 POLYGON((0 0,20 0,20 20,0 20,0 0))
+-112 POLYGON((1 1,21 1,21 21,1 21,1 1))
+-113 POLYGON((3 6,4 6,4 10,3 10,3 6))
+-114 POLYGON((10 0,16 0,16 48,10 48,10 0))
+-115 POLYGON((10 0,10 0,10 48,10 48,10 0))
+-116 POLYGON((1 2,21 2,21 8,1 8,1 2))
+-117 POLYGON((28 0,84 0,84 42,28 42,28 0))
+-118 POLYGON((28 0,84 0,84 42,28 42,28 0))
+-119 POLYGON((0 0,3 0,3 3,0 3,0 0))
+-120 POLYGON((0 0,10 0,10 10,0 10,0 0))
+-121 POLYGON((3 6,44 6,44 9,3 9,3 6))
+-122 GEOMETRYCOLLECTION EMPTY
+-123 GEOMETRYCOLLECTION EMPTY
+-SELECT fid, X(g) FROM gis_point;
+-fid X(g)
+-101 10
+-102 20
+-103 20
+-104 10
+-SELECT fid, Y(g) FROM gis_point;
+-fid Y(g)
+-101 10
+-102 10
+-103 20
+-104 20
+-SELECT fid, AsText(StartPoint(g)) FROM gis_line;
+-fid AsText(StartPoint(g))
+-105 POINT(0 0)
+-106 POINT(10 10)
+-107 POINT(10 10)
+-SELECT fid, AsText(EndPoint(g)) FROM gis_line;
+-fid AsText(EndPoint(g))
+-105 POINT(10 0)
+-106 POINT(10 10)
+-107 POINT(40 10)
+-SELECT fid, GLength(g) FROM gis_line;
+-fid GLength(g)
+-105 24.14213562373095
+-106 40
+-107 30
+-SELECT fid, NumPoints(g) FROM gis_line;
+-fid NumPoints(g)
+-105 3
+-106 5
+-107 2
+-SELECT fid, AsText(PointN(g, 2)) FROM gis_line;
+-fid AsText(PointN(g, 2))
+-105 POINT(0 10)
+-106 POINT(20 10)
+-107 POINT(40 10)
+-SELECT fid, IsClosed(g) FROM gis_line;
+-fid IsClosed(g)
+-105 0
+-106 1
+-107 0
+-SELECT fid, AsText(Centroid(g)) FROM gis_polygon;
+-fid AsText(Centroid(g))
+-108 POINT(15 15)
+-109 POINT(25.416666666666668 25.416666666666668)
+-110 POINT(20 10)
+-SELECT fid, Area(g) FROM gis_polygon;
+-fid Area(g)
+-108 100
+-109 2400
+-110 450
+-SELECT fid, AsText(ExteriorRing(g)) FROM gis_polygon;
+-fid AsText(ExteriorRing(g))
+-108 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+-109 LINESTRING(0 0,50 0,50 50,0 50,0 0)
+-110 LINESTRING(0 0,30 0,30 30,0 0)
+-SELECT fid, NumInteriorRings(g) FROM gis_polygon;
+-fid NumInteriorRings(g)
+-108 0
+-109 1
+-110 0
+-SELECT fid, AsText(InteriorRingN(g, 1)) FROM gis_polygon;
+-fid AsText(InteriorRingN(g, 1))
+-108 NULL
+-109 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+-110 NULL
+-SELECT fid, IsClosed(g) FROM gis_multi_line;
+-fid IsClosed(g)
+-114 0
+-115 0
+-116 0
+-SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon;
+-fid AsText(Centroid(g))
+-117 POINT(55.58852775304245 17.426536064113982)
+-118 POINT(55.58852775304245 17.426536064113982)
+-119 POINT(2 2)
+-SELECT fid, Area(g) FROM gis_multi_polygon;
+-fid Area(g)
+-117 1684.5
+-118 1684.5
+-119 4.5
+-SELECT fid, NumGeometries(g) from gis_multi_point;
+-fid NumGeometries(g)
+-111 4
+-112 4
+-113 2
+-SELECT fid, NumGeometries(g) from gis_multi_line;
+-fid NumGeometries(g)
+-114 2
+-115 1
+-116 2
+-SELECT fid, NumGeometries(g) from gis_multi_polygon;
+-fid NumGeometries(g)
+-117 2
+-118 2
+-119 1
+-SELECT fid, NumGeometries(g) from gis_geometrycollection;
+-fid NumGeometries(g)
+-120 2
+-121 2
+-122 0
+-123 0
+-SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point;
+-fid AsText(GeometryN(g, 2))
+-111 POINT(10 10)
+-112 POINT(11 11)
+-113 POINT(4 10)
+-SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_line;
+-fid AsText(GeometryN(g, 2))
+-114 LINESTRING(16 0,16 23,16 48)
+-115 NULL
+-116 LINESTRING(2 5,5 8,21 7)
+-SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_polygon;
+-fid AsText(GeometryN(g, 2))
+-117 POLYGON((59 18,67 18,67 13,59 13,59 18))
+-118 POLYGON((59 18,67 18,67 13,59 13,59 18))
+-119 NULL
+-SELECT fid, AsText(GeometryN(g, 2)) from gis_geometrycollection;
+-fid AsText(GeometryN(g, 2))
+-120 LINESTRING(0 0,10 10)
+-121 LINESTRING(3 6,7 9)
+-122 NULL
+-123 NULL
+-SELECT fid, AsText(GeometryN(g, 1)) from gis_geometrycollection;
+-fid AsText(GeometryN(g, 1))
+-120 POINT(0 0)
+-121 POINT(44 6)
+-122 NULL
+-123 NULL
+-SELECT g1.fid as first, g2.fid as second,
+-Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o,
+-Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
+-Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r
+-FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
+-first second w c o e d t i r
+-120 120 1 1 0 1 0 1 1 0
+-120 121 0 0 1 0 0 0 1 0
+-120 122 0 1 NULL 0 NULL 0 NULL 0
+-120 123 0 1 NULL 0 NULL 0 NULL 0
+-121 120 0 0 1 0 0 0 1 0
+-121 121 1 1 0 1 0 1 1 0
+-121 122 0 1 NULL 0 NULL 0 NULL 0
+-121 123 0 1 NULL 0 NULL 0 NULL 0
+-122 120 1 0 NULL 0 NULL 0 NULL 0
+-122 121 1 0 NULL 0 NULL 0 NULL 0
+-122 122 1 1 NULL 1 NULL 0 NULL 0
+-122 123 1 1 NULL 1 NULL 0 NULL 0
+-123 120 1 0 NULL 0 NULL 0 NULL 0
+-123 121 1 0 NULL 0 NULL 0 NULL 0
+-123 122 1 1 NULL 1 NULL 0 NULL 0
+-123 123 1 1 NULL 1 NULL 0 NULL 0
+-DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
+-USE gis_ogs;
+-# Lakes
+-INSERT INTO lakes VALUES (
+-101, 'BLUE LAKE',
+-PolyFromText(
+-'POLYGON(
+- (52 18,66 23,73 9,48 6,52 18),
+- (59 18,67 18,67 13,59 13,59 18)
+- )',
+-101));
+-# Road Segments
+-INSERT INTO road_segments VALUES(102, 'Route 5', NULL, 2,
+-LineFromText(
+-'LINESTRING( 0 18, 10 21, 16 23, 28 26, 44 31 )' ,101));
+-INSERT INTO road_segments VALUES(103, 'Route 5', 'Main Street', 4,
+-LineFromText(
+-'LINESTRING( 44 31, 56 34, 70 38 )' ,101));
+-INSERT INTO road_segments VALUES(104, 'Route 5', NULL, 2,
+-LineFromText(
+-'LINESTRING( 70 38, 72 48 )' ,101));
+-INSERT INTO road_segments VALUES(105, 'Main Street', NULL, 4,
+-LineFromText(
+-'LINESTRING( 70 38, 84 42 )' ,101));
+-INSERT INTO road_segments VALUES(106, 'Dirt Road by Green Forest', NULL,
+-1,
+-LineFromText(
+-'LINESTRING( 28 26, 28 0 )',101));
+-# DividedRoutes
+-INSERT INTO divided_routes VALUES(119, 'Route 75', 4,
+-MLineFromText(
+-'MULTILINESTRING((10 48,10 21,10 0),
+- (16 0,16 23,16 48))', 101));
+-# Forests
+-INSERT INTO forests VALUES(109, 'Green Forest',
+-MPolyFromText(
+-'MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),
+- (52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))',
+-101));
+-# Bridges
+-INSERT INTO bridges VALUES(110, 'Cam Bridge', PointFromText(
+-'POINT( 44 31 )', 101));
+-# Streams
+-INSERT INTO streams VALUES(111, 'Cam Stream',
+-LineFromText(
+-'LINESTRING( 38 48, 44 41, 41 36, 44 31, 52 18 )', 101));
+-INSERT INTO streams VALUES(112, NULL,
+-LineFromText(
+-'LINESTRING( 76 0, 78 4, 73 9 )', 101));
+-# Buildings
+-INSERT INTO buildings VALUES(113, '123 Main Street',
+-PointFromText(
+-'POINT( 52 30 )', 101),
+-PolyFromText(
+-'POLYGON( ( 50 31, 54 31, 54 29, 50 29, 50 31) )', 101));
+-INSERT INTO buildings VALUES(114, '215 Main Street',
+-PointFromText(
+-'POINT( 64 33 )', 101),
+-PolyFromText(
+-'POLYGON( ( 66 34, 62 34, 62 32, 66 32, 66 34) )', 101));
+-# Ponds
+-INSERT INTO ponds VALUES(120, NULL, 'Stock Pond',
+-MPolyFromText(
+-'MULTIPOLYGON( ( ( 24 44, 22 42, 24 40, 24 44) ),
+- ( ( 26 44, 26 40, 28 42, 26 44) ) )', 101));
+-# Named Places
+-INSERT INTO named_places VALUES(117, 'Ashton',
+-PolyFromText(
+-'POLYGON( ( 62 48, 84 48, 84 30, 56 30, 56 34, 62 48) )', 101));
+-INSERT INTO named_places VALUES(118, 'Goose Island',
+-PolyFromText(
+-'POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )', 101));
+-# Map Neatlines
+-INSERT INTO map_neatlines VALUES(115,
+-PolyFromText(
+-'POLYGON( ( 0 0, 0 48, 84 48, 84 0, 0 0 ) )', 101));
+-SELECT Dimension(shore)
+-FROM lakes
+-WHERE name = 'Blue Lake';
+-Dimension(shore)
+-2
+-SELECT GeometryType(centerlines)
+-FROM divided_routes
+-WHERE name = 'Route 75';
+-GeometryType(centerlines)
+-MULTILINESTRING
+-SELECT AsText(boundary)
+-FROM named_places
+-WHERE name = 'Goose Island';
+-AsText(boundary)
+-POLYGON((67 13,67 18,59 18,59 13,67 13))
+-SELECT AsText(PolyFromWKB(AsBinary(boundary),101))
+-FROM named_places
+-WHERE name = 'Goose Island';
+-AsText(PolyFromWKB(AsBinary(boundary),101))
+-POLYGON((67 13,67 18,59 18,59 13,67 13))
+-SELECT SRID(boundary)
+-FROM named_places
+-WHERE name = 'Goose Island';
+-SRID(boundary)
+-101
+-SELECT IsEmpty(centerline)
+-FROM road_segments
+-WHERE name = 'Route 5'
+-AND aliases = 'Main Street';
+-IsEmpty(centerline)
+-0
+-SELECT AsText(Envelope(boundary))
+-FROM named_places
+-WHERE name = 'Goose Island';
+-AsText(Envelope(boundary))
+-POLYGON((59 13,67 13,67 18,59 18,59 13))
+-SELECT X(position)
+-FROM bridges
+-WHERE name = 'Cam Bridge';
+-X(position)
+-44
+-SELECT Y(position)
+-FROM bridges
+-WHERE name = 'Cam Bridge';
+-Y(position)
+-31
+-SELECT AsText(StartPoint(centerline))
+-FROM road_segments
+-WHERE fid = 102;
+-AsText(StartPoint(centerline))
+-POINT(0 18)
+-SELECT AsText(EndPoint(centerline))
+-FROM road_segments
+-WHERE fid = 102;
+-AsText(EndPoint(centerline))
+-POINT(44 31)
+-SELECT GLength(centerline)
+-FROM road_segments
+-WHERE fid = 106;
+-GLength(centerline)
+-26
+-SELECT NumPoints(centerline)
+-FROM road_segments
+-WHERE fid = 102;
+-NumPoints(centerline)
+-5
+-SELECT AsText(PointN(centerline, 1))
+-FROM road_segments
+-WHERE fid = 102;
+-AsText(PointN(centerline, 1))
+-POINT(0 18)
+-SELECT AsText(Centroid(boundary))
+-FROM named_places
+-WHERE name = 'Goose Island';
+-AsText(Centroid(boundary))
+-POINT(63 15.5)
+-SELECT Area(boundary)
+-FROM named_places
+-WHERE name = 'Goose Island';
+-Area(boundary)
+-40
+-SELECT AsText(ExteriorRing(shore))
+-FROM lakes
+-WHERE name = 'Blue Lake';
+-AsText(ExteriorRing(shore))
+-LINESTRING(52 18,66 23,73 9,48 6,52 18)
+-SELECT NumInteriorRings(shore)
+-FROM lakes
+-WHERE name = 'Blue Lake';
+-NumInteriorRings(shore)
+-1
+-SELECT AsText(InteriorRingN(shore, 1))
+-FROM lakes
+-WHERE name = 'Blue Lake';
+-AsText(InteriorRingN(shore, 1))
+-LINESTRING(59 18,67 18,67 13,59 13,59 18)
+-SELECT NumGeometries(centerlines)
+-FROM divided_routes
+-WHERE name = 'Route 75';
+-NumGeometries(centerlines)
+-2
+-SELECT AsText(GeometryN(centerlines, 2))
+-FROM divided_routes
+-WHERE name = 'Route 75';
+-AsText(GeometryN(centerlines, 2))
+-LINESTRING(16 0,16 23,16 48)
+-SELECT IsClosed(centerlines)
+-FROM divided_routes
+-WHERE name = 'Route 75';
+-IsClosed(centerlines)
+-0
+-SELECT GLength(centerlines)
+-FROM divided_routes
+-WHERE name = 'Route 75';
+-GLength(centerlines)
+-96
+-SELECT AsText(Centroid(shores))
+-FROM ponds
+-WHERE fid = 120;
+-AsText(Centroid(shores))
+-POINT(25 42)
+-SELECT Area(shores)
+-FROM ponds
+-WHERE fid = 120;
+-Area(shores)
+-8
+-SELECT ST_Equals(boundary,
+-PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1))
+-FROM named_places
+-WHERE name = 'Goose Island';
+-ST_Equals(boundary,
+-PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1))
+-1
+-SELECT ST_Disjoint(centerlines, boundary)
+-FROM divided_routes, named_places
+-WHERE divided_routes.name = 'Route 75'
+-AND named_places.name = 'Ashton';
+-ST_Disjoint(centerlines, boundary)
+-1
+-SELECT ST_Touches(centerline, shore)
+-FROM streams, lakes
+-WHERE streams.name = 'Cam Stream'
+-AND lakes.name = 'Blue Lake';
+-ST_Touches(centerline, shore)
+-1
+-SELECT Crosses(road_segments.centerline, divided_routes.centerlines)
+-FROM road_segments, divided_routes
+-WHERE road_segments.fid = 102
+-AND divided_routes.name = 'Route 75';
+-Crosses(road_segments.centerline, divided_routes.centerlines)
+-1
+-SELECT ST_Intersects(road_segments.centerline, divided_routes.centerlines)
+-FROM road_segments, divided_routes
+-WHERE road_segments.fid = 102
+-AND divided_routes.name = 'Route 75';
+-ST_Intersects(road_segments.centerline, divided_routes.centerlines)
+-1
+-SELECT ST_Contains(forests.boundary, named_places.boundary)
+-FROM forests, named_places
+-WHERE forests.name = 'Green Forest'
+-AND named_places.name = 'Ashton';
+-ST_Contains(forests.boundary, named_places.boundary)
+-0
+-SELECT ST_Distance(position, boundary)
+-FROM bridges, named_places
+-WHERE bridges.name = 'Cam Bridge'
+-AND named_places.name = 'Ashton';
+-ST_Distance(position, boundary)
+-12
+-SELECT AsText(ST_Difference(named_places.boundary, forests.boundary))
+-FROM named_places, forests
+-WHERE named_places.name = 'Ashton'
+-AND forests.name = 'Green Forest';
+-AsText(ST_Difference(named_places.boundary, forests.boundary))
+-POLYGON((56 34,62 48,84 48,84 42,56 34))
+-SELECT AsText(ST_Union(shore, boundary))
+-FROM lakes, named_places
+-WHERE lakes.name = 'Blue Lake'
+-AND named_places.name = 'Goose Island';
+-AsText(ST_Union(shore, boundary))
+-POLYGON((48 6,52 18,66 23,73 9,48 6))
+-SELECT AsText(ST_SymDifference(shore, boundary))
+-FROM lakes, named_places
+-WHERE lakes.name = 'Blue Lake'
+-AND named_places.name = 'Ashton';
+-AsText(ST_SymDifference(shore, boundary))
+-MULTIPOLYGON(((48 6,52 18,66 23,73 9,48 6),(59 13,59 18,67 18,67 13,59 13)),((56 30,56 34,62 48,84 48,84 30,56 30)))
+-SELECT count(*)
+-FROM buildings, bridges
+-WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1;
+-count(*)
+-1
++ERROR HY000: The used table type doesn't support SPATIAL indexes
++# ERROR: Statement ended with errno 1464, errname ER_TABLE_CANT_HANDLE_SPKEYS (expected to succeed)
++# ------------ UNEXPECTED RESULT ------------
++# [ CREATE TABLE gis_point (fid INT(11) /*!*/ /*Custom column options*/, g POINT NOT NULL, SPATIAL INDEX(g)) ENGINE=InnoDB /*!*/ /*Custom table options*/ ]
++# The statement|command finished with ER_TABLE_CANT_HANDLE_SPKEYS.
++# Geometry types or spatial indexes or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ DROP DATABASE gis_ogs;
+ USE test;
diff --git a/storage/innobase/mysql-test/storage_engine/vcol.rdiff b/storage/innobase/mysql-test/storage_engine/vcol.rdiff
new file mode 100644
index 00000000000..2226062834e
--- /dev/null
+++ b/storage/innobase/mysql-test/storage_engine/vcol.rdiff
@@ -0,0 +1,82 @@
+--- suite/storage_engine/vcol.result 2012-07-12 20:24:16.628339715 +0400
++++ suite/storage_engine/vcol.reject 2012-07-15 17:53:17.457007891 +0400
+@@ -1,69 +1,12 @@
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1 (a <INT_COLUMN>, b <INT_COLUMN> GENERATED ALWAYS AS (a+1)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-SHOW COLUMNS IN t1;
+-Field Type Null Key Default Extra
+-a int(11) # #
+-b int(11) # # VIRTUAL
+-INSERT INTO t1 (a) VALUES (1),(2);
+-INSERT INTO t1 (a,b) VALUES (3,3),(4,4);
+-Warnings:
+-Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+-Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+-SELECT * FROM t1;
+-a b
+-1 2
+-2 3
+-3 4
+-4 5
+-DROP TABLE t1;
+-CREATE TABLE t1 (a <INT_COLUMN>, b <INT_COLUMN> GENERATED ALWAYS AS (a+1) PERSISTENT) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-SHOW COLUMNS IN t1;
+-Field Type Null Key Default Extra
+-a int(11) # #
+-b int(11) # # PERSISTENT
+-INSERT INTO t1 (a) VALUES (1),(2);
+-INSERT INTO t1 (a,b) VALUES (3,3),(4,4);
+-Warnings:
+-Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+-Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+-SELECT * FROM t1;
+-a b
+-1 2
+-2 3
+-3 4
+-4 5
+-DROP TABLE t1;
+-CREATE TABLE t1 (a <INT_COLUMN>, b <INT_COLUMN> GENERATED ALWAYS AS (a+1) VIRTUAL) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-SHOW COLUMNS IN t1;
+-Field Type Null Key Default Extra
+-a int(11) # #
+-b int(11) # # VIRTUAL
+-INSERT INTO t1 (a) VALUES (1),(2);
+-INSERT INTO t1 (a,b) VALUES (3,3),(4,4);
+-Warnings:
+-Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+-Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+-SELECT * FROM t1;
+-a b
+-1 2
+-2 3
+-3 4
+-4 5
+-DROP TABLE t1;
+-CREATE TABLE t1 (a <INT_COLUMN>, b <INT_COLUMN> AS (a+1) PERSISTENT) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-SHOW COLUMNS IN t1;
+-Field Type Null Key Default Extra
+-a int(11) # #
+-b int(11) # # PERSISTENT
+-INSERT INTO t1 (a) VALUES (1),(2);
+-INSERT INTO t1 (a,b) VALUES (3,3),(4,4);
+-Warnings:
+-Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+-Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+-SELECT * FROM t1;
+-a b
+-1 2
+-2 3
+-3 4
+-4 5
+-DROP TABLE t1;
++ERROR HY000: InnoDB storage engine does not support computed columns
++# ERROR: Statement ended with errno 1910, errname ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS (expected to succeed)
++# ------------ UNEXPECTED RESULT ------------
++# [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/, b INT(11) /*!*/ /*Custom column options*/ GENERATED ALWAYS AS (a+1)) ENGINE=InnoDB /*!*/ /*Custom table options*/ ]
++# The statement|command finished with ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS.
++# Virtual columns or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 0694bf75ace..a99b6080e0a 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1433,7 +1433,8 @@ run_again:
check_index = foreign->foreign_index;
}
- if (check_table == NULL || check_table->ibd_file_missing) {
+ if (check_table == NULL || check_table->ibd_file_missing
+ || check_index == NULL) {
if (check_ref) {
FILE* ef = dict_foreign_err_file;
@@ -1465,9 +1466,6 @@ run_again:
goto exit_func;
}
- ut_a(check_table);
- ut_a(check_index);
-
if (check_table != table) {
/* We already have a LOCK_IX on table, but not necessarily
on check_table */
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index 98ec4a3a13b..0aad8675ff8 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -158,18 +158,6 @@ row_vers_impl_x_locked_low(
prev_trx_id = row_get_rec_trx_id(
prev_version, clust_index, clust_offsets);
- /* If trx_id differs from prev_trx_id and if the
- prev_version is marked deleted then the prev_trx_id
- must have already committed for the trx_id to be able
- to modify the row. Therefore, prev_trx_id cannot hold
- any implicit lock. */
-
- if (vers_del && trx_id != prev_trx_id) {
-
- trx_id = 0;
- break;
- }
-
/* The stack of versions is locked by mtr. Thus, it
is safe to fetch the prefixes for externally stored
columns. */
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index c3a53a18d90..80ebe0df2b3 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -1129,7 +1129,8 @@ trx_commit(
trx->must_flush_log_later = TRUE;
} else if (srv_flush_log_at_trx_commit == 0) {
/* Do nothing */
- } else if (srv_flush_log_at_trx_commit == 1) {
+ } else if (srv_flush_log_at_trx_commit == 1 ||
+ srv_flush_log_at_trx_commit == 3) {
if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
/* Write the log but do not flush it to disk */
@@ -1424,7 +1425,11 @@ trx_commit_complete_for_mysql(
/* Do nothing */
} else if (srv_flush_log_at_trx_commit == 0) {
/* Do nothing */
- } else if (srv_flush_log_at_trx_commit == 1) {
+ } else if (srv_flush_log_at_trx_commit == 1 && trx->active_commit_ordered) {
+ /* Do nothing - we already flushed the prepare and binlog write
+ to disk, so transaction is durable (will be recovered from
+ binlog if necessary) */
+ } else if (srv_flush_log_at_trx_commit == 1 || srv_flush_log_at_trx_commit == 3) {
if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
/* Write the log but do not flush it to disk */
@@ -1823,7 +1828,7 @@ trx_prepare(
if (srv_flush_log_at_trx_commit == 0) {
/* Do nothing */
- } else if (srv_flush_log_at_trx_commit == 1) {
+ } else if (srv_flush_log_at_trx_commit == 1 || srv_flush_log_at_trx_commit == 3) {
if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
/* Write the log but do not flush it to disk */
diff --git a/storage/maria/CMakeLists.txt b/storage/maria/CMakeLists.txt
index 2817e11681c..9ca198873d1 100644
--- a/storage/maria/CMakeLists.txt
+++ b/storage/maria/CMakeLists.txt
@@ -68,7 +68,7 @@ SET_TARGET_PROPERTIES(aria_dump_log PROPERTIES COMPILE_FLAGS "-DMARIA_DUMP_LOG")
MYSQL_ADD_EXECUTABLE(aria_pack maria_pack.c COMPONENT Server)
TARGET_LINK_LIBRARIES(aria_pack aria)
-IF(WITH_UNIT_TESTS AND FALSE)
+IF(WITH_UNIT_TESTS)
ADD_EXECUTABLE(ma_test1 ma_test1.c)
TARGET_LINK_LIBRARIES(ma_test1 aria)
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 958b1b837f5..f6124fdd9ff 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -235,7 +235,7 @@ static MYSQL_SYSVAR_ULONG(pagecache_age_threshold,
"until it is considered aged enough to be downgraded to a warm block. "
"This specifies the percentage ratio of that number of hits to the "
"total number of blocks in the page cache.", 0, 0,
- 300, 100, ~0L, 100);
+ 300, 100, ~ (ulong) 0L, 100);
static MYSQL_SYSVAR_ULONGLONG(pagecache_buffer_size, pagecache_buffer_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
@@ -1012,6 +1012,28 @@ const char *ha_maria::index_type(uint key_number)
}
+ulong ha_maria::index_flags(uint inx, uint part, bool all_parts) const
+{
+ ulong flags;
+ if (table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT)
+ flags= 0;
+ else
+ if ((table_share->key_info[inx].flags & HA_SPATIAL ||
+ table_share->key_info[inx].algorithm == HA_KEY_ALG_RTREE))
+ {
+ /* All GIS scans are non-ROR scans. We also disable IndexConditionPushdown */
+ flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
+ HA_READ_ORDER | HA_KEYREAD_ONLY | HA_KEY_SCAN_NOT_ROR;
+ }
+ else
+ {
+ flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
+ HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN;
+ }
+ return flags;
+}
+
+
double ha_maria::scan_time()
{
if (file->s->data_file_type == BLOCK_RECORD)
diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h
index aa8c0f17d48..2cba48c04aa 100644
--- a/storage/maria/ha_maria.h
+++ b/storage/maria/ha_maria.h
@@ -65,12 +65,7 @@ public:
const char **bas_ext() const;
ulonglong table_flags() const
{ return int_table_flags; }
- ulong index_flags(uint inx, uint part, bool all_parts) const
- {
- return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
- 0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
- HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN);
- }
+ ulong index_flags(uint inx, uint part, bool all_parts) const;
uint max_supported_keys() const
{ return MARIA_MAX_KEY; }
uint max_supported_key_length() const;
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 02cb01b581c..8e0407c9d7a 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -4677,6 +4677,8 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
MARIA_ROW *cur_row= &info->cur_row;
DBUG_ENTER("_ma_read_block_record2");
+ LINT_INIT(blob_buffer);
+
start_of_data= data;
flag= (uint) (uchar) data[0];
cur_null_bytes= share->base.original_null_bytes;
diff --git a/storage/maria/ma_ft_nlq_search.c b/storage/maria/ma_ft_nlq_search.c
index e57cc135ca1..5c1ab85ef8a 100644
--- a/storage/maria/ma_ft_nlq_search.c
+++ b/storage/maria/ma_ft_nlq_search.c
@@ -83,6 +83,8 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
#endif
DBUG_ENTER("walk_and_match");
+ LINT_INIT_STRUCT(subkeys);
+
word->weight=LWS_FOR_QUERY;
_ma_ft_make_key(info, &key, aio->keynr, keybuff, word, 0);
diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c
index 8b2dc4a1e07..502ac2b8809 100644
--- a/storage/maria/ma_key_recover.c
+++ b/storage/maria/ma_key_recover.c
@@ -946,7 +946,9 @@ uint _ma_apply_redo_index(MARIA_HA *info,
uint page_offset= 0, org_page_length;
uint page_length, keypage_header, keynr;
uint max_page_size= share->max_index_block_size;
- uint __attribute__((unused)) new_page_length= 0;
+#ifndef DBUG_OFF
+ uint new_page_length= 0;
+#endif
int result;
MARIA_PAGE page;
DBUG_ENTER("_ma_apply_redo_index");
@@ -1108,7 +1110,9 @@ uint _ma_apply_redo_index(MARIA_HA *info,
DBUG_PRINT("redo", ("org_page_length: %u new_page_length: %u",
uint2korr(header), uint2korr(header+2)));
DBUG_ASSERT(uint2korr(header) == page_length);
+#ifndef DBUG_OFF
new_page_length= min(uint2korr(header+2), max_page_size);
+#endif
header+= 4;
break;
case KEY_OP_MAX_PAGELENGTH:
diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c
index 2618d6a5b50..6aaccea219f 100644
--- a/storage/maria/ma_pagecache.c
+++ b/storage/maria/ma_pagecache.c
@@ -3372,6 +3372,7 @@ restart:
PAGECACHE_BLOCK_LINK *block;
uint status;
int page_st;
+ LINT_INIT(page_st);
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
if (!pagecache->can_be_used)
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index 3b774fb4283..ccb4bf77717 100644
--- a/storage/maria/ma_search.c
+++ b/storage/maria/ma_search.c
@@ -439,6 +439,10 @@ int _ma_prefix_search(const MARIA_KEY *key, const MARIA_PAGE *ma_page,
const uchar *sort_order= keyinfo->seg->charset->sort_order;
DBUG_ENTER("_ma_prefix_search");
+ LINT_INIT(seg_len_pack);
+ LINT_INIT(prefix_len);
+ LINT_INIT(length);
+
t_buff[0]=0; /* Avoid bugs */
page_flag= ma_page->flag;
nod_flag= ma_page->node;
diff --git a/storage/maria/ma_test_all.sh b/storage/maria/ma_test_all.sh
index 041fbf3abe6..4e9be4a5beb 100755
--- a/storage/maria/ma_test_all.sh
+++ b/storage/maria/ma_test_all.sh
@@ -7,13 +7,22 @@
#
#
+PRG='unittest/ma_test_all-t'
+UTST='../../unittest/unit.pl'
+
+if [ ! -x $PRG ] ; then
+ DIR=`dirname $0`
+ PRG="$DIR/unittest/ma_test_all-t"
+ UTST="$DIR/../../unittest/unit.pl"
+fi
+
if test -n "$1"; then
# unit.pl can't pass options to ma_test_all-t, so if anything
# was passed as an argument, assume the purpose was to pass
# them to ma_test_all-t and call it directly
- unittest/ma_test_all-t $@
+ $PRG $@
else
- perl ../../unittest/unit.pl run unittest/ma_test_all-t
+ perl $UTST run $PRG
fi
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index 27653ae5574..62225a7a4b0 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -21,9 +21,6 @@
#include <m_ctype.h>
#include <stdarg.h>
#include <my_getopt.h>
-#ifdef HAVE_SYS_VADVICE_H
-#include <sys/vadvise.h>
-#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
diff --git a/storage/myisam/CMakeLists.txt b/storage/myisam/CMakeLists.txt
index 97c1bc78d95..f58c942b4d7 100644
--- a/storage/myisam/CMakeLists.txt
+++ b/storage/myisam/CMakeLists.txt
@@ -46,7 +46,7 @@ TARGET_LINK_LIBRARIES(myisamlog myisam)
MYSQL_ADD_EXECUTABLE(myisampack myisampack.c COMPONENT Server)
TARGET_LINK_LIBRARIES(myisampack myisam)
-IF(WITH_UNIT_TESTS AND FALSE)
+IF(WITH_UNIT_TESTS)
ADD_EXECUTABLE(mi_test1 mi_test1.c)
TARGET_LINK_LIBRARIES(mi_test1 myisam)
diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c
index f419ac3d689..8b61e1dc4f2 100644
--- a/storage/myisam/ft_boolean_search.c
+++ b/storage/myisam/ft_boolean_search.c
@@ -352,7 +352,7 @@ static int _ftb_no_dupes_cmp(void* not_used __attribute__((unused)),
returns 1 if the search was finished (must-word wasn't found)
*/
-static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
+static int _ft2_search_no_lock(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
{
int r;
int subkeys=1;
@@ -452,7 +452,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
ftbw->key_root=info->s->state.key_root[ftb->keynr];
ftbw->keyinfo=info->s->keyinfo+ftb->keynr;
ftbw->off=0;
- return _ft2_search(ftb, ftbw, 0);
+ return _ft2_search_no_lock(ftb, ftbw, 0);
}
/* matching key found */
@@ -480,6 +480,18 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
return 0;
}
+static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search)
+{
+ int r;
+ MYISAM_SHARE *share= ftb->info->s;
+ if (share->concurrent_insert)
+ mysql_rwlock_rdlock(&share->key_root_lock[ftb->keynr]);
+ r= _ft2_search_no_lock(ftb, ftbw, init_search);
+ if (share->concurrent_insert)
+ mysql_rwlock_unlock(&share->key_root_lock[ftb->keynr]);
+ return r;
+}
+
static void _ftb_init_index_search(FT_INFO *ftb)
{
int i;
diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c
index e31075e55d1..bafa7064e28 100644
--- a/storage/myisam/ft_nlq_search.c
+++ b/storage/myisam/ft_nlq_search.c
@@ -70,9 +70,10 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
TREE_ELEMENT *selem;
double gweight=1;
MI_INFO *info=aio->info;
+ MYISAM_SHARE *share= info->s;
uchar *keybuff=aio->keybuff;
MI_KEYDEF *keyinfo=info->s->keyinfo+aio->keynr;
- my_off_t key_root=info->s->state.key_root[aio->keynr];
+ my_off_t key_root;
uint extra= HA_FT_WLEN + info->s->rec_reflength;
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
float tmp_weight;
@@ -80,6 +81,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
#error
#endif
DBUG_ENTER("walk_and_match");
+ LINT_INIT_STRUCT(subkeys);
word->weight=LWS_FOR_QUERY;
@@ -87,6 +89,11 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
keylen-=HA_FT_WLEN;
doc_cnt=0;
+ if (share->concurrent_insert)
+ mysql_rwlock_rdlock(&share->key_root_lock[aio->keynr]);
+
+ key_root= share->state.key_root[aio->keynr];
+
/* Skip rows inserted by current inserted */
for (r=_mi_search(info, keyinfo, keybuff, keylen, SEARCH_FIND, key_root) ;
!r &&
@@ -96,6 +103,9 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
info->lastkey_length, SEARCH_BIGGER, key_root))
;
+ if (share->concurrent_insert)
+ mysql_rwlock_unlock(&share->key_root_lock[aio->keynr]);
+
info->update|= HA_STATE_AKTIV; /* for _mi_test_if_changed() */
/* The following should be safe, even if we compare doubles */
@@ -119,6 +129,8 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
keyinfo=& info->s->ft2_keyinfo;
key_root=info->lastpos;
keylen=0;
+ if (share->concurrent_insert)
+ mysql_rwlock_rdlock(&share->key_root_lock[aio->keynr]);
r=_mi_search_first(info, keyinfo, key_root);
goto do_skip;
}
@@ -154,6 +166,9 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
if (gweight < 0 || doc_cnt > 2000000)
gweight=0;
+ if (share->concurrent_insert)
+ mysql_rwlock_rdlock(&share->key_root_lock[aio->keynr]);
+
if (_mi_test_if_changed(info) == 0)
r=_mi_search_next(info, keyinfo, info->lastkey, info->lastkey_length,
SEARCH_BIGGER, key_root);
@@ -166,6 +181,8 @@ do_skip:
r= _mi_search_next(info, keyinfo, info->lastkey, info->lastkey_length,
SEARCH_BIGGER, key_root);
+ if (share->concurrent_insert)
+ mysql_rwlock_unlock(&share->key_root_lock[aio->keynr]);
}
word->weight=gweight;
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 4ddaf520f7b..6eaf77a5d2d 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -689,6 +689,28 @@ const char *ha_myisam::index_type(uint key_number)
}
+ulong ha_myisam::index_flags(uint inx, uint part, bool all_parts) const
+{
+ ulong flags;
+ if (table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT)
+ flags= 0;
+ else
+ if ((table_share->key_info[inx].flags & HA_SPATIAL ||
+ table_share->key_info[inx].algorithm == HA_KEY_ALG_RTREE))
+ {
+ /* All GIS scans are non-ROR scans. We also disable IndexConditionPushdown */
+ flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
+ HA_READ_ORDER | HA_KEYREAD_ONLY | HA_KEY_SCAN_NOT_ROR;
+ }
+ else
+ {
+ flags= HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
+ HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN;
+ }
+ return flags;
+}
+
+
/* Name is here without an extension */
int ha_myisam::open(const char *name, int mode, uint test_if_locked)
{
diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h
index 7b0e9e8a1d7..42b4f7f1653 100644
--- a/storage/myisam/ha_myisam.h
+++ b/storage/myisam/ha_myisam.h
@@ -64,12 +64,7 @@ class ha_myisam: public handler
int index_end();
int rnd_end();
- ulong index_flags(uint inx, uint part, bool all_parts) const
- {
- return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ?
- 0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE |
- HA_READ_ORDER | HA_KEYREAD_ONLY | HA_DO_INDEX_COND_PUSHDOWN);
- }
+ ulong index_flags(uint inx, uint part, bool all_parts) const;
uint max_supported_keys() const { return MI_MAX_KEY; }
uint max_supported_key_parts() const { return HA_MAX_KEY_SEG; }
uint max_supported_key_length() const { return HA_MAX_KEY_LENGTH; }
diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c
index 92d7459dfc5..dab1f66ed6d 100644
--- a/storage/myisam/mi_extra.c
+++ b/storage/myisam/mi_extra.c
@@ -330,9 +330,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
if (!share->temporary)
flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map,
FLUSH_KEEP);
-#ifdef HAVE_PWRITE
_mi_decrement_open_count(info);
-#endif
if (share->not_flushed)
{
share->not_flushed=0;
diff --git a/storage/myisam/mi_test_all.sh b/storage/myisam/mi_test_all.sh
index 641f1cc0a35..c9c89a9ecac 100755
--- a/storage/myisam/mi_test_all.sh
+++ b/storage/myisam/mi_test_all.sh
@@ -99,7 +99,7 @@ if test -f mi_test1$MACH ; then suffix=$MACH ; else suffix=""; fi
# check of myisampack / myisamchk
./myisampack$suffix --force -s test1
# Ignore error for index file
-./myisamchk$suffix -es test1 2>&1 >& /dev/null
+./myisamchk$suffix -es test1 2>&1 > /dev/null
./myisamchk$suffix -rqs test1
./myisamchk$suffix -es test1
./myisamchk$suffix -rs test1
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index fa8cc679997..7d8b577e8b0 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -20,9 +20,6 @@
#include <stdarg.h>
#include <my_getopt.h>
#include <my_bit.h>
-#ifdef HAVE_SYS_VADVICE_H
-#include <sys/vadvise.h>
-#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
diff --git a/storage/myisam/mysql-test/mtr2/suite.pm b/storage/myisam/mysql-test/mtr2/suite.pm
new file mode 100644
index 00000000000..0f287e4a8ba
--- /dev/null
+++ b/storage/myisam/mysql-test/mtr2/suite.pm
@@ -0,0 +1,9 @@
+package My::Suite::MTR2::MyISAM;
+
+@ISA = qw(My::Suite);
+
+sub skip_combinations {(
+ 'combinations' => [ '1st' ],
+)}
+bless { };
+
diff --git a/storage/myisam/mysql-test/storage_engine/alter_tablespace.rdiff b/storage/myisam/mysql-test/storage_engine/alter_tablespace.rdiff
new file mode 100644
index 00000000000..3caf2ad6c3a
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/alter_tablespace.rdiff
@@ -0,0 +1,32 @@
+--- suite/storage_engine/alter_tablespace.result 2012-07-12 19:53:40.775419511 +0400
++++ suite/storage_engine/alter_tablespace.reject 2012-07-15 16:21:14.910435703 +0400
+@@ -1,19 +1,14 @@
+ DROP TABLE IF EXISTS t1, t2;
+ CREATE TABLE t1 (a <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ ALTER TABLE t1 DISCARD TABLESPACE;
+-DROP TABLE t1;
+-CREATE TABLE t1 (a <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+-INSERT INTO t1 (a) VALUES (1),(2);
+-SELECT * FROM t1;
+-a
+-1
+-2
+-ALTER TABLE t1 DISCARD TABLESPACE;
+-SELECT * FROM t1;
+-ERROR HY000: Got error -1 from storage engine
+-ALTER TABLE t1 IMPORT TABLESPACE;
+-SELECT * FROM t1;
+-a
+-1
+-2
++ERROR HY000: Table storage engine for 't1' doesn't have this option
++# ERROR: Statement ended with errno 1031, errname ER_ILLEGAL_HA (expected to succeed)
++# ------------ UNEXPECTED RESULT ------------
++# [ ALTER TABLE t1 DISCARD TABLESPACE ]
++# The statement|command finished with ER_ILLEGAL_HA.
++# Tablespace operations or the syntax or the mix could be unsupported.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ DROP TABLE t1;
diff --git a/storage/myisam/mysql-test/storage_engine/check_table.rdiff b/storage/myisam/mysql-test/storage_engine/check_table.rdiff
new file mode 100644
index 00000000000..48e8fc2e770
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/check_table.rdiff
@@ -0,0 +1,20 @@
+--- suite/storage_engine/check_table.result 2012-07-15 04:19:07.782936394 +0400
++++ suite/storage_engine/check_table.reject 2012-07-15 16:21:16.734412773 +0400
+@@ -18,7 +18,7 @@
+ INSERT INTO t1 (a,b) VALUES (6,'f');
+ CHECK TABLE t1 FAST;
+ Table Op Msg_type Msg_text
+-test.t1 check status OK
++test.t1 check status Table is already up to date
+ INSERT INTO t1 (a,b) VALUES (7,'g');
+ INSERT INTO t2 (a,b) VALUES (8,'h');
+ CHECK TABLE t2, t1 MEDIUM;
+@@ -52,7 +52,7 @@
+ INSERT INTO t1 (a) VALUES (17),(120),(132);
+ CHECK TABLE t1 FAST;
+ Table Op Msg_type Msg_text
+-test.t1 check status OK
++test.t1 check status Table is already up to date
+ INSERT INTO t1 (a) VALUES (801),(900),(7714);
+ CHECK TABLE t1 MEDIUM;
+ Table Op Msg_type Msg_text
diff --git a/storage/myisam/mysql-test/storage_engine/define_engine.inc b/storage/myisam/mysql-test/storage_engine/define_engine.inc
new file mode 100644
index 00000000000..d5e741629de
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/define_engine.inc
@@ -0,0 +1,45 @@
+###########################################
+#
+# This is a template of the include file define_engine.inc which
+# should be placed in storage/<engine>/mysql-test/storage_engine folder.
+#
+################################
+#
+# The name of the engine under test must be defined in $ENGINE variable.
+# You can set it either here (uncomment and edit) or in your environment.
+#
+let $ENGINE = MyISAM;
+#
+################################
+#
+# The following three variables define specific options for columns and tables.
+# Normally there should be none needed, but for some engines it can be different.
+# If the engine requires specific column option for all or indexed columns,
+# set them inside the comment, e.g. /*!NOT NULL*/.
+# Do the same for table options if needed, e.g. /*!INSERT_METHOD=LAST*/
+
+let $default_col_opts = /*!*/;
+let $default_col_indexed_opts = /*!*/;
+let $default_tbl_opts = /*!*/;
+
+# INDEX, UNIQUE INDEX, PRIMARY KEY, special index type - choose the fist that the engine allows,
+# or set it to /*!*/ if none is supported
+
+let $default_index = /*!INDEX*/;
+
+# If the engine does not support the following types, replace them with the closest possible
+
+let $default_int_type = INT(11);
+let $default_char_type = CHAR(8);
+
+################################
+
+--disable_query_log
+--disable_result_log
+
+# Here you can place your custom MTR code which needs to be executed before each test,
+# e.g. creation of an additional schema or table, etc.
+# The cleanup part should be defined in cleanup_engine.inc
+
+--enable_query_log
+--enable_result_log
diff --git a/storage/myisam/mysql-test/storage_engine/foreign_keys.rdiff b/storage/myisam/mysql-test/storage_engine/foreign_keys.rdiff
new file mode 100644
index 00000000000..67157754c04
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/foreign_keys.rdiff
@@ -0,0 +1,145 @@
+--- suite/storage_engine/foreign_keys.result 2012-07-12 18:56:19.782678645 +0400
++++ suite/storage_engine/foreign_keys.reject 2012-07-15 16:21:30.414240794 +0400
+@@ -12,29 +12,57 @@
+ t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ `b` char(8) DEFAULT NULL,
+- KEY `a` (`a`),
+- CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)
++ KEY `a` (`a`)
+ ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+ INSERT INTO t2 (a,b) VALUES (1,'a'),(2,'b');
+-ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
++# ERROR: Statement succeeded (expected results: ER_NO_REFERENCED_ROW_2)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command succeeded unexpectedly.
++# Foreign keys or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ INSERT INTO t1 (a,b) VALUES (1,'c'),(2,'d');
+ INSERT INTO t2 (a,b) VALUES (1,'a'),(2,'b');
+ UPDATE t2 SET a=a+1;
+-ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
++# ERROR: Statement succeeded (expected results: ER_NO_REFERENCED_ROW_2)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command succeeded unexpectedly.
++# Foreign keys or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ UPDATE t1 SET a=3 WHERE a=2;
+-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
++# ERROR: Statement succeeded (expected results: ER_ROW_IS_REFERENCED_2)
+ DELETE FROM t1 WHERE a=2;
+-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
++# ERROR: Statement succeeded (expected results: ER_ROW_IS_REFERENCED_2)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command succeeded unexpectedly.
++# Foreign keys or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ DELETE FROM t2 WHERE a=2;
+ SELECT * FROM t1;
+ a b
+ 1 c
+-2 d
++3 d
+ SELECT * FROM t2;
+ a b
+-1 a
++3 b
++3 b
+ DROP TABLE t1;
+-ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
++# ERROR: Statement succeeded (expected results: ER_ROW_IS_REFERENCED)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command succeeded unexpectedly.
++# Foreign keys or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ DROP TABLE t2;
+ CREATE TABLE t2 (a <INT_COLUMN>,
+ b <CHAR_COLUMN>,
+@@ -46,26 +74,65 @@
+ t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ `b` char(8) DEFAULT NULL,
+- KEY `a` (`a`),
+- CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`) ON DELETE CASCADE ON UPDATE CASCADE
++ KEY `a` (`a`)
+ ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+ INSERT INTO t2 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d');
+-ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`) ON DELETE CASCADE ON UPDATE CASCADE)
++# ERROR: Statement succeeded (expected results: ER_NO_REFERENCED_ROW_2)
+ INSERT INTO t1 (a,b) VALUES (3,'a'),(4,'a');
++ERROR 42S02: Table 'test.t1' doesn't exist
+ INSERT INTO t2 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(4,'e'),(3,'a');
+ UPDATE t1 SET a=a+1;
++ERROR 42S02: Table 'test.t1' doesn't exist
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_NO_SUCH_TABLE.
++# UPDATE or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ SELECT * FROM t2;
+ a b
+-5 a
+-5 a
+-5 b
+-5 c
+-5 d
+-5 e
++1 a
++1 a
++2 b
++2 b
++3 a
++3 c
++3 c
++4 d
++4 d
++4 e
+ DELETE FROM t1 WHERE b='a' LIMIT 2;
++ERROR 42S02: Table 'test.t1' doesn't exist
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_NO_SUCH_TABLE.
++# DELETE or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ SELECT * FROM t2;
+ a b
++1 a
++1 a
++2 b
++2 b
++3 a
++3 c
++3 c
++4 d
++4 d
++4 e
+ TRUNCATE TABLE t1;
+-ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`t1` (`a`))
++ERROR 42S02: Table 'test.t1' doesn't exist
++# ERROR: Statement ended with errno 1146, errname ER_NO_SUCH_TABLE (expected results: ER_TRUNCATE_ILLEGAL_FK)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command finished with ER_NO_SUCH_TABLE.
++# Foreign keys or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ DROP TABLE t2;
+ DROP TABLE t1;
++ERROR 42S02: Unknown table 't1'
diff --git a/storage/myisam/mysql-test/storage_engine/index_type_hash.rdiff b/storage/myisam/mysql-test/storage_engine/index_type_hash.rdiff
new file mode 100644
index 00000000000..e7fa0013fa9
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/index_type_hash.rdiff
@@ -0,0 +1,60 @@
+--- suite/storage_engine/index_type_hash.result 2012-07-15 01:10:17.919128889 +0400
++++ suite/storage_engine/index_type_hash.reject 2012-07-15 16:21:32.806210722 +0400
+@@ -4,7 +4,7 @@
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ SHOW KEYS IN t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 1 a 1 a # # NULL NULL # HASH
++t1 1 a 1 a # # NULL NULL # BTREE
+ DROP TABLE t1;
+ CREATE TABLE t1 (a <INT_COLUMN>,
+ b <CHAR_COLUMN>,
+@@ -12,8 +12,8 @@
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ SHOW KEYS IN t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 1 a_b 1 a # # NULL NULL # HASH a_b index
+-t1 1 a_b 2 b # # NULL NULL # HASH a_b index
++t1 1 a_b 1 a # # NULL NULL # BTREE a_b index
++t1 1 a_b 2 b # # NULL NULL # BTREE a_b index
+ DROP TABLE t1;
+ CREATE TABLE t1 (a <INT_COLUMN>,
+ b <CHAR_COLUMN>,
+@@ -22,8 +22,8 @@
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ SHOW KEYS IN t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 1 a 1 a # # NULL NULL # HASH
+-t1 1 b 1 b # # NULL NULL # HASH
++t1 1 a 1 a # # NULL NULL # BTREE
++t1 1 b 1 b # # NULL NULL # BTREE
+ DROP TABLE t1;
+ CREATE TABLE t1 (a <INT_COLUMN>,
+ b <CHAR_COLUMN>,
+@@ -31,7 +31,7 @@
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ SHOW KEYS IN t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 0 a 1 a # # NULL NULL # HASH
++t1 0 a 1 a # # NULL NULL # BTREE
+ INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+ INSERT INTO t1 (a,b) VALUES (1,'c');
+ ERROR 23000: Duplicate entry '1' for key 'a'
+@@ -43,7 +43,7 @@
+ ALTER TABLE t1 ADD <CUSTOM_INDEX> (a) USING HASH COMMENT 'simple index on a';
+ SHOW INDEX FROM t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 1 a 1 a # # NULL NULL # HASH simple index on a
++t1 1 a 1 a # # NULL NULL # BTREE simple index on a
+ ALTER TABLE t1 DROP KEY a;
+ DROP TABLE t1;
+ CREATE TABLE t1 (a <INT_COLUMN>,
+@@ -52,7 +52,7 @@
+ ) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ SHOW KEYS IN t1;
+ Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+-t1 0 a 1 a # # NULL NULL # HASH
++t1 0 a 1 a # # NULL NULL # BTREE
+ INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b');
+ INSERT INTO t1 (a,b) VALUES (1,'c');
+ ERROR 23000: Duplicate entry '1' for key 'a'
diff --git a/storage/myisam/mysql-test/storage_engine/show_engine.rdiff b/storage/myisam/mysql-test/storage_engine/show_engine.rdiff
new file mode 100644
index 00000000000..4e6624653ea
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/show_engine.rdiff
@@ -0,0 +1,10 @@
+--- suite/storage_engine/show_engine.result 2012-06-24 23:55:19.539380000 +0400
++++ suite/storage_engine/show_engine.reject 2012-07-15 16:21:54.401939228 +0400
+@@ -4,7 +4,6 @@
+ # volatile data (timestamps, memory info, etc.)
+ SHOW ENGINE <STORAGE_ENGINE> STATUS;
+ Type Name Status
+-<STORAGE_ENGINE> ### Engine status, can be long and changeable ###
+ # For SHOW MUTEX even the number of lines is volatile, so the result logging is disabled,
+ # the test only checks that the command does not produce any errors
+ SHOW ENGINE <STORAGE_ENGINE> MUTEX;
diff --git a/storage/myisam/mysql-test/storage_engine/tbl_opt_insert_method.rdiff b/storage/myisam/mysql-test/storage_engine/tbl_opt_insert_method.rdiff
new file mode 100644
index 00000000000..a8df852515a
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/tbl_opt_insert_method.rdiff
@@ -0,0 +1,11 @@
+--- suite/storage_engine/tbl_opt_insert_method.result 2012-06-24 23:55:19.539380000 +0400
++++ suite/storage_engine/tbl_opt_insert_method.reject 2012-07-15 16:21:56.381914337 +0400
+@@ -5,7 +5,7 @@
+ t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` char(8) DEFAULT NULL
+-) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=FIRST
++) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+ ALTER TABLE t1 INSERT_METHOD=NO;
+ SHOW CREATE TABLE t1;
+ Table Create Table
diff --git a/storage/myisam/mysql-test/storage_engine/tbl_opt_union.rdiff b/storage/myisam/mysql-test/storage_engine/tbl_opt_union.rdiff
new file mode 100644
index 00000000000..4fa164523db
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/tbl_opt_union.rdiff
@@ -0,0 +1,16 @@
+--- suite/storage_engine/tbl_opt_union.result 2012-06-24 23:55:19.539380000 +0400
++++ suite/storage_engine/tbl_opt_union.reject 2012-07-15 16:21:58.121892463 +0400
+@@ -4,11 +4,11 @@
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+-) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 UNION=(`child1`)
++) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+ ALTER TABLE t1 UNION = (child1,child2);
+ SHOW CREATE TABLE t1;
+ Table Create Table
+ t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL
+-) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 UNION=(`child1`,`child2`)
++) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+ DROP TABLE t1, child1, child2;
diff --git a/storage/myisam/mysql-test/storage_engine/trx/cons_snapshot_repeatable_read.rdiff b/storage/myisam/mysql-test/storage_engine/trx/cons_snapshot_repeatable_read.rdiff
new file mode 100644
index 00000000000..8d1434ad2fe
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/cons_snapshot_repeatable_read.rdiff
@@ -0,0 +1,9 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MyISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+13a20
+> 1
diff --git a/storage/myisam/mysql-test/storage_engine/trx/cons_snapshot_serializable.rdiff b/storage/myisam/mysql-test/storage_engine/trx/cons_snapshot_serializable.rdiff
new file mode 100644
index 00000000000..8d1434ad2fe
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/cons_snapshot_serializable.rdiff
@@ -0,0 +1,9 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MyISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+13a20
+> 1
diff --git a/storage/myisam/mysql-test/storage_engine/trx/delete.rdiff b/storage/myisam/mysql-test/storage_engine/trx/delete.rdiff
new file mode 100644
index 00000000000..491b4636796
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/delete.rdiff
@@ -0,0 +1,50 @@
+--- suite/storage_engine/trx/delete.result 2012-07-12 23:06:18.946113626 +0400
++++ suite/storage_engine/trx/delete.reject 2012-07-15 16:55:46.108397219 +0400
+@@ -1,3 +1,15 @@
++# -- WARNING ----------------------------------------------------------------
++# According to I_S.ENGINES, MyISAM does not support transactions.
++# If it is true, the test will most likely fail; you can
++# either create an rdiff file, or add the test to disabled.def.
++# If transactions should be supported, check the data in Information Schema.
++# ---------------------------------------------------------------------------
++# -- WARNING ----------------------------------------------------------------
++# According to I_S.ENGINES, MyISAM does not support savepoints.
++# If it is true, the test will most likely fail; you can
++# either create an rdiff file (recommended), or add the test to disabled.def.
++# If savepoints should be supported, check the data in Information Schema.
++# ---------------------------------------------------------------------------
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(6,'f'),(7,'g'),(8,'h'),(10000,'foobar');
+@@ -46,27 +58,17 @@
+ DELETE FROM t1;
+ RELEASE SAVEPOINT spt1;
+ ROLLBACK;
++Warnings:
++Warning 1196 Some non-transactional changed tables couldn't be rolled back
+ SELECT * FROM t1;
+ a b
+-10000 foobar
+-10000 foobar
+-2 b
+-2 b
+-4 d
+-4 d
+-5 e
+-5 e
+-6 f
+-6 f
+-7 g
+-7 g
+-8 h
+-8 h
+ BEGIN;
+ DELETE FROM t1 WHERE a <= 4 ORDER BY b DESC LIMIT 1;
+ SAVEPOINT spt1;
+ DELETE FROM t1;
+ INSERT INTO t1 (a,b) VALUES (1,'a');
+ ROLLBACK TO SAVEPOINT spt1;
++Warnings:
++Warning 1196 Some non-transactional changed tables couldn't be rolled back
+ COMMIT;
+ DROP TABLE t1;
diff --git a/storage/myisam/mysql-test/storage_engine/trx/insert.rdiff b/storage/myisam/mysql-test/storage_engine/trx/insert.rdiff
new file mode 100644
index 00000000000..4619db1d095
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/insert.rdiff
@@ -0,0 +1,65 @@
+--- suite/storage_engine/trx/insert.result 2012-07-12 23:09:44.663527407 +0400
++++ suite/storage_engine/trx/insert.reject 2012-07-15 16:55:46.676390078 +0400
+@@ -1,3 +1,15 @@
++# -- WARNING ----------------------------------------------------------------
++# According to I_S.ENGINES, MyISAM does not support transactions.
++# If it is true, the test will most likely fail; you can
++# either create an rdiff file, or add the test to disabled.def.
++# If transactions should be supported, check the data in Information Schema.
++# ---------------------------------------------------------------------------
++# -- WARNING ----------------------------------------------------------------
++# According to I_S.ENGINES, MyISAM does not support savepoints.
++# If it is true, the test will most likely fail; you can
++# either create an rdiff file (recommended), or add the test to disabled.def.
++# If savepoints should be supported, check the data in Information Schema.
++# ---------------------------------------------------------------------------
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ BEGIN;
+@@ -21,8 +33,11 @@
+ RELEASE SAVEPOINT spt1;
+ INSERT INTO t1 (a,b) VALUES (DEFAULT,DEFAULT);
+ ROLLBACK;
++Warnings:
++Warning 1196 Some non-transactional changed tables couldn't be rolled back
+ SELECT * FROM t1;
+ a b
++0 test
+ 1 a
+ 10 foo
+ 100 foo
+@@ -31,25 +46,34 @@
+ 3 c
+ 4 d
+ 5 e
++NULL NULL
++NULL NULL
+ BEGIN;
+ INSERT t1 (a) VALUE (10),(20);
+ SAVEPOINT spt1;
+ INSERT INTO t1 SET a = 11, b = 'f';
+ INSERT t1 SET b = DEFAULT;
+ ROLLBACK TO SAVEPOINT spt1;
++Warnings:
++Warning 1196 Some non-transactional changed tables couldn't be rolled back
+ INSERT INTO t1 (b,a) VALUES ('test1',10);
+ COMMIT;
+ SELECT * FROM t1;
+ a b
++0 test
+ 1 a
+ 10 NULL
+ 10 foo
+ 10 test1
+ 100 foo
+ 11 abc
++11 f
+ 2 b
+ 20 NULL
+ 3 c
+ 4 d
+ 5 e
++NULL NULL
++NULL NULL
++NULL NULL
+ DROP TABLE t1;
diff --git a/storage/myisam/mysql-test/storage_engine/trx/level_read_committed.rdiff b/storage/myisam/mysql-test/storage_engine/trx/level_read_committed.rdiff
new file mode 100644
index 00000000000..c0cc9ff9351
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/level_read_committed.rdiff
@@ -0,0 +1,44 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MyISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+18a25
+> 1
+25a33,34
+> 1
+> 2
+30a40,43
+> 1
+> 101
+> 102
+> 2
+34a48,49
+> 101
+> 102
+39a55,56
+> 101
+> 102
+44a62,63
+> 101
+> 102
+51a71,72
+> 101
+> 102
+54a76,77
+> 301
+> 302
+58a82,83
+> 101
+> 102
+61a87,88
+> 301
+> 302
+65a93,94
+> 101
+> 102
+68a98,99
+> 301
+> 302
diff --git a/storage/myisam/mysql-test/storage_engine/trx/level_read_uncommitted.rdiff b/storage/myisam/mysql-test/storage_engine/trx/level_read_uncommitted.rdiff
new file mode 100644
index 00000000000..2a7ddd33c8c
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/level_read_uncommitted.rdiff
@@ -0,0 +1,7 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MyISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
diff --git a/storage/myisam/mysql-test/storage_engine/trx/level_repeatable_read.rdiff b/storage/myisam/mysql-test/storage_engine/trx/level_repeatable_read.rdiff
new file mode 100644
index 00000000000..8b8df802275
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/level_repeatable_read.rdiff
@@ -0,0 +1,53 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MyISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+18a25
+> 1
+25a33,34
+> 1
+> 2
+27,28c36
+< ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+< # WARNING: Statement ended with errno 1205, errname 'ER_LOCK_WAIT_TIMEOUT'.
+---
+> # WARNING: Statement ended with errno 0, errname ''.
+31a40,43
+> 1
+> 101
+> 102
+> 2
+35a48,49
+> 101
+> 102
+40a55,56
+> 101
+> 102
+44a61,64
+> 1
+> 101
+> 102
+> 2
+49a70,73
+> 1
+> 101
+> 102
+> 2
+51a76,77
+> 301
+> 302
+55a82,83
+> 101
+> 102
+58a87,88
+> 301
+> 302
+62a93,94
+> 101
+> 102
+65a98,99
+> 301
+> 302
diff --git a/storage/myisam/mysql-test/storage_engine/trx/level_serializable.rdiff b/storage/myisam/mysql-test/storage_engine/trx/level_serializable.rdiff
new file mode 100644
index 00000000000..bbcb8ac1838
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/level_serializable.rdiff
@@ -0,0 +1,69 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MyISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+14,15c20
+< ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+< # WARNING: Statement ended with errno 1205, errname 'ER_LOCK_WAIT_TIMEOUT'.
+---
+> # WARNING: Statement ended with errno 0, errname ''.
+19a25
+> 1
+22,23c28
+< ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+< # WARNING: Statement ended with errno 1205, errname 'ER_LOCK_WAIT_TIMEOUT'.
+---
+> # WARNING: Statement ended with errno 0, errname ''.
+27a33,34
+> 1
+> 2
+32a40,43
+> 1
+> 101
+> 102
+> 2
+35a47,50
+> 1
+> 101
+> 102
+> 2
+38a54,57
+> 1
+> 101
+> 102
+> 2
+41a61,64
+> 1
+> 101
+> 102
+> 2
+46a70,77
+> 1
+> 101
+> 102
+> 2
+> 201
+> 202
+> 301
+> 302
+49a81,88
+> 1
+> 101
+> 102
+> 2
+> 201
+> 202
+> 301
+> 302
+52a92,99
+> 1
+> 101
+> 102
+> 2
+> 201
+> 202
+> 301
+> 302
diff --git a/storage/myisam/mysql-test/storage_engine/trx/select_for_update.rdiff b/storage/myisam/mysql-test/storage_engine/trx/select_for_update.rdiff
new file mode 100644
index 00000000000..08e0802a28f
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/select_for_update.rdiff
@@ -0,0 +1,50 @@
+--- suite/storage_engine/trx/select_for_update.result 2012-07-13 01:26:07.612653808 +0400
++++ suite/storage_engine/trx/select_for_update.reject 2012-07-15 16:55:49.784351006 +0400
+@@ -1,3 +1,9 @@
++# -- WARNING ----------------------------------------------------------------
++# According to I_S.ENGINES, MyISAM does not support transactions.
++# If it is true, the test will most likely fail; you can
++# either create an rdiff file, or add the test to disabled.def.
++# If transactions should be supported, check the data in Information Schema.
++# ---------------------------------------------------------------------------
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'a');
+@@ -14,16 +20,33 @@
+ 1 a
+ 3 a
+ SELECT * FROM t1 WHERE b='a' LOCK IN SHARE MODE;
+-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
++a b
++1 a
++3 a
++# ERROR: Statement succeeded (expected results: ER_LOCK_WAIT_TIMEOUT)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command succeeded unexpectedly.
++# SELECT .. FOR UPDATE or LOCK IN SHARE MODE or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ UPDATE t1 SET b='c' WHERE b='a';
+-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
++# ERROR: Statement succeeded (expected results: ER_LOCK_WAIT_TIMEOUT)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command succeeded unexpectedly.
++# UPDATE or SELECT .. FOR UPDATE or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ connection con1;
+ COMMIT;
+ SELECT * FROM t1;
+ a b
+-1 a
++1 c
+ 2 b
+-3 a
++3 c
+ disconnect con1;
+ connection default;
+ UPDATE t1 SET b='c' WHERE b='a';
diff --git a/storage/myisam/mysql-test/storage_engine/trx/select_lock_in_share_mode.rdiff b/storage/myisam/mysql-test/storage_engine/trx/select_lock_in_share_mode.rdiff
new file mode 100644
index 00000000000..97941bbdb13
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/select_lock_in_share_mode.rdiff
@@ -0,0 +1,37 @@
+--- suite/storage_engine/trx/select_lock_in_share_mode.result 2012-07-13 01:30:17.505512229 +0400
++++ suite/storage_engine/trx/select_lock_in_share_mode.reject 2012-07-15 16:55:50.444342708 +0400
+@@ -1,3 +1,9 @@
++# -- WARNING ----------------------------------------------------------------
++# According to I_S.ENGINES, MyISAM does not support transactions.
++# If it is true, the test will most likely fail; you can
++# either create an rdiff file, or add the test to disabled.def.
++# If transactions should be supported, check the data in Information Schema.
++# ---------------------------------------------------------------------------
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'a');
+@@ -18,14 +24,21 @@
+ 1 a
+ 3 a
+ UPDATE t1 SET b='c' WHERE b='a';
+-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
++# ERROR: Statement succeeded (expected results: ER_LOCK_WAIT_TIMEOUT)
++# ------------ UNEXPECTED RESULT ------------
++# The statement|command succeeded unexpectedly.
++# LOCK IN SHARE MODE or UPDATE or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
++# You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
++# Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
++# Also, this problem may cause a chain effect (more errors of different kinds in the test).
++# -------------------------------------------
+ connection con1;
+ COMMIT;
+ SELECT * FROM t1;
+ a b
+-1 a
++1 c
+ 2 b
+-3 a
++3 c
+ disconnect con1;
+ connection default;
+ UPDATE t1 SET b='c' WHERE b='a';
diff --git a/storage/myisam/mysql-test/storage_engine/trx/update.rdiff b/storage/myisam/mysql-test/storage_engine/trx/update.rdiff
new file mode 100644
index 00000000000..131286d613c
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/update.rdiff
@@ -0,0 +1,58 @@
+--- suite/storage_engine/trx/update.result 2012-07-13 01:43:50.355293322 +0400
++++ suite/storage_engine/trx/update.reject 2012-07-15 16:55:51.016335518 +0400
+@@ -1,3 +1,15 @@
++# -- WARNING ----------------------------------------------------------------
++# According to I_S.ENGINES, MyISAM does not support transactions.
++# If it is true, the test will most likely fail; you can
++# either create an rdiff file, or add the test to disabled.def.
++# If transactions should be supported, check the data in Information Schema.
++# ---------------------------------------------------------------------------
++# -- WARNING ----------------------------------------------------------------
++# According to I_S.ENGINES, MyISAM does not support savepoints.
++# If it is true, the test will most likely fail; you can
++# either create an rdiff file (recommended), or add the test to disabled.def.
++# If savepoints should be supported, check the data in Information Schema.
++# ---------------------------------------------------------------------------
+ DROP TABLE IF EXISTS t1;
+ CREATE TABLE t1 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+ INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e'),(10000,'foobar');
+@@ -24,25 +36,29 @@
+ UPDATE t1 SET b = 'update' WHERE a <= 4 ORDER BY a DESC, b ASC LIMIT 3;
+ UPDATE t1 SET b = '';
+ ROLLBACK;
++Warnings:
++Warning 1196 Some non-transactional changed tables couldn't be rolled back
+ BEGIN;
+ UPDATE t1 SET b = 'update2' WHERE a <= 100;
+ SAVEPOINT spt1;
+ UPDATE t1 SET b = '';
+ ROLLBACK TO SAVEPOINT spt1;
++Warnings:
++Warning 1196 Some non-transactional changed tables couldn't be rolled back
+ UPDATE t1 SET b = 'upd' WHERE a = 10050;
+ COMMIT;
+ SELECT * FROM t1;
+ a b
+ 10050 upd
+ 10050 upd
+-51 update2
+-51 update2
+-52 update2
+-52 update2
+-53 update2
+-53 update2
+-54 update2
+-54 update2
+-55 update2
+-55 update2
++51
++51
++52
++52
++53
++53
++54
++54
++55
++55
+ DROP TABLE t1;
diff --git a/storage/myisam/mysql-test/storage_engine/trx/xa.rdiff b/storage/myisam/mysql-test/storage_engine/trx/xa.rdiff
new file mode 100644
index 00000000000..f445ad909f3
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/xa.rdiff
@@ -0,0 +1,89 @@
+--- suite/storage_engine/trx/xa.result 2012-07-13 01:47:00.788899248 +0400
++++ suite/storage_engine/trx/xa.reject 2012-07-15 16:55:51.604328125 +0400
+@@ -1,3 +1,9 @@
++# -- WARNING ----------------------------------------------------------------
++# According to I_S.ENGINES, MyISAM does not support XA.
++# If it is true, the test will most likely fail; you can
++# either create an rdiff file, or add the test to disabled.def.
++# If XA should be supported, check the data in Information Schema.
++# ---------------------------------------------------------------------------
+ DROP TABLE IF EXISTS t1;
+ connect con1,localhost,root,,;
+ connect con2,localhost,root,,;
+@@ -9,17 +15,22 @@
+ connection con1;
+ SELECT * FROM t1;
+ a
++1
+ connection con2;
+ INSERT INTO t1 (a) VALUES (2);
+ XA END 'xa1';
+ connection con1;
+ SELECT * FROM t1;
+ a
++1
++2
+ connection con2;
+ XA PREPARE 'xa1';
+ connection con1;
+ SELECT * FROM t1;
+ a
++1
++2
+ connection con2;
+ XA RECOVER;
+ formatID gtrid_length bqual_length data
+@@ -38,6 +49,7 @@
+ a
+ 1
+ 2
++3
+ connection con2;
+ INSERT INTO t1 (a) VALUES (4);
+ XA END 'xa2';
+@@ -46,6 +58,8 @@
+ a
+ 1
+ 2
++3
++4
+ connection con2;
+ XA COMMIT 'xa2' ONE PHASE;
+ connection con1;
+@@ -65,6 +79,7 @@
+ 2
+ 3
+ 4
++5
+ connection con2;
+ INSERT INTO t1 (a) VALUES (6);
+ XA END 'xa3';
+@@ -75,6 +90,8 @@
+ 2
+ 3
+ 4
++5
++6
+ connection con2;
+ XA PREPARE 'xa3';
+ connection con1;
+@@ -84,8 +101,12 @@
+ 2
+ 3
+ 4
++5
++6
+ connection con2;
+ XA ROLLBACK 'xa3';
++Warnings:
++Warning 1196 Some non-transactional changed tables couldn't be rolled back
+ connection con1;
+ SELECT * FROM t1;
+ a
+@@ -93,4 +114,6 @@
+ 2
+ 3
+ 4
++5
++6
+ DROP TABLE t1;
diff --git a/storage/myisam/mysql-test/storage_engine/trx/xa_recovery.rdiff b/storage/myisam/mysql-test/storage_engine/trx/xa_recovery.rdiff
new file mode 100644
index 00000000000..f4629fb19a0
--- /dev/null
+++ b/storage/myisam/mysql-test/storage_engine/trx/xa_recovery.rdiff
@@ -0,0 +1,33 @@
+--- suite/storage_engine/trx/xa_recovery.result 2012-07-13 01:48:46.859565758 +0400
++++ suite/storage_engine/trx/xa_recovery.reject 2012-07-15 16:55:53.740301272 +0400
+@@ -1,3 +1,9 @@
++# -- WARNING ----------------------------------------------------------------
++# According to I_S.ENGINES, MyISAM does not support XA.
++# If it is true, the test will most likely fail; you can
++# either create an rdiff file, or add the test to disabled.def.
++# If XA should be supported, check the data in Information Schema.
++# ---------------------------------------------------------------------------
+ call mtr.add_suppression("Found 2 prepared XA transactions");
+ FLUSH TABLES;
+ DROP TABLE IF EXISTS t1;
+@@ -18,12 +24,18 @@
+ connection default;
+ XA RECOVER;
+ formatID gtrid_length bqual_length data
+-1 3 0 xa1
+-1 3 0 xa2
+ XA ROLLBACK 'xa1';
++ERROR XAE04: XAER_NOTA: Unknown XID
+ XA COMMIT 'xa2';
++ERROR XAE04: XAER_NOTA: Unknown XID
+ SELECT * FROM t1;
+ a
++1
++2
+ 3
+ 4
++Warnings:
++Error 145 Table './test/t1' is marked as crashed and should be repaired
++Error 1194 Table 't1' is marked as crashed and should be repaired
++Error 1034 1 client is using or hasn't closed the table properly
+ DROP TABLE t1;
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index 1fbdfe12d3d..093a2a6dcef 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -1635,6 +1635,47 @@ ha_rows ha_myisammrg::records()
return myrg_records(file);
}
+uint ha_myisammrg::count_query_cache_dependant_tables(uint8 *tables_type)
+{
+ MYRG_INFO *file = myrg_info();
+ /*
+ Here should be following statement
+ (*tables_type)|= HA_CACHE_TBL_NONTRANSACT;
+ but it has no effect because HA_CACHE_TBL_NONTRANSACT is 0
+ */
+ return (file->end_table - file->open_tables);
+}
+
+
+my_bool ha_myisammrg::register_query_cache_dependant_tables(THD *thd
+ __attribute__((unused)),
+ Query_cache *cache,
+ Query_cache_block_table **block_table,
+ uint *n)
+{
+ MYRG_INFO *file =myrg_info();
+ DBUG_ENTER("ha_myisammrg::register_query_cache_dependant_tables");
+
+ for (MYRG_TABLE *table =file->open_tables;
+ table != file->end_table ;
+ table++)
+ {
+ char key[MAX_DBKEY_LENGTH];
+ uint32 db_length;
+ uint key_length= cache->filename_2_table_key(key, table->table->filename,
+ &db_length);
+ (++(*block_table))->n= ++(*n);
+ /*
+ There are not callback function for for MyISAM, and engine data
+ */
+ if (!cache->insert_table(key_length, key, (*block_table),
+ db_length,
+ table_cache_type(),
+ 0, 0, TRUE))
+ DBUG_RETURN(TRUE);
+ }
+ DBUG_RETURN(FALSE);
+}
extern int myrg_panic(enum ha_panic_function flag);
int myisammrg_panic(handlerton *hton, ha_panic_function flag)
diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h
index e0dc6e07542..f5ba2ffef38 100644
--- a/storage/myisammrg/ha_myisammrg.h
+++ b/storage/myisammrg/ha_myisammrg.h
@@ -149,4 +149,10 @@ public:
bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes);
int check(THD* thd, HA_CHECK_OPT* check_opt);
ha_rows records();
+ virtual uint count_query_cache_dependant_tables(uint8 *tables_type);
+ virtual my_bool
+ register_query_cache_dependant_tables(THD *thd,
+ Query_cache *cache,
+ Query_cache_block_table **block,
+ uint *n);
};
diff --git a/storage/myisammrg/mysql-test/storage_engine/alter_table.inc b/storage/myisammrg/mysql-test/storage_engine/alter_table.inc
new file mode 100644
index 00000000000..a978ade4f75
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/alter_table.inc
@@ -0,0 +1,116 @@
+##################################
+#
+# This include file will be used for all ALTER TABLE statements in the suite.
+# If you need to add additional steps or change the logic, copy the file
+# to storage/<engine>/mysql-test/storage_engine/ folder and modify it there.
+#
+##################
+#
+# Parameters:
+#
+# --let $alter_definition = <alter definition> # mandatory, everything that goes after the table name in ALTER statement
+# --let $table_name = <table name> # optional, default t1
+# --let $error_codes = <expected error codes, as in --error> # optional, default 0
+# --let $online = [0|1] # optional, default 0 (1 adds ONLINE)
+# --let $rename_to = <new table name> # optional, default empty.
+# # If set, means we are running RENAME TO, then alter definition is ignored
+#
+# Usage examples:
+#
+# --let $alter_definition = ADD COLUMN b $char_col DEFAULT ''
+#
+
+--let $child_alter_definition = $alter_definition
+
+if ($rename_to)
+{
+ --let $alter_definition = RENAME TO $rename_to
+ --let $child_alter_definition = RENAME TO mrg.$rename_to
+}
+
+if (!$alter_definition)
+{
+ --die # The ALTER statement is empty
+}
+
+--let $alter_statement = ALTER
+
+if ($online)
+{
+ --let $alter_statement = $alter_statement ONLINE
+}
+
+if (!$table_name)
+{
+ --let $table_name = t1
+}
+
+--let $alter_statement = $alter_statement TABLE $table_name $alter_definition
+# We don't want to do ONLINE on underlying tables, we are not testing MyISAM
+--let $child_statement = ALTER TABLE mrg.$table_name $child_alter_definition
+
+
+
+# We now have the complete ALTER statement in $alter_statement.
+# If your ALTER statement should be composed differently,
+# modify the logic above.
+
+#####################
+# Here you can add logic needed BEFORE the main statement
+# (e.g. base tables need to be altered, etc.).
+# Surround it by --disable_query_log/--enable_query_log
+# if you don't want it to appear in the result output.
+#####################
+
+--source obfuscate.inc
+
+eval $alter_statement;
+--source check_errors.inc
+
+# Make sure you don't add any statements between the main ALTER (above)
+# and saving mysql_errno and mysql_errname (below)
+# They are saved in case you want to add more logic after the main ALTER,
+# because we need the result code of the statement.
+# Also, do not change $alter_statement after it is executed!
+
+--let $my_errno = $mysql_errno
+--let $my_errname = $mysql_errname
+
+#####################
+# Here you can add logic needed AFTER the main statement.
+# Surround it by --disable_query_log/--enable_query_log
+# if you don't want it to appear in the result output.
+#####################
+--disable_query_log
+--disable_warnings
+--disable_result_log
+# We will only try to alter the underlying table if the main alter was successful
+if (!$my_errno)
+{
+ if ($rename_to)
+ {
+ eval ALTER TABLE $rename_to UNION(mrg.$rename_to);
+ }
+ # In the same section, the manual says that FLUSH TABLES should be performed before altering
+ # the underlying table, and later also says that it should be done after. We'll do both
+ FLUSH TABLES;
+ eval $child_statement;
+ FLUSH TABLES;
+}
+--enable_result_log
+--enable_warnings
+--enable_query_log
+
+# Unset the parameters, we don't want them to be accidentally reused later
+--let $alter_definition =
+--let $table_name =
+--let $error_codes =
+--let $online = 0
+--let $rename_to =
+
+# Restore the error codes of the main statement
+--let $mysql_errno = $my_errno
+--let $mysql_errname = $my_errname
+# Make sure you don't add any SQL statements after restoring
+# mysql_errno and mysql_errname (above)
+
diff --git a/storage/myisammrg/mysql-test/storage_engine/alter_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/alter_table.rdiff
new file mode 100644
index 00000000000..447a38a5b2b
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/alter_table.rdiff
@@ -0,0 +1,68 @@
+11c11
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+19c19
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+27c27
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+35c35
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+43c43
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+51c51
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+59c59
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+67c67
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+75c75
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+82c82
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+91c91
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t2`)
+100c100
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+107c107
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+122c122
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 COLLATE=latin1_general_cs INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+130c130
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=utf8
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=utf8 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+138c138
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+146c146
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/alter_tablespace.rdiff b/storage/myisammrg/mysql-test/storage_engine/alter_tablespace.rdiff
new file mode 100644
index 00000000000..cfc821582ed
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/alter_tablespace.rdiff
@@ -0,0 +1,27 @@
+4,18c4,13
+< DROP TABLE t1;
+< CREATE TABLE t1 (a <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< INSERT INTO t1 (a) VALUES (1),(2);
+< SELECT * FROM t1;
+< a
+< 1
+< 2
+< ALTER TABLE t1 DISCARD TABLESPACE;
+< SELECT * FROM t1;
+< ERROR HY000: Got error -1 from storage engine
+< ALTER TABLE t1 IMPORT TABLESPACE;
+< SELECT * FROM t1;
+< a
+< 1
+< 2
+---
+> ERROR HY000: 'test.t1' is not BASE TABLE
+> # ERROR: Statement ended with errno 1347, errname ER_WRONG_OBJECT (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ ALTER TABLE t1 DISCARD TABLESPACE ]
+> # The statement|command finished with ER_WRONG_OBJECT.
+> # Tablespace operations or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
diff --git a/storage/myisammrg/mysql-test/storage_engine/analyze_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/analyze_table.rdiff
new file mode 100644
index 00000000000..139bcc00a81
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/analyze_table.rdiff
@@ -0,0 +1,22 @@
+8c8
+< test.t1 analyze status OK
+---
+> test.t1 analyze note The storage engine for the table doesn't support analyze
+12c12
+< test.t2 analyze status OK
+---
+> test.t2 analyze note The storage engine for the table doesn't support analyze
+17,18c17,18
+< test.t1 analyze status OK
+< test.t2 analyze status OK
+---
+> test.t1 analyze note The storage engine for the table doesn't support analyze
+> test.t2 analyze note The storage engine for the table doesn't support analyze
+24c24
+< test.t1 analyze status OK
+---
+> test.t1 analyze note The storage engine for the table doesn't support analyze
+28c28
+< test.t1 analyze status OK
+---
+> test.t1 analyze note The storage engine for the table doesn't support analyze
diff --git a/storage/myisammrg/mysql-test/storage_engine/autoincrement.rdiff b/storage/myisammrg/mysql-test/storage_engine/autoincrement.rdiff
new file mode 100644
index 00000000000..e9095aa3944
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/autoincrement.rdiff
@@ -0,0 +1,34 @@
+9c9
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+55c55
+< t1 <STORAGE_ENGINE> # # # # # # # # 6 # # # # # # #
+---
+> t1 <STORAGE_ENGINE> # # # # # # # # 0 # # # # # # #
+62c62
+< t1 # # # # # # # # # 8 # # # # # # #
+---
+> t1 # # # # # # # # # 0 # # # # # # #
+81c81
+< t1 # # # # # # # # # 10 # # # # # # #
+---
+> t1 # # # # # # # # # 0 # # # # # # #
+85c85
+< t1 # # # # # # # # # 21 # # # # # # #
+---
+> t1 # # # # # # # # # 0 # # # # # # #
+106c106
+< t1 # # # # # # # # # 22 # # # # # # #
+---
+> t1 # # # # # # # # # 0 # # # # # # #
+128,129c128,129
+< 100 a
+< 101 b
+---
+> 1 a
+> 2 b
+132c132
+< 100
+---
+> 1
diff --git a/storage/myisammrg/mysql-test/storage_engine/cache_index.rdiff b/storage/myisammrg/mysql-test/storage_engine/cache_index.rdiff
new file mode 100644
index 00000000000..e10b22a8e66
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/cache_index.rdiff
@@ -0,0 +1,46 @@
+15,16c15,16
+< test.t1 assign_to_keycache status OK
+< test.t2 assign_to_keycache status OK
+---
+> test.t1 assign_to_keycache note The storage engine for the table doesn't support assign_to_keycache
+> test.t2 assign_to_keycache note The storage engine for the table doesn't support assign_to_keycache
+19,20c19,20
+< test.t1 preload_keys status OK
+< test.t2 preload_keys status OK
+---
+> test.t1 preload_keys note The storage engine for the table doesn't support preload_keys
+> test.t2 preload_keys note The storage engine for the table doesn't support preload_keys
+25,26c25,26
+< test.t1 preload_keys status OK
+< test.t2 preload_keys status OK
+---
+> test.t1 preload_keys note The storage engine for the table doesn't support preload_keys
+> test.t2 preload_keys note The storage engine for the table doesn't support preload_keys
+31c31
+< test.t1 preload_keys status OK
+---
+> test.t1 preload_keys note The storage engine for the table doesn't support preload_keys
+35c35
+< test.t1 assign_to_keycache status OK
+---
+> test.t1 assign_to_keycache note The storage engine for the table doesn't support assign_to_keycache
+39c39
+< test.t1 preload_keys status OK
+---
+> test.t1 preload_keys note The storage engine for the table doesn't support preload_keys
+50c50
+< test.t1 assign_to_keycache status OK
+---
+> test.t1 assign_to_keycache note The storage engine for the table doesn't support assign_to_keycache
+54c54
+< test.t1 preload_keys status OK
+---
+> test.t1 preload_keys note The storage engine for the table doesn't support preload_keys
+62c62
+< test.t1 assign_to_keycache status OK
+---
+> test.t1 assign_to_keycache note The storage engine for the table doesn't support assign_to_keycache
+66c66
+< test.t1 preload_keys status OK
+---
+> test.t1 preload_keys note The storage engine for the table doesn't support preload_keys
diff --git a/storage/myisammrg/mysql-test/storage_engine/char_indexes.rdiff b/storage/myisammrg/mysql-test/storage_engine/char_indexes.rdiff
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/char_indexes.rdiff
diff --git a/storage/myisammrg/mysql-test/storage_engine/checksum_table_live.rdiff b/storage/myisammrg/mysql-test/storage_engine/checksum_table_live.rdiff
new file mode 100644
index 00000000000..1710cc18fea
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/checksum_table_live.rdiff
@@ -0,0 +1,6 @@
+14,15c14,15
+< test.t1 4272806499
+< test.t2 0
+---
+> test.t1 NULL
+> test.t2 NULL
diff --git a/storage/myisammrg/mysql-test/storage_engine/cleanup_engine.inc b/storage/myisammrg/mysql-test/storage_engine/cleanup_engine.inc
new file mode 100644
index 00000000000..b8f84110c76
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/cleanup_engine.inc
@@ -0,0 +1,16 @@
+###########################################
+#
+# This is a stub of the include file cleanup_engine.inc which
+# should be placed in storage/<engine>/mysql-test/storage_engine folder.
+#
+################################
+#
+# Here you can add whatever is needed to cleanup
+# in case your define_engine.inc created any artefacts,
+# e.g. an additional schema and/or tables.
+--disable_query_log
+--disable_warnings
+DROP DATABASE IF EXISTS mrg;
+--enable_warnings
+--enable_query_log
+
diff --git a/storage/myisammrg/mysql-test/storage_engine/create_table.inc b/storage/myisammrg/mysql-test/storage_engine/create_table.inc
new file mode 100644
index 00000000000..c74460d42fb
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/create_table.inc
@@ -0,0 +1,208 @@
+##################################
+#
+# This include file will be used for all CREATE TABLE statements in the suite.
+# If you need to add additional steps or change the logic, copy the file
+# to storage/<engine>/mysql-test/storage_engine/ folder and modify it there.
+#
+##################
+#
+# Parameters:
+#
+# --let $create_definition = <column names, types, indexes) # optional, default a $int_col, b $char_col (based on defaults)
+# --let $table_name = <table name> # optional, default t1
+# --let $table_options = <table options> # optional, default based on define_engine.inc
+# --let $partition_options = <partitioning definition> # optional, default none
+# --let $as_select = <SELECT statement> # optional, default empty
+# --let $error_codes = <expected error codes, as in --error> # optional, default 0
+# --let $if_not_exists = [0|1] # optional, default 0 (1 adds IF NOT EXISTS clause)
+# --let $default_engine = [0|1] # optional, default 0 (with 1 will rely on default engine, no ENGINE=)
+# --let $temporary = [0|1] # optional, default 0 (1 adds TEMPORARY)
+# --let $disable_query_log = [0|1] # optional, default 0 (1 disables logging of CREATE)
+#
+# Usage examples:
+#
+# --source create_table.inc -- creates a default table
+#
+# --let $create_definition = a INT NOT NULL, b CHAR(1) PRIMARY KEY, INDEX(a)
+# --let $table_options = AUTO_INCREMENT = 100
+# --let $partition_options = PARTITION BY HASH(a) PARTITIONS 2
+# --let $as_select = SELECT 1, 'a'
+# --source create_table.inc
+#
+# Additionally, a test can define $extra_tbl_options. The difference with $table_options
+# is that its value is persistent and will be used until it is unset explicitly, or
+# until the test ends. The purpose of it is to allow one test to call another test,
+# when the called test does not know about specific options the calling test might require,
+# and thus cannot set them on per-create basis.
+
+--let $create_statement = CREATE
+
+if ($temporary)
+{
+ --let $create_statement = $create_statement TEMPORARY
+}
+
+--let $create_statement = $create_statement TABLE
+
+if ($if_not_exists)
+{
+ --let $create_statement = $create_statement IF NOT EXISTS
+}
+
+if (!$table_name)
+{
+ --let $table_name = t1
+}
+
+# Child statement is a statement that will create an underlying table.
+# From this point, it will deviate from the main statement, that's why
+# we start creating it here in parallel with the main one.
+# For underlying tables, we will create a table in mrg schema, e.g.
+# for table t1 the underlying table will be mrg.t1, etc.
+# Since we will only create one child here, it should be enough. If we want more,
+# we can always add a suffix, e.g. mrg.t1_child1, mrg.t1_child2, etc.
+
+--let $child_statement = $create_statement mrg.$table_name
+--let $create_statement = $create_statement $table_name
+
+if (!$create_definition)
+{
+ # If $create_definition is not defined, and AS SELECT is requested,
+ # we should not set $create_definition to the default value,
+ # because it might be inconsistent with the SELECT.
+ if (!$as_select)
+ {
+ --let $create_definition = a $int_col, b $char_col
+ }
+}
+
+if ($create_definition)
+{
+ --let $create_statement = $create_statement ($create_definition)
+ # Table definition for the underlying table should be the same
+ # as for the MERGE table
+ --let $child_statement = $child_statement ($create_definition)
+}
+
+# If $default_engine is set, we will rely on the default storage engine
+
+if (!$default_engine)
+{
+ --let $create_statement = $create_statement ENGINE=$storage_engine
+}
+# Engine for an underlying table differs
+--let $child_statement = $child_statement ENGINE=MyISAM
+
+# Save default table options, we will want to restore them later
+--let $default_tbl_opts_saved = $default_tbl_opts
+--let $default_tbl_opts = $default_tbl_opts UNION(mrg.$table_name) INSERT_METHOD=LAST
+
+# Default table options from define_engine.inc
+--let $create_statement = $create_statement $default_tbl_opts
+
+# The calling script could request additional table options
+if ($table_options)
+{
+ --let $create_statement = $create_statement $table_options
+ --let $child_statement = $child_statement $table_options
+}
+
+# The difference between $extra_tbl_opts and $table_options
+# is that its $extra_tbl_opts is persistent -- it will not be unset at the end of this file,
+# and will be used until it is unset explicitly by the calling test,
+# or until the test ends. The purpose of it is to allow one test to call another test,
+# when the called test does not know about specific options the calling test might require,
+# and thus cannot set them on per-create basis.
+
+if ($extra_tbl_opts)
+{
+ --let $create_statement = $create_statement $extra_tbl_opts
+ --let $child_statement = $child_statement $extra_tbl_opts
+}
+
+if ($as_select)
+{
+ --let $create_statement = $create_statement AS $as_select
+ --let $child_statement = $child_statement AS $as_select
+}
+
+if ($partition_options)
+{
+ --let $create_statement = $create_statement $partition_options
+ --let $child_statement = $child_statement $partition_options
+}
+
+# We now have the complete CREATE statement in $create_statement.
+# If your CREATE statement should be composed differently,
+# modify the logic above.
+
+#####################
+# Here you can add logic needed BEFORE the main table creation
+# (e.g. the table needs a base table, a reference table, etc.).
+# Surround it by --disable_query_log/--enable_query_log
+# if you don't want it to appear in the result output.
+#####################
+--disable_warnings
+--disable_query_log
+--disable_result_log
+eval DROP TABLE IF EXISTS mrg.$table_name;
+eval $child_statement;
+--enable_result_log
+--enable_query_log
+--enable_warnings
+
+if ($disable_query_log)
+{
+ --disable_query_log
+}
+
+--source obfuscate.inc
+
+eval $create_statement;
+--source strict_check_errors.inc
+
+# Make sure you don't add any statements between the main CREATE (above)
+# and saving mysql_errno and mysql_errname (below)
+# They are saved in case you want to add more logic after the main CREATE,
+# because we need the result code of the table creation.
+# Also, do not change $create_statement after it is executed!
+
+--let $my_errno = $mysql_errno
+--let $my_errname = $mysql_errname
+
+
+if ($disable_query_log)
+{
+ --enable_query_log
+}
+
+#####################
+# Here you can add logic needed AFTER the main table creation,
+# e.g. triggers creation.
+# Surround it by --disable_query_log/--enable_query_log
+# if you don't want it to appear in the result output.
+#####################
+
+
+# Unset the parameters, we don't want them to be accidentally reused later
+--let $create_definition =
+--let $table_name = t1
+--let $table_options =
+--let $partition_options =
+--let $as_select = 0
+--let $error_codes =
+--let $if_not_exists = 0
+--let $default_engine = 0
+--let $temporary = 0
+--let $disable_query_log = 0
+
+# Restore default table options now
+--let $default_tbl_opts = $default_tbl_opts_saved
+
+
+# Restore the error codes of the main statement
+--let $mysql_errno = $my_errno
+--let $mysql_errname = $my_errname
+# Make sure you don't add any SQL statements after restoring
+# mysql_errno and mysql_errname (above)
+
diff --git a/storage/myisammrg/mysql-test/storage_engine/create_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/create_table.rdiff
new file mode 100644
index 00000000000..5d3578ad3cd
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/create_table.rdiff
@@ -0,0 +1,37 @@
+7c7
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+16c16
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+22c22
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+27,36c27,35
+< SHOW CREATE TABLE t1;
+< Table Create Table
+< t1 CREATE TABLE `t1` (
+< `1` bigint(20) NOT NULL DEFAULT '0'
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+< SELECT * FROM t1;
+< 1
+< 1
+< 2
+< DROP TABLE t1;
+---
+> ERROR HY000: 'test.t1' is not BASE TABLE
+> # ERROR: Statement ended with errno 1347, errname ER_WRONG_OBJECT (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command finished with ER_WRONG_OBJECT.
+> # CREATE TABLE .. AS SELECT or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+43c42
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/define_engine.inc b/storage/myisammrg/mysql-test/storage_engine/define_engine.inc
new file mode 100644
index 00000000000..aabd1747737
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/define_engine.inc
@@ -0,0 +1,49 @@
+###########################################
+#
+# This is a template of the include file define_engine.inc which
+# should be placed in storage/<engine>/mysql-test/storage_engine folder.
+#
+################################
+#
+# The name of the engine under test must be defined in $ENGINE variable.
+# You can set it either here (uncomment and edit) or in your environment.
+#
+let $ENGINE = MRG_MYISAM;
+#
+################################
+#
+# The following three variables define specific options for columns and tables.
+# Normally there should be none needed, but for some engines it can be different.
+# If the engine requires specific column option for all or indexed columns,
+# set them inside the comment, e.g. /*!NOT NULL*/.
+# Do the same for table options if needed, e.g. /*!INSERT_METHOD=LAST*/
+
+let $default_col_opts = /*!*/;
+let $default_col_indexed_opts = /*!*/;
+let $default_tbl_opts = /*!*/;
+
+# INDEX, UNIQUE INDEX, PRIMARY KEY, special index type - choose the fist that the engine allows,
+# or set it to /*!*/ if none is supported
+
+let $default_index = /*!INDEX*/;
+
+# If the engine does not support the following types, replace them with the closest possible
+
+let $default_int_type = INT(11);
+let $default_char_type = CHAR(8);
+
+################################
+
+--disable_query_log
+--disable_result_log
+
+# Here you can place your custom MTR code which needs to be executed before each test,
+# e.g. creation of an additional schema or table, etc.
+# The cleanup part should be defined in cleanup_engine.inc
+--disable_warnings
+DROP DATABASE IF EXISTS mrg;
+--enable_warnings
+CREATE DATABASE mrg;
+
+--enable_query_log
+--enable_result_log
diff --git a/storage/myisammrg/mysql-test/storage_engine/disabled.def b/storage/myisammrg/mysql-test/storage_engine/disabled.def
new file mode 100644
index 00000000000..9f7569a2d24
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/disabled.def
@@ -0,0 +1,2 @@
+alter_table_online : MySQL:57657 (Temporary MERGE table with temporary underlying is broken by ALTER)
+
diff --git a/storage/myisammrg/mysql-test/storage_engine/foreign_keys.rdiff b/storage/myisammrg/mysql-test/storage_engine/foreign_keys.rdiff
new file mode 100644
index 00000000000..7362bd282a5
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/foreign_keys.rdiff
@@ -0,0 +1,138 @@
+15,17c15,16
+< KEY `a` (`a`),
+< CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`)
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> KEY `a` (`a`)
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t2`)
+19c18,25
+< ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+---
+> # ERROR: Statement succeeded (expected results: ER_NO_REFERENCED_ROW_2)
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command succeeded unexpectedly.
+> # Foreign keys or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+23c29,36
+< ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+---
+> # ERROR: Statement succeeded (expected results: ER_NO_REFERENCED_ROW_2)
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command succeeded unexpectedly.
+> # Foreign keys or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+25c38
+< ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+---
+> # ERROR: Statement succeeded (expected results: ER_ROW_IS_REFERENCED_2)
+27c40,47
+< ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+---
+> # ERROR: Statement succeeded (expected results: ER_ROW_IS_REFERENCED_2)
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command succeeded unexpectedly.
+> # Foreign keys or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+32c52
+< 2 d
+---
+> 3 d
+35c55,56
+< 1 a
+---
+> 3 b
+> 3 b
+37c58,65
+< ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+---
+> # ERROR: Statement succeeded (expected results: ER_ROW_IS_REFERENCED)
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command succeeded unexpectedly.
+> # Foreign keys or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+49,51c77,78
+< KEY `a` (`a`),
+< CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`) ON DELETE CASCADE ON UPDATE CASCADE
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> KEY `a` (`a`)
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t2`)
+53c80
+< ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`) ON DELETE CASCADE ON UPDATE CASCADE)
+---
+> # ERROR: Statement succeeded (expected results: ER_NO_REFERENCED_ROW_2)
+54a82
+> ERROR 42S02: Table 'test.t1' doesn't exist
+56a85,92
+> ERROR 42S02: Table 'test.t1' doesn't exist
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command finished with ER_NO_SUCH_TABLE.
+> # UPDATE or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+59,64c95,104
+< 5 a
+< 5 a
+< 5 b
+< 5 c
+< 5 d
+< 5 e
+---
+> 1 a
+> 1 a
+> 2 b
+> 2 b
+> 3 a
+> 3 c
+> 3 c
+> 4 d
+> 4 d
+> 4 e
+65a106,113
+> ERROR 42S02: Table 'test.t1' doesn't exist
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command finished with ER_NO_SUCH_TABLE.
+> # DELETE or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+67a116,125
+> 1 a
+> 1 a
+> 2 b
+> 2 b
+> 3 a
+> 3 c
+> 3 c
+> 4 d
+> 4 d
+> 4 e
+69c127,135
+< ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `test`.`t1` (`a`))
+---
+> ERROR 42S02: Table 'test.t1' doesn't exist
+> # ERROR: Statement ended with errno 1146, errname ER_NO_SUCH_TABLE (expected results: ER_TRUNCATE_ILLEGAL_FK)
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command finished with ER_NO_SUCH_TABLE.
+> # Foreign keys or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+71a138
+> ERROR 42S02: Unknown table 't1'
diff --git a/storage/myisammrg/mysql-test/storage_engine/fulltext_search.rdiff b/storage/myisammrg/mysql-test/storage_engine/fulltext_search.rdiff
new file mode 100644
index 00000000000..262370f01ed
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/fulltext_search.rdiff
@@ -0,0 +1,142 @@
+7,64c7,15
+< SHOW INDEXES IN t1;
+< Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+< t1 1 v1 1 v1 # # NULL NULL YES FULLTEXT
+< INSERT INTO t1 (v0,v1,v2) VALUES ('text1','Here is a list of recommended books on MariaDB and MySQL. We\'ve provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+< If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+< For developers who want to code on MariaDB or MySQL
+< * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+< o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+< o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic.
+< * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+< o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB!
+< For MariaDB / MySQL end users
+< * MariaDB Crash Course by Ben Forta
+< o First MariaDB book!
+< o For people who want to learn SQL and the basics of MariaDB.
+< o Now shipping. Purchase at Amazon.com or your favorite bookseller.
+< * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+< o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+< o Free to read in the Knowledgebase!
+< * MySQL (4th Edition) by Paul DuBois
+< o The \'default\' book to read if you wont to learn to use MySQL / MariaDB.
+< * MySQL Cookbook by Paul DuBois
+< o A lot of examples of how to use MySQL. As with all of Paul\'s books, it\'s worth its weight in gold and even enjoyable reading for such a \'dry\' subject.
+< * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+< o \"High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL\'s full power.\" (From the book description at O\'Reilly)
+<
+< * MySQL Admin Cookbook
+< o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration
+<
+< * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+< o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. ',
+< 'There are several reasons why contributing code is one of the easiest and most rewarding ways to contribute to MariaDB:
+<
+< 1. We are very responsive toward reviews of submitted code and as soon as the review is done, the submitted code is merged into an existing MariaDB tree and made available to everyone, not just select customers.
+< 2. Code reviews are performed by the MariaDB core development team and the quality, detail, and timeliness of our reviews are better than you will find elsewhere.
+< 3. With MariaDB everyone has access to the latest code.
+< 4. If a patch is very safe and/or very useful we are willing to push it into the stable code (as long as it can\'t break any existing applications). We are willing to do this to ensure the freedom to add small, needed fixes on a stable release so users don\'t have to wait a year for something to be added which is critical to their business.
+< 5. If you are an active contributor, you can become a member of maria-captains, even if you aren\'t working for Monty Program Ab. All captains have the same rights as any other captain to accept and reject patches. Our development model is truly open for everyone.
+< The Contributing Code page details many of the actual steps involved in working with the MariaDB source code. It\'s important that you use the same tools and submit patches in the same way as other developers to keep development running smoothly.'
+< ), ('text2','test1','test2');
+< SELECT v0 FROM t1 WHERE MATCH(v1) AGAINST ('contributing' IN NATURAL LANGUAGE MODE);
+< v0
+< INSERT INTO t1 (v0,v1,v2) VALUES ('text3','test','test');
+< SELECT v0, MATCH(v1) AGAINST('contributing' IN NATURAL LANGUAGE MODE) AS rating FROM t1 WHERE MATCH(v1) AGAINST ('contributing' IN NATURAL LANGUAGE MODE);
+< v0 rating
+< INSERT INTO t1 (v0,v1,v2) VALUES ('text4','Contributing more...','...is a good idea'),('text5','test','test');
+< SELECT v0, MATCH(v1) AGAINST('contributing') AS rating FROM t1 WHERE MATCH(v1) AGAINST ('contributing');
+< v0 rating
+< text4 1.3705332279205322
+< SELECT v0 FROM t1 WHERE MATCH(v1,v2) AGAINST ('-test1 +critical +Cook*' IN BOOLEAN MODE);
+< v0
+< text1
+< SELECT v0 FROM t1 WHERE MATCH(v1,v2) AGAINST ('-patch +critical +Cook*' IN BOOLEAN MODE);
+< v0
+< SELECT v0, MATCH(v1) AGAINST('database' WITH QUERY EXPANSION) AS rating FROM t1 WHERE MATCH(v1) AGAINST ('database' WITH QUERY EXPANSION);
+< v0 rating
+< text1 178.11756896972656
+< DROP TABLE t1;
+---
+> ERROR HY000: The used table type doesn't support FULLTEXT indexes
+> # ERROR: Statement ended with errno 1214, errname ER_TABLE_CANT_HANDLE_FT (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command finished with ER_TABLE_CANT_HANDLE_FT.
+> # FULLTEXT indexes or VARCHAR|TEXT data types or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+71,132c22,30
+< SHOW INDEXES IN t1;
+< Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+< t1 1 v1 1 v1 # # NULL NULL YES FULLTEXT
+< t1 1 v1_v2 1 v1 # # NULL NULL YES FULLTEXT
+< t1 1 v1_v2 2 v2 # # NULL NULL YES FULLTEXT
+< INSERT INTO t1 (v0,v1,v2) VALUES ('text1','Here is a list of recommended books on MariaDB and MySQL. We\'ve provided links to Amazon.com here for convenience, but they can be found at many other bookstores, both online and off.
+< If you want to have your favorite MySQL / MariaDB book listed here, please leave a comment.
+< For developers who want to code on MariaDB or MySQL
+< * Understanding MySQL Internals by Sasha Pachev, former MySQL developer at MySQL AB.
+< o This is the only book we know about that describes the internals of MariaDB / MySQL. A must have for anyone who wants to understand and develop on MariaDB!
+< o Not all topics are covered and some parts are slightly outdated, but still the best book on this topic.
+< * MySQL 5.1 Plugin Development by Sergei Golubchik and Andrew Hutchings
+< o A must read for anyone wanting to write a plugin for MariaDB, written by the Sergei who designed the plugin interface for MySQL and MariaDB!
+< For MariaDB / MySQL end users
+< * MariaDB Crash Course by Ben Forta
+< o First MariaDB book!
+< o For people who want to learn SQL and the basics of MariaDB.
+< o Now shipping. Purchase at Amazon.com or your favorite bookseller.
+< * SQL-99 Complete, Really by Peter Gulutzan & Trudy Pelzer.
+< o Everything you wanted to know about the SQL 99 standard. Excellent reference book!
+< o Free to read in the Knowledgebase!
+< * MySQL (4th Edition) by Paul DuBois
+< o The \'default\' book to read if you wont to learn to use MySQL / MariaDB.
+< * MySQL Cookbook by Paul DuBois
+< o A lot of examples of how to use MySQL. As with all of Paul\'s books, it\'s worth its weight in gold and even enjoyable reading for such a \'dry\' subject.
+< * High Performance MySQL, Second Edition, By Baron Schwartz, Peter Zaitsev, Vadim Tkachenko, Jeremy D. Zawodny, Arjen Lentz, Derek J. Balling, et al.
+< o \"High Performance MySQL is the definitive guide to building fast, reliable systems with MySQL. Written by noted experts with years of real-world experience building very large systems, this book covers every aspect of MySQL performance in detail, and focuses on robustness, security, and data integrity. Learn advanced techniques in depth so you can bring out MySQL\'s full power.\" (From the book description at O\'Reilly)
+<
+< * MySQL Admin Cookbook
+< o A quick step-by-step guide for MySQL users and database administrators to tackle real-world challenges with MySQL configuration and administration
+<
+< * MySQL 5.0 Certification Study Guide, By Paul DuBois, Stefan Hinz, Carsten Pedersen
+< o This is the official guide to cover the passing of the two MySQL Certification examinations. It is valid till version 5.0 of the server, so while it misses all the features available in MySQL 5.1 and greater (including MariaDB 5.1 and greater), it provides a good basic understanding of MySQL for the end-user. ',
+< 'There are several reasons why contributing code is one of the easiest and most rewarding ways to contribute to MariaDB:
+<
+< 1. We are very responsive toward reviews of submitted code and as soon as the review is done, the submitted code is merged into an existing MariaDB tree and made available to everyone, not just select customers.
+< 2. Code reviews are performed by the MariaDB core development team and the quality, detail, and timeliness of our reviews are better than you will find elsewhere.
+< 3. With MariaDB everyone has access to the latest code.
+< 4. If a patch is very safe and/or very useful we are willing to push it into the stable code (as long as it can\'t break any existing applications). We are willing to do this to ensure the freedom to add small, needed fixes on a stable release so users don\'t have to wait a year for something to be added which is critical to their business.
+< 5. If you are an active contributor, you can become a member of maria-captains, even if you aren\'t working for Monty Program Ab. All captains have the same rights as any other captain to accept and reject patches. Our development model is truly open for everyone.
+< The Contributing Code page details many of the actual steps involved in working with the MariaDB source code. It\'s important that you use the same tools and submit patches in the same way as other developers to keep development running smoothly.'
+< ), ('text2','test1','test2');
+< SELECT v0 FROM t1 WHERE MATCH(v1,v2) AGAINST ('contributing' IN NATURAL LANGUAGE MODE);
+< v0
+< INSERT INTO t1 (v0,v1,v2) VALUES ('text3','test','test');
+< SELECT v0, MATCH(v1,v2) AGAINST('contributing' IN NATURAL LANGUAGE MODE) AS rating FROM t1 WHERE MATCH(v1,v2) AGAINST ('contributing' IN NATURAL LANGUAGE MODE);
+< v0 rating
+< text1 0.2809644043445587
+< INSERT INTO t1 (v0,v1,v2) VALUES ('text4','Contributing more...','...is a good idea'),('text5','test','test');
+< SELECT v0, MATCH(v1) AGAINST('contributing') AS rating FROM t1 WHERE MATCH(v1) AGAINST ('contributing');
+< v0 rating
+< text4 1.3705332279205322
+< SELECT v0 FROM t1 WHERE MATCH(v1,v2) AGAINST ('-test1 +critical +Cook*' IN BOOLEAN MODE);
+< v0
+< text1
+< SELECT v0 FROM t1 WHERE MATCH(v1,v2) AGAINST ('-patch +critical +Cook*' IN BOOLEAN MODE);
+< v0
+< SELECT v0, MATCH(v1,v2) AGAINST('database' WITH QUERY EXPANSION) AS rating FROM t1 WHERE MATCH(v1,v2) AGAINST ('database' WITH QUERY EXPANSION);
+< v0 rating
+< text1 190.56150817871094
+< text4 1.1758291721343994
+< DROP TABLE t1;
+---
+> ERROR HY000: The used table type doesn't support FULLTEXT indexes
+> # ERROR: Statement ended with errno 1214, errname ER_TABLE_CANT_HANDLE_FT (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command finished with ER_TABLE_CANT_HANDLE_FT.
+> # FULLTEXT indexes or multiple keys or VARCHAR|TEXT data types or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
diff --git a/storage/myisammrg/mysql-test/storage_engine/handler.rdiff b/storage/myisammrg/mysql-test/storage_engine/handler.rdiff
new file mode 100644
index 00000000000..f0c01085ad9
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/handler.rdiff
@@ -0,0 +1,79 @@
+5,47c5,12
+< HANDLER t1 READ FIRST;
+< ERROR 42S02: Unknown table 't1' in HANDLER
+< HANDLER h1 READ FIRST;
+< a b
+< foobar 1000
+< HANDLER h1 READ NEXT;
+< a b
+< a 1
+< HANDLER h1 READ FIRST WHERE a < 'foo';
+< a b
+< a 1
+< HANDLER h1 READ NEXT;
+< a b
+< bar 200
+< HANDLER h1 READ NEXT;
+< a b
+< foo 100
+< HANDLER h1 READ NEXT;
+< a b
+< HANDLER h1 READ FIRST LIMIT 2;
+< a b
+< foobar 1000
+< a 1
+< HANDLER h1 READ NEXT;
+< a b
+< bar 200
+< HANDLER h1 READ NEXT WHERE b>500 LIMIT 2;
+< a b
+< HANDLER t1 OPEN;
+< HANDLER h1 READ FIRST WHERE b>500 LIMIT 5;
+< a b
+< foobar 1000
+< HANDLER t1 READ NEXT;
+< a b
+< foobar 1000
+< HANDLER h1 READ NEXT WHERE b<100;
+< a b
+< HANDLER t1 CLOSE;
+< HANDLER h1 READ FIRST;
+< a b
+< foobar 1000
+< HANDLER t1 CLOSE;
+< ERROR 42S02: Unknown table 't1' in HANDLER
+---
+> ERROR HY000: Table storage engine for 'h1' doesn't have this option
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command finished with ER_ILLEGAL_HA.
+> # Functionality or the syntax or the mix could be unsupported.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+54,76c19
+< HANDLER h1 READ a = (100);
+< a b
+< 100 f
+< HANDLER h1 READ a <= (100) WHERE b < 'f';
+< a b
+< 2 c
+< HANDLER h1 READ a > (2) WHERE b IS NOT NULL LIMIT 2;
+< a b
+< 100 f
+< 101 b
+< HANDLER h1 READ a FIRST;
+< a b
+< 1 a
+< HANDLER h1 READ a LAST;
+< a b
+< 200 b
+< HANDLER h1 READ a PREV;
+< a b
+< 101 b
+< HANDLER h1 READ a NEXT;
+< a b
+< 200 b
+< HANDLER h1 CLOSE;
+---
+> ERROR HY000: Table storage engine for 'h1' doesn't have this option
diff --git a/storage/myisammrg/mysql-test/storage_engine/index.rdiff b/storage/myisammrg/mysql-test/storage_engine/index.rdiff
new file mode 100644
index 00000000000..6e6f18e39bc
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/index.rdiff
@@ -0,0 +1,6 @@
+64,66c64
+< ERROR 23000: Duplicate entry '1' for key 'a'
+< # Statement ended with one of expected results (ER_DUP_ENTRY,ER_DUP_KEY).
+< # If you got a difference in error message, just add it to rdiff file
+---
+> # ERROR: Statement succeeded (expected results: ER_DUP_ENTRY,ER_DUP_KEY)
diff --git a/storage/myisammrg/mysql-test/storage_engine/index_enable_disable.rdiff b/storage/myisammrg/mysql-test/storage_engine/index_enable_disable.rdiff
new file mode 100644
index 00000000000..8913f17a2a6
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/index_enable_disable.rdiff
@@ -0,0 +1,17 @@
+13a14,15
+> Warnings:
+> Note 1031 Table storage engine for 't1' doesn't have this option
+16c18
+< t1 1 a 1 a # # NULL NULL YES BTREE disabled
+---
+> t1 1 a 1 a # # NULL NULL YES BTREE
+19c21
+< 1 SIMPLE t1 ALL NULL NULL NULL NULL 19 Using filesort
+---
+> 1 SIMPLE t1 index NULL a 5 NULL 19 Using index
+22a25,26
+> Warnings:
+> Note 1031 Table storage engine for 't1' doesn't have this option
+34a39,40
+> Warnings:
+> Note 1031 Table storage engine for 't1' doesn't have this option
diff --git a/storage/myisammrg/mysql-test/storage_engine/index_type_btree.rdiff b/storage/myisammrg/mysql-test/storage_engine/index_type_btree.rdiff
new file mode 100644
index 00000000000..6e6f18e39bc
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/index_type_btree.rdiff
@@ -0,0 +1,6 @@
+64,66c64
+< ERROR 23000: Duplicate entry '1' for key 'a'
+< # Statement ended with one of expected results (ER_DUP_ENTRY,ER_DUP_KEY).
+< # If you got a difference in error message, just add it to rdiff file
+---
+> # ERROR: Statement succeeded (expected results: ER_DUP_ENTRY,ER_DUP_KEY)
diff --git a/storage/myisammrg/mysql-test/storage_engine/index_type_hash.rdiff b/storage/myisammrg/mysql-test/storage_engine/index_type_hash.rdiff
new file mode 100644
index 00000000000..1b57afe5b64
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/index_type_hash.rdiff
@@ -0,0 +1,34 @@
+7c7
+< t1 1 a 1 a # # NULL NULL # HASH
+---
+> t1 1 a 1 a # # NULL NULL # BTREE
+15,16c15,16
+< t1 1 a_b 1 a # # NULL NULL # HASH a_b index
+< t1 1 a_b 2 b # # NULL NULL # HASH a_b index
+---
+> t1 1 a_b 1 a # # NULL NULL # BTREE a_b index
+> t1 1 a_b 2 b # # NULL NULL # BTREE a_b index
+25,26c25,26
+< t1 1 a 1 a # # NULL NULL # HASH
+< t1 1 b 1 b # # NULL NULL # HASH
+---
+> t1 1 a 1 a # # NULL NULL # BTREE
+> t1 1 b 1 b # # NULL NULL # BTREE
+34c34
+< t1 0 a 1 a # # NULL NULL # HASH
+---
+> t1 0 a 1 a # # NULL NULL # BTREE
+46c46
+< t1 1 a 1 a # # NULL NULL # HASH simple index on a
+---
+> t1 1 a 1 a # # NULL NULL # BTREE simple index on a
+55c55
+< t1 0 a 1 a # # NULL NULL # HASH
+---
+> t1 0 a 1 a # # NULL NULL # BTREE
+64,66c64
+< ERROR 23000: Duplicate entry '1' for key 'a'
+< # Statement ended with one of expected results (ER_DUP_ENTRY,ER_DUP_KEY).
+< # If you got a difference in error message, just add it to rdiff file
+---
+> # ERROR: Statement succeeded (expected results: ER_DUP_ENTRY,ER_DUP_KEY)
diff --git a/storage/myisammrg/mysql-test/storage_engine/insert_delayed.rdiff b/storage/myisammrg/mysql-test/storage_engine/insert_delayed.rdiff
new file mode 100644
index 00000000000..e0d0eefabe4
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/insert_delayed.rdiff
@@ -0,0 +1,14 @@
+7a8,15
+> ERROR HY000: DELAYED option not supported for table 't1'
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command finished with ER_DELAYED_NOT_SUPPORTED.
+> # INSERT DELAYED or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+8a17
+> ERROR HY000: DELAYED option not supported for table 't1'
+23,24d31
+< 3 c
+< 4 d
diff --git a/storage/myisammrg/mysql-test/storage_engine/lock.rdiff b/storage/myisammrg/mysql-test/storage_engine/lock.rdiff
new file mode 100644
index 00000000000..d035648551a
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/lock.rdiff
@@ -0,0 +1,62 @@
+44a45,46
+> ERROR HY000: Table 't1' was not locked with LOCK TABLES
+> # ERROR: Statement ended with errno 1100, errname ER_TABLE_NOT_LOCKED (expected to succeed)
+45a48,49
+> ERROR HY000: Table 't2' was not locked with LOCK TABLES
+> # ERROR: Statement ended with errno 1100, errname ER_TABLE_NOT_LOCKED (expected to succeed)
+46a51
+> ERROR HY000: Table 't2' was not locked with LOCK TABLES
+47a53
+> ERROR HY000: Table 't2' was not locked with LOCK TABLES
+48a55
+> ERROR 42S02: Table 'test.t1' doesn't exist
+49a57
+> ERROR 42S02: Table 'test.t1' doesn't exist
+50a59
+> ERROR 42S02: Table 'test.t1' doesn't exist
+52a62
+> ERROR 42S02: Table 'test.t1' doesn't exist
+54c64,65
+< ERROR HY000: Table 't1' was not locked with LOCK TABLES
+---
+> ERROR 42S02: Table 'test.t1' doesn't exist
+> # ERROR: Statement ended with errno 1146, errname ER_NO_SUCH_TABLE (expected results: ER_TABLE_NOT_LOCKED)
+56a68
+> ERROR 42S02: Table 'test.t1' doesn't exist
+57a70
+> ERROR 42S02: Table 'test.t1' doesn't exist
+59c72,73
+< ERROR HY000: Table 't2' was not locked with LOCK TABLES
+---
+> ERROR 42S02: Unknown table 't1,t2'
+> # ERROR: Statement ended with errno 1051, errname ER_BAD_TABLE_ERROR (expected results: ER_TABLE_NOT_LOCKED)
+61a76
+> ERROR 42S02: Unknown table 't1,t2'
+67a83,84
+> ERROR HY000: Table 't1' was not locked with LOCK TABLES
+> # ERROR: Statement ended with errno 1100, errname ER_TABLE_NOT_LOCKED (expected to succeed)
+68a86,87
+> ERROR HY000: Table 't2' was not locked with LOCK TABLES
+> # ERROR: Statement ended with errno 1100, errname ER_TABLE_NOT_LOCKED (expected to succeed)
+69a89,90
+> ERROR HY000: Table 't3' was not locked with LOCK TABLES
+> # ERROR: Statement ended with errno 1100, errname ER_TABLE_NOT_LOCKED (expected to succeed)
+70a92
+> ERROR 42S02: Table 'test.t1' doesn't exist
+71a94,103
+> ERROR 42S02: Table 'test.t2' doesn't exist
+> # ERROR: Statement ended with errno 1146, errname ER_NO_SUCH_TABLE (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ ALTER TABLE t2 ADD COLUMN c2 INT(11) /*!*/ /*Custom column options*/ ]
+> # The statement|command finished with ER_NO_SUCH_TABLE.
+> # ALTER TABLE or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+72a105
+> ERROR 42S02: Unknown table 't1,t2,t3'
+109c142
+< a b
+---
+> ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
diff --git a/storage/myisammrg/mysql-test/storage_engine/optimize_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/optimize_table.rdiff
new file mode 100644
index 00000000000..f74c49cedea
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/optimize_table.rdiff
@@ -0,0 +1,24 @@
+8c8
+< test.t1 optimize status OK
+---
+> test.t1 optimize note The storage engine for the table doesn't support optimize
+12c12
+< test.t2 optimize status OK
+---
+> test.t2 optimize note The storage engine for the table doesn't support optimize
+17,18c17,18
+< test.t1 optimize status OK
+< test.t2 optimize status OK
+---
+> test.t1 optimize note The storage engine for the table doesn't support optimize
+> test.t2 optimize note The storage engine for the table doesn't support optimize
+21,22c21,22
+< test.t1 optimize status Table is already up to date
+< test.t2 optimize status Table is already up to date
+---
+> test.t1 optimize note The storage engine for the table doesn't support optimize
+> test.t2 optimize note The storage engine for the table doesn't support optimize
+28c28
+< test.t1 optimize status OK
+---
+> test.t1 optimize note The storage engine for the table doesn't support optimize
diff --git a/storage/myisammrg/mysql-test/storage_engine/parts/alter_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/parts/alter_table.rdiff
new file mode 100644
index 00000000000..a2cb0c1dcb1
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/parts/alter_table.rdiff
@@ -0,0 +1,63 @@
+3,36c3,12
+< INSERT INTO t1 (a) VALUES (1),(2),(2),(3),(4);
+< ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
+< EXPLAIN PARTiTIONS SELECT a FROM t1 WHERE a = 3;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p3 # # # # # # #
+< ALTER TABLE t1 COALESCE PARTITION 1;
+< EXPLAIN PARTiTIONS SELECT a FROM t1 WHERE a = 3;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0 # # # # # # #
+< ALTER TABLE t1 REORGANIZE PARTITION;
+< EXPLAIN PARTiTIONS SELECT a FROM t1 WHERE a = 2;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0 # # # # # # #
+< ALTER TABLE t1 REBUILD PARTITION p0;
+< EXPLAIN PARTiTIONS SELECT a FROM t1;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0 # # # # # # #
+< ALTER TABLE t1 REMOVE PARTITIONING;
+< EXPLAIN PARTiTIONS SELECT a FROM t1;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 NULL # # # # # # #
+< ALTER TABLE t1 PARTITION BY LIST(a) (PARTITION p0 VALUES IN (1,2,3), PARTITION p1 VALUES IN (101,102));
+< ERROR HY000: Table has no partition for value 4
+< ALTER TABLE t1 PARTITION BY LIST(a) (PARTITION p0 VALUES IN (1,2,3,4), PARTITION p1 VALUES IN (101,102));
+< INSERT INTO t1 (a) VALUES (50);
+< ERROR HY000: Table has no partition for value 50
+< ALTER TABLE t1 ADD PARTITION (PARTITION p2 VALUES IN (50,51));
+< INSERT INTO t1 (a) VALUES (50);
+< ALTER TABLE t1 DROP PARTITION p1;
+< ALTER TABLE t1 REORGANIZE PARTITION p0, p2 INTO (PARTITION p0 VALUES IN (1,2,3), PARTITION p1 VALUES IN (4), PARTITION p2 VALUES IN (50,51), PARTITION p3 VALUES IN (101,102));
+< EXPLAIN PARTiTIONS SELECT a FROM t1 WHERE a = 2;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0 # # # # # # #
+< DROP TABLE t1;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY HASH(a) PARTITIONS 2 ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+41,42c17,29
+< ALTER TABLE t1 DROP PARTITION abc;
+< DROP TABLE t1;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/, b INT(11) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY LIST(a) SUBPARTITION by HASH(b) (
+> PARTITION abc VALUES IN (1,2,3),
+> PARTITION def VALUES IN (100,101,102)
+> ) ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or subpartitions or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
diff --git a/storage/myisammrg/mysql-test/storage_engine/parts/analyze_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/parts/analyze_table.rdiff
new file mode 100644
index 00000000000..ce29f3dcf52
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/parts/analyze_table.rdiff
@@ -0,0 +1,83 @@
+3,18c3,12
+< INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(2,'d'),(4,'e'),(100,'f'),(101,'g');
+< CREATE TABLE t2 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< INSERT INTO t2 (a,b) SELECT a,b FROM t1;
+< INSERT INTO t1 (a,b) VALUES (3,'c');
+< ALTER TABLE t1 ANALYZE PARTITION p0;
+< Table Op Msg_type Msg_text
+< test.t1 analyze status OK
+< INSERT INTO t2 (a,b) VALUES (4,'d'), (1000,'e');
+< ALTER TABLE t1 ANALYZE PARTITION LOCAL ALL;
+< Table Op Msg_type Msg_text
+< test.t1 analyze status OK
+< INSERT INTO t1 (a,b) VALUES (5,'f'),(50,'g');
+< ALTER TABLE t1 ANALYZE PARTITION NO_WRITE_TO_BINLOG p1,p0;
+< Table Op Msg_type Msg_text
+< test.t1 analyze status OK
+< DROP TABLE t1, t2;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/, b CHAR(8) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY HASH(a) PARTITIONS 2 ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+20a15,16
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+21a18
+> ERROR 42S02: Table 'test.t1' doesn't exist
+22a20,21
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+23a23
+> ERROR 42S02: Table 'test.t1' doesn't exist
+26c26,27
+< test.t1 analyze status OK
+---
+> test.t1 analyze Error Table 'test.t1' doesn't exist
+> test.t1 analyze status Operation failed
+27a29
+> ERROR 42S02: Table 'test.t2' doesn't exist
+30c32,33
+< test.t2 analyze status OK
+---
+> test.t2 analyze Error Table 'test.t2' doesn't exist
+> test.t2 analyze status Operation failed
+31a35
+> ERROR 42S02: Table 'test.t1' doesn't exist
+32a37
+> ERROR 42S02: Table 'test.t2' doesn't exist
+35,36c40,43
+< test.t1 analyze status OK
+< test.t2 analyze status OK
+---
+> test.t1 analyze Error Table 'test.t1' doesn't exist
+> test.t1 analyze status Operation failed
+> test.t2 analyze Error Table 'test.t2' doesn't exist
+> test.t2 analyze status Operation failed
+37a45
+> ERROR 42S02: Unknown table 't1,t2'
+38a47,48
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+39a50
+> ERROR 42S02: Table 'test.t1' doesn't exist
+42c53,54
+< test.t1 analyze status OK
+---
+> test.t1 analyze Error Table 'test.t1' doesn't exist
+> test.t1 analyze status Operation failed
+43a56
+> ERROR 42S02: Table 'test.t1' doesn't exist
+46c59,60
+< test.t1 analyze status OK
+---
+> test.t1 analyze Error Table 'test.t1' doesn't exist
+> test.t1 analyze status Operation failed
+47a62
+> ERROR 42S02: Unknown table 't1'
diff --git a/storage/myisammrg/mysql-test/storage_engine/parts/check_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/parts/check_table.rdiff
new file mode 100644
index 00000000000..3f3db85a23e
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/parts/check_table.rdiff
@@ -0,0 +1,172 @@
+3,36c3,12
+< INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(2,'d'),(4,'e'),(100,'f'),(101,'g');
+< CREATE TABLE t2 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS> PARTITION BY RANGE(a) (
+< PARTITION p0 VALUES LESS THAN (100),
+< PARTITION p1 VALUES LESS THAN MAXVALUE
+< );
+< INSERT INTO t2 (a,b) SELECT a, b FROM t1;
+< ALTER TABLE t1 CHECK PARTITION p0;
+< Table Op Msg_type Msg_text
+< test.t1 check status OK
+< INSERT INTO t1 (a,b) VALUES (3,'c');
+< ALTER TABLE t1 CHECK PARTITION p0, p1 FOR UPGRADE;
+< Table Op Msg_type Msg_text
+< test.t1 check status OK
+< INSERT INTO t2 (a,b) VALUES (10000,'e');
+< ALTER TABLE t2 CHECK PARTITION p0 QUICK;
+< Table Op Msg_type Msg_text
+< test.t2 check status OK
+< INSERT INTO t1 (a,b) VALUES (6,'f');
+< ALTER TABLE t1 CHECK PARTITION p1 FAST;
+< Table Op Msg_type Msg_text
+< test.t1 check status OK
+< INSERT INTO t2 (a,b) VALUES (8,'h');
+< ALTER TABLE t2 CHECK PARTITION p1 MEDIUM;
+< Table Op Msg_type Msg_text
+< test.t2 check status OK
+< INSERT INTO t1 (a,b) VALUES (9,'i');
+< ALTER TABLE t1 CHECK PARTITION ALL EXTENDED;
+< Table Op Msg_type Msg_text
+< test.t1 check status OK
+< INSERT INTO t1 (a,b) VALUES (11,'k');
+< ALTER TABLE t1 CHECK PARTITION p0 CHANGED;
+< Table Op Msg_type Msg_text
+< test.t1 check status OK
+< DROP TABLE t1, t2;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/, b CHAR(8) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY HASH(a) PARTITIONS 2 ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+38a15,16
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+39a18
+> ERROR 42S02: Table 'test.t1' doesn't exist
+40a20,21
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+43c24,25
+< test.t1 check status OK
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+44a27
+> ERROR 42S02: Table 'test.t1' doesn't exist
+45a29
+> ERROR 42S02: Table 'test.t2' doesn't exist
+48,49c32,35
+< test.t1 check status OK
+< test.t2 check status OK
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+> test.t2 check Error Table 'test.t2' doesn't exist
+> test.t2 check status Operation failed
+50a37
+> ERROR 42S02: Table 'test.t2' doesn't exist
+53c40,41
+< test.t2 check status OK
+---
+> test.t2 check Error Table 'test.t2' doesn't exist
+> test.t2 check status Operation failed
+54a43
+> ERROR 42S02: Table 'test.t1' doesn't exist
+57c46,47
+< test.t1 check status OK
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+58a49
+> ERROR 42S02: Table 'test.t1' doesn't exist
+59a51
+> ERROR 42S02: Table 'test.t2' doesn't exist
+62,63c54,57
+< test.t2 check status OK
+< test.t1 check status OK
+---
+> test.t2 check Error Table 'test.t2' doesn't exist
+> test.t2 check status Operation failed
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+64a59
+> ERROR 42S02: Table 'test.t1' doesn't exist
+65a61
+> ERROR 42S02: Table 'test.t2' doesn't exist
+68,69c64,67
+< test.t1 check status OK
+< test.t2 check status OK
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+> test.t2 check Error Table 'test.t2' doesn't exist
+> test.t2 check status Operation failed
+70a69
+> ERROR 42S02: Table 'test.t1' doesn't exist
+73c72,73
+< test.t1 check status OK
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+74a75
+> ERROR 42S02: Unknown table 't1,t2'
+75a77,78
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+76a80
+> ERROR 42S02: Table 'test.t1' doesn't exist
+79c83,84
+< test.t1 check status OK
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+80a86
+> ERROR 42S02: Table 'test.t1' doesn't exist
+83c89,90
+< test.t1 check status OK
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+84a92
+> ERROR 42S02: Table 'test.t1' doesn't exist
+87c95,96
+< test.t1 check status OK
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+88a98
+> ERROR 42S02: Table 'test.t1' doesn't exist
+91c101,102
+< test.t1 check status OK
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+92a104
+> ERROR 42S02: Table 'test.t1' doesn't exist
+95c107,108
+< test.t1 check status OK
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+96a110
+> ERROR 42S02: Table 'test.t1' doesn't exist
+99c113,114
+< test.t1 check status OK
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+100a116
+> ERROR 42S02: Table 'test.t1' doesn't exist
+103c119,120
+< test.t1 check status OK
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+104a122
+> ERROR 42S02: Unknown table 't1'
diff --git a/storage/myisammrg/mysql-test/storage_engine/parts/checksum_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/parts/checksum_table.rdiff
new file mode 100644
index 00000000000..bc5b07686bf
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/parts/checksum_table.rdiff
@@ -0,0 +1,81 @@
+2a3,4
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+3a6
+> ERROR 42S02: Table 'test.t1' doesn't exist
+4a8,9
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+7c12,14
+< test.t1 4272806499
+---
+> test.t1 NULL
+> Warnings:
+> Error 1146 Table 'test.t1' doesn't exist
+10,11c17,21
+< test.t2 0
+< test.t1 4272806499
+---
+> test.t2 NULL
+> test.t1 NULL
+> Warnings:
+> Error 1146 Table 'test.t2' doesn't exist
+> Error 1146 Table 'test.t1' doesn't exist
+15a26,28
+> Warnings:
+> Error 1146 Table 'test.t1' doesn't exist
+> Error 1146 Table 'test.t2' doesn't exist
+18,19c31,35
+< test.t1 4272806499
+< test.t2 0
+---
+> test.t1 NULL
+> test.t2 NULL
+> Warnings:
+> Error 1146 Table 'test.t1' doesn't exist
+> Error 1146 Table 'test.t2' doesn't exist
+20a37
+> ERROR 42S02: Unknown table 't1,t2'
+22a40,41
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+23a43
+> ERROR 42S02: Table 'test.t1' doesn't exist
+24a45,46
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+27c49,51
+< test.t1 0
+---
+> test.t1 NULL
+> Warnings:
+> Error 1146 Table 'test.t1' doesn't exist
+30,31c54,58
+< test.t2 0
+< test.t1 0
+---
+> test.t2 NULL
+> test.t1 NULL
+> Warnings:
+> Error 1146 Table 'test.t2' doesn't exist
+> Error 1146 Table 'test.t1' doesn't exist
+34,35c61,65
+< test.t1 0
+< test.t2 0
+---
+> test.t1 NULL
+> test.t2 NULL
+> Warnings:
+> Error 1146 Table 'test.t1' doesn't exist
+> Error 1146 Table 'test.t2' doesn't exist
+38,39c68,72
+< test.t1 4272806499
+< test.t2 0
+---
+> test.t1 NULL
+> test.t2 NULL
+> Warnings:
+> Error 1146 Table 'test.t1' doesn't exist
+> Error 1146 Table 'test.t2' doesn't exist
+40a74
+> ERROR 42S02: Unknown table 't1,t2'
diff --git a/storage/myisammrg/mysql-test/storage_engine/parts/create_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/parts/create_table.rdiff
new file mode 100644
index 00000000000..11fbc4812dc
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/parts/create_table.rdiff
@@ -0,0 +1,156 @@
+3,10c3,12
+< INSERT INTO t1 (a) VALUES (1),(2),(3),(2);
+< EXPLAIN PARTITIONS SELECT a FROM t1;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0,p1 # # # # # # #
+< EXPLAIN PARTITIONS SELECT a FROM t1 WHERE a=2;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0 # # # # # # #
+< DROP TABLE t1;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY HASH(a) PARTITIONS 2 ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+12,19c14,23
+< INSERT INTO t1 (a) VALUES ('a'),('b'),('c');
+< EXPLAIN PARTITIONS SELECT a FROM t1;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0,p1 # # # # # # #
+< EXPLAIN PARTITIONS SELECT a FROM t1 WHERE a = 'b';
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p1 # # # # # # #
+< DROP TABLE t1;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a CHAR(8) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY KEY(a) PARTITIONS 2 ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or CHAR types or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+21,31c25,34
+< SHOW INDEX IN t1;
+< Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+< t1 1 a 1 a # # NULL NULL # #
+< INSERT INTO t1 (a) VALUES (1),(2),(3),(5);
+< EXPLAIN PARTITIONS SELECT a FROM t1;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0,p1 # # # # # # #
+< EXPLAIN PARTITIONS SELECT a FROM t1 WHERE a IN (1,3);
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0 # # # # # # #
+< DROP TABLE t1;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom indexed column options*/, /*!INDEX*/ /*Custom index*/ (a)) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY KEY(a) PARTITIONS 2 ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or indexes or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+33,43c36,45
+< SHOW INDEX IN t1;
+< Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+< t1 0 PRIMARY 1 a # # NULL NULL # #
+< INSERT INTO t1 (a) VALUES (1),(200),(3),(2);
+< EXPLAIN PARTITIONS SELECT a FROM t1;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0,p1 # # # # # # #
+< EXPLAIN PARTITIONS SELECT a FROM t1 WHERE a=2;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p1 # # # # # # #
+< DROP TABLE t1;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom indexed column options*/ PRIMARY KEY) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY KEY() PARTITIONS 2 ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # PK or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+48,58c50,63
+< INSERT INTO t1 (a) VALUES (1),(2),(400);
+< EXPLAIN PARTITIONS SELECT a FROM t1;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0,p1 # # # # # # #
+< EXPLAIN PARTITIONS SELECT a FROM t1 WHERE a = 2;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0 # # # # # # #
+< INSERT INTO t1 (a) VALUES (10000);
+< ERROR HY000: Table has no partition for value 10000
+< DROP TABLE t1;
+< CREATE TABLE t1 (a <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS> PARTITION BY LIST(a) (
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY RANGE(a) (
+> PARTITION p0 VALUES LESS THAN (10),
+> PARTITION p1 VALUES LESS THAN (1000)
+> ) ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+> CREATE TABLE t1 (a <INT_COLUMN>, b <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS> PARTITION BY LIST(a) SUBPARTITION by HASH(b) (
+62,72c67,70
+< INSERT INTO t1 (a) VALUES (1),(101),(1);
+< EXPLAIN PARTITIONS SELECT a FROM t1;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 abc,def # # # # # # #
+< EXPLAIN PARTITIONS SELECT a FROM t1 WHERE a = 100;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE NULL NULL # # # # # # #
+< INSERT INTO t1 (a) VALUES (50);
+< ERROR HY000: Table has no partition for value 50
+< DROP TABLE t1;
+< CREATE TABLE t1 (a <INT_COLUMN>, b <INT_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS> PARTITION BY LIST(a) SUBPARTITION by HASH(b) (
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/, b INT(11) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY LIST(a) SUBPARTITION by HASH(b) (
+75,91c73,79
+< );
+< SHOW INDEX IN t1;
+< Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment
+< INSERT INTO t1 (a,b) VALUES (1,1),(101,2),(1,3);
+< EXPLAIN PARTITIONS SELECT a FROM t1;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 abc_abcsp0,def_defsp0 # # # # # # #
+< EXPLAIN PARTITIONS SELECT a FROM t1 WHERE a = 100;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE NULL NULL # # # # # # #
+< SELECT TABLE_SCHEMA, TABLE_NAME, PARTITION_NAME, SUBPARTITION_NAME, PARTITION_METHOD, SUBPARTITION_METHOD
+< FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't1';
+< TABLE_SCHEMA TABLE_NAME PARTITION_NAME SUBPARTITION_NAME PARTITION_METHOD SUBPARTITION_METHOD
+< test t1 abc abcsp0 LIST HASH
+< test t1 def defsp0 LIST HASH
+< SELECT * FROM INFORMATION_SCHEMA.PARTITIONS;
+< DROP TABLE t1;
+---
+> ) ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or subpartitions or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
diff --git a/storage/myisammrg/mysql-test/storage_engine/parts/optimize_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/parts/optimize_table.rdiff
new file mode 100644
index 00000000000..350d93fe91f
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/parts/optimize_table.rdiff
@@ -0,0 +1,91 @@
+3,25c3,12
+< INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(2,'d'),(4,'e'),(100,'f'),(101,'g');
+< CREATE TABLE t2 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS> PARTITION BY RANGE(a) (
+< PARTITION p0 VALUES LESS THAN (100),
+< PARTITION p1 VALUES LESS THAN MAXVALUE
+< );
+< INSERT INTO t2 (a,b) SELECT a, b FROM t1;
+< INSERT INTO t1 (a,b) VALUES (3,'c'),(4,'d');
+< ALTER TABLE t1 OPTIMIZE PARTITION p1;
+< Table Op Msg_type Msg_text
+< test.t1 optimize status OK
+< INSERT INTO t2 (a,b) VALUES (4,'d');
+< ALTER TABLE t2 OPTIMIZE PARTITION p0 NO_WRITE_TO_BINLOG;
+< Table Op Msg_type Msg_text
+< test.t2 optimize status OK
+< INSERT INTO t1 (a,b) VALUES (6,'f');
+< ALTER TABLE t1 OPTIMIZE PARTITION ALL LOCAL;
+< Table Op Msg_type Msg_text
+< test.t1 optimize status OK
+< INSERT INTO t2 (a,b) VALUES (5,'e');
+< ALTER TABLE t2 OPTIMIZE PARTITION p1,p0;
+< Table Op Msg_type Msg_text
+< test.t2 optimize status OK
+< DROP TABLE t1, t2;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/, b CHAR(8) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY HASH(a) PARTITIONS 2 ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+27a15,16
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+28a18
+> ERROR 42S02: Table 'test.t1' doesn't exist
+29a20,21
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+30a23
+> ERROR 42S02: Table 'test.t1' doesn't exist
+33c26,27
+< test.t1 optimize status OK
+---
+> test.t1 optimize Error Table 'test.t1' doesn't exist
+> test.t1 optimize status Operation failed
+34a29
+> ERROR 42S02: Table 'test.t2' doesn't exist
+37c32,33
+< test.t2 optimize status OK
+---
+> test.t2 optimize Error Table 'test.t2' doesn't exist
+> test.t2 optimize status Operation failed
+38a35
+> ERROR 42S02: Table 'test.t2' doesn't exist
+39a37
+> ERROR 42S02: Table 'test.t1' doesn't exist
+42,43c40,43
+< test.t1 optimize status OK
+< test.t2 optimize status OK
+---
+> test.t1 optimize Error Table 'test.t1' doesn't exist
+> test.t1 optimize status Operation failed
+> test.t2 optimize Error Table 'test.t2' doesn't exist
+> test.t2 optimize status Operation failed
+46,47c46,49
+< test.t1 optimize status OK
+< test.t2 optimize status OK
+---
+> test.t1 optimize Error Table 'test.t1' doesn't exist
+> test.t1 optimize status Operation failed
+> test.t2 optimize Error Table 'test.t2' doesn't exist
+> test.t2 optimize status Operation failed
+48a51
+> ERROR 42S02: Unknown table 't1,t2'
+49a53,54
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+50a56
+> ERROR 42S02: Table 'test.t1' doesn't exist
+53c59,60
+< test.t1 optimize status OK
+---
+> test.t1 optimize Error Table 'test.t1' doesn't exist
+> test.t1 optimize status Operation failed
+54a62
+> ERROR 42S02: Unknown table 't1'
diff --git a/storage/myisammrg/mysql-test/storage_engine/parts/repair_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/parts/repair_table.rdiff
new file mode 100644
index 00000000000..4c39421261c
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/parts/repair_table.rdiff
@@ -0,0 +1,295 @@
+4,33c4,13
+< INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(2,'d'),(4,'e'),(100,'f'),(101,'g');
+< CREATE TABLE t2 (a <INT_COLUMN>, b <CHAR_COLUMN>) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS> PARTITION BY RANGE(a) (
+< PARTITION p0 VALUES LESS THAN (100),
+< PARTITION p1 VALUES LESS THAN MAXVALUE
+< );
+< INSERT INTO t2 (a,b) SELECT a, b FROM t1;
+< ALTER TABLE t1 REPAIR PARTITION p0;
+< Table Op Msg_type Msg_text
+< test.t1 repair status OK
+< INSERT INTO t1 VALUES (3,'c');
+< ALTER TABLE t1 REPAIR PARTITION NO_WRITE_TO_BINLOG p0, p1;
+< Table Op Msg_type Msg_text
+< test.t1 repair status OK
+< INSERT INTO t2 (a,b) VALUES (5,'e'),(6,'f');
+< ALTER TABLE t2 REPAIR PARTITION LOCAL p1;
+< Table Op Msg_type Msg_text
+< test.t2 repair status OK
+< INSERT INTO t1 (a,b) VALUES (7,'g'),(8,'h');
+< ALTER TABLE t1 REPAIR PARTITION LOCAL ALL EXTENDED;
+< Table Op Msg_type Msg_text
+< test.t1 repair status OK
+< INSERT INTO t1 VALUES (10,'j');
+< ALTER TABLE t1 REPAIR PARTITION p1 QUICK USE_FRM;
+< Table Op Msg_type Msg_text
+< test.t1 repair status OK
+< INSERT INTO t2 (a,b) VALUES (12,'l');
+< ALTER TABLE t2 REPAIR PARTITION NO_WRITE_TO_BINLOG ALL QUICK EXTENDED USE_FRM;
+< Table Op Msg_type Msg_text
+< test.t2 repair status OK
+< DROP TABLE t1, t2;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/, b CHAR(8) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY HASH(a) PARTITIONS 2 ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+35a16,17
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+36a19
+> ERROR 42S02: Table 'test.t1' doesn't exist
+37a21,22
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+40c25,26
+< test.t1 repair status OK
+---
+> test.t1 repair Error Table 'test.t1' doesn't exist
+> test.t1 repair status Operation failed
+41a28
+> ERROR 42S02: Table 'test.t1' doesn't exist
+42a30
+> ERROR 42S02: Table 'test.t2' doesn't exist
+45,46c33,36
+< test.t1 repair status OK
+< test.t2 repair status OK
+---
+> test.t1 repair Error Table 'test.t1' doesn't exist
+> test.t1 repair status Operation failed
+> test.t2 repair Error Table 'test.t2' doesn't exist
+> test.t2 repair status Operation failed
+47a38
+> ERROR 42S02: Table 'test.t2' doesn't exist
+50c41,42
+< test.t2 repair status OK
+---
+> test.t2 repair Error Table 'test.t2' doesn't exist
+> test.t2 repair status Operation failed
+51a44
+> ERROR 42S02: Table 'test.t1' doesn't exist
+52a46
+> ERROR 42S02: Table 'test.t2' doesn't exist
+55,56c49,52
+< test.t2 repair status OK
+< test.t1 repair status OK
+---
+> test.t2 repair Error Table 'test.t2' doesn't exist
+> test.t2 repair status Operation failed
+> test.t1 repair Error Table 'test.t1' doesn't exist
+> test.t1 repair status Operation failed
+57a54
+> ERROR 42S02: Table 'test.t1' doesn't exist
+58a56
+> ERROR 42S02: Table 'test.t2' doesn't exist
+61,62c59,62
+< test.t1 repair status OK
+< test.t2 repair status OK
+---
+> test.t1 repair Error Table 'test.t1' doesn't exist
+> test.t1 repair status Operation failed
+> test.t2 repair Error Table 'test.t2' doesn't exist
+> test.t2 repair status Operation failed
+63a64
+> ERROR 42S02: Table 'test.t1' doesn't exist
+64a66
+> ERROR 42S02: Table 'test.t2' doesn't exist
+67,68c69,72
+< test.t1 repair status OK
+< test.t2 repair status OK
+---
+> test.t1 repair Error Table 'test.t1' doesn't exist
+> test.t1 repair status Operation failed
+> test.t2 repair Error Table 'test.t2' doesn't exist
+> test.t2 repair status Operation failed
+71,73c75,76
+< ERROR HY000: Failed to read from the .par file
+< # Statement ended with one of expected results (0,130,ER_FAILED_READ_FROM_PAR_FILE,ER_OPEN_AS_READONLY).
+< # If you got a difference in error message, just add it to rdiff file
+---
+> ERROR 42S02: Table 'test.t1' doesn't exist
+> # ERROR: Statement ended with errno 1146, errname ER_NO_SUCH_TABLE (expected results: 0,130,ER_FAILED_READ_FROM_PAR_FILE,ER_OPEN_AS_READONLY)
+76,78c79,80
+< test.t1 check Error Failed to read from the .par file
+< test.t1 check Error Incorrect information in file: './test/t1.frm'
+< test.t1 check error Corrupt
+---
+> test.t1 check Error Table 'test.t1' doesn't exist
+> test.t1 check status Operation failed
+80,82c82,83
+< ERROR HY000: Failed to read from the .par file
+< # Statement ended with one of expected results (0,130,ER_FAILED_READ_FROM_PAR_FILE,ER_OPEN_AS_READONLY).
+< # If you got a difference in error message, just add it to rdiff file
+---
+> ERROR 42S02: Table 'test.t1' doesn't exist
+> # ERROR: Statement ended with errno 1146, errname ER_NO_SUCH_TABLE (expected results: 0,130,ER_FAILED_READ_FROM_PAR_FILE,ER_OPEN_AS_READONLY)
+85,87c86,87
+< test.t1 repair Error Failed to read from the .par file
+< test.t1 repair Error Incorrect information in file: './test/t1.frm'
+< test.t1 repair error Corrupt
+---
+> test.t1 repair Error Table 'test.t1' doesn't exist
+> test.t1 repair status Operation failed
+88a89
+> ERROR 42S02: Unknown table 't1,t2'
+93a95,96
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+96c99,100
+< test.t1 repair status OK
+---
+> test.t1 repair Error Table 'test.t1' doesn't exist
+> test.t1 repair status Operation failed
+97a102
+> ERROR 42S02: Table 'test.t1' doesn't exist
+100c105,106
+< test.t1 repair status OK
+---
+> test.t1 repair Error Table 'test.t1' doesn't exist
+> test.t1 repair status Operation failed
+101a108
+> ERROR 42S02: Table 'test.t1' doesn't exist
+104,235c111,112
+< test.t1 repair status OK
+< t1#P#p0.MYD
+< t1#P#p0.MYI
+< t1#P#p1.MYD
+< t1#P#p1.MYI
+< t1.frm
+< t1.par
+< INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+< # Statement ended with one of expected results (0,144).
+< # If you got a difference in error message, just add it to rdiff file
+< FLUSH TABLE t1;
+< Restoring <DATADIR>/test/t1#P#p0.MYD
+< CHECK TABLE t1;
+< Table Op Msg_type Msg_text
+< test.t1 check error Size of datafile is: 26 Should be: 39
+< test.t1 check error Partition p0 returned error
+< test.t1 check error Corrupt
+< SELECT * FROM t1;
+< a b
+< 8 h
+< 10 j
+< 7 g
+< 15 o
+< Warnings:
+< Error 145 Table './test/t1#P#p0' is marked as crashed and should be repaired
+< Error 1194 Table 't1' is marked as crashed and should be repaired
+< Error 1034 Number of rows changed from 3 to 2
+< # Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+< # If you got a difference in error message, just add it to rdiff file
+< INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+< # Statement ended with one of expected results (0,144).
+< # If you got a difference in error message, just add it to rdiff file
+< FLUSH TABLE t1;
+< Restoring <DATADIR>/test/t1#P#p0.MYI
+< CHECK TABLE t1;
+< Table Op Msg_type Msg_text
+< test.t1 check warning Size of datafile is: 39 Should be: 26
+< test.t1 check error Record-count is not ok; is 3 Should be: 2
+< test.t1 check warning Found 3 key parts. Should be: 2
+< test.t1 check error Partition p0 returned error
+< test.t1 check error Corrupt
+< SELECT * FROM t1;
+< a b
+< 8 h
+< 10 j
+< 14 n
+< 7 g
+< 15 o
+< 15 o
+< Warnings:
+< Error 145 Table './test/t1#P#p0' is marked as crashed and should be repaired
+< Error 1194 Table 't1' is marked as crashed and should be repaired
+< Error 1034 Number of rows changed from 2 to 3
+< # Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+< # If you got a difference in error message, just add it to rdiff file
+< INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+< # Statement ended with one of expected results (0,144).
+< # If you got a difference in error message, just add it to rdiff file
+< FLUSH TABLE t1;
+< Restoring <DATADIR>/test/t1#P#p1.MYD
+< CHECK TABLE t1;
+< Table Op Msg_type Msg_text
+< test.t1 check error Size of datafile is: 39 Should be: 52
+< test.t1 check error Partition p1 returned error
+< test.t1 check error Corrupt
+< SELECT * FROM t1;
+< a b
+< 8 h
+< 10 j
+< 14 n
+< 14 n
+< 7 g
+< 15 o
+< 15 o
+< Warnings:
+< Error 145 Table './test/t1#P#p1' is marked as crashed and should be repaired
+< Error 1194 Table 't1' is marked as crashed and should be repaired
+< Error 1034 Number of rows changed from 4 to 3
+< # Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+< # If you got a difference in error message, just add it to rdiff file
+< INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+< # Statement ended with one of expected results (0,144).
+< # If you got a difference in error message, just add it to rdiff file
+< FLUSH TABLE t1;
+< Restoring <DATADIR>/test/t1#P#p1.MYI
+< CHECK TABLE t1;
+< Table Op Msg_type Msg_text
+< test.t1 check warning Size of datafile is: 52 Should be: 39
+< test.t1 check error Record-count is not ok; is 4 Should be: 3
+< test.t1 check warning Found 4 key parts. Should be: 3
+< test.t1 check error Partition p1 returned error
+< test.t1 check error Corrupt
+< SELECT * FROM t1;
+< a b
+< 8 h
+< 10 j
+< 14 n
+< 14 n
+< 14 n
+< 7 g
+< 15 o
+< 15 o
+< 15 o
+< Warnings:
+< Error 145 Table './test/t1#P#p1' is marked as crashed and should be repaired
+< Error 1194 Table 't1' is marked as crashed and should be repaired
+< Error 1034 Number of rows changed from 3 to 4
+< # Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+< # If you got a difference in error message, just add it to rdiff file
+< INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+< # Statement ended with one of expected results (0,144).
+< # If you got a difference in error message, just add it to rdiff file
+< FLUSH TABLE t1;
+< Restoring <DATADIR>/test/t1.par
+< CHECK TABLE t1;
+< Table Op Msg_type Msg_text
+< test.t1 check status OK
+< SELECT * FROM t1;
+< a b
+< 8 h
+< 10 j
+< 14 n
+< 14 n
+< 14 n
+< 14 n
+< 7 g
+< 15 o
+< 15 o
+< 15 o
+< 15 o
+< # Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+< # If you got a difference in error message, just add it to rdiff file
+---
+> test.t1 repair Error Table 'test.t1' doesn't exist
+> test.t1 repair status Operation failed
+236a114
+> ERROR 42S02: Unknown table 't1'
diff --git a/storage/myisammrg/mysql-test/storage_engine/parts/truncate_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/parts/truncate_table.rdiff
new file mode 100644
index 00000000000..2c1364d52e1
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/parts/truncate_table.rdiff
@@ -0,0 +1,100 @@
+3,8c3,12
+< TRUNCATE TABLE t1;
+< INSERT INTO t1 (a,b) VALUES (1,'a'), (2,'b'), (3,'c');
+< TRUNCATE TABLE t1;
+< SELECT * FROM t1;
+< a b
+< DROP TABLE t1;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/, b CHAR(8) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY HASH(a) PARTITIONS 2 ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+10,52c14,23
+< SHOW CREATE TABLE t1;
+< Table Create Table
+< t1 CREATE TABLE `t1` (
+< `a` int(11) NOT NULL AUTO_INCREMENT,
+< `c` char(8) DEFAULT NULL,
+< PRIMARY KEY (`a`)
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+< /*!50100 PARTITION BY HASH (a)
+< PARTITIONS 2 */
+< INSERT INTO t1 (c) VALUES ('a'),('b'),('c');
+< SHOW CREATE TABLE t1;
+< Table Create Table
+< t1 CREATE TABLE `t1` (
+< `a` int(11) NOT NULL AUTO_INCREMENT,
+< `c` char(8) DEFAULT NULL,
+< PRIMARY KEY (`a`)
+< ) ENGINE=<STORAGE_ENGINE> AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
+< /*!50100 PARTITION BY HASH (a)
+< PARTITIONS 2 */
+< TRUNCATE TABLE t1;
+< SHOW CREATE TABLE t1;
+< Table Create Table
+< t1 CREATE TABLE `t1` (
+< `a` int(11) NOT NULL AUTO_INCREMENT,
+< `c` char(8) DEFAULT NULL,
+< PRIMARY KEY (`a`)
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+< /*!50100 PARTITION BY HASH (a)
+< PARTITIONS 2 */
+< INSERT INTO t1 (c) VALUES ('d');
+< SHOW CREATE TABLE t1;
+< Table Create Table
+< t1 CREATE TABLE `t1` (
+< `a` int(11) NOT NULL AUTO_INCREMENT,
+< `c` char(8) DEFAULT NULL,
+< PRIMARY KEY (`a`)
+< ) ENGINE=<STORAGE_ENGINE> AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
+< /*!50100 PARTITION BY HASH (a)
+< PARTITIONS 2 */
+< SELECT * FROM t1;
+< a c
+< 1 d
+< DROP TABLE t1;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom indexed column options*/ KEY AUTO_INCREMENT, c CHAR(8) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY HASH(a) PARTITIONS 2 ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or PK or auto-increment or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+54,68c25,34
+< INSERT INTO t1 (a,b) VALUES (1,'a'),(2,'b'),(3,'c'),(2,'d'),(4,'e'),(100,'f'),(101,'g');
+< ALTER TABLE t1 TRUNCATE PARTITION p0;
+< SELECT * FROM t1;
+< a b
+< 1 a
+< 101 g
+< 3 c
+< EXPLAIN PARTITIONS SELECT * FROM t1;
+< id select_type table partitions type possible_keys key key_len ref rows Extra
+< 1 SIMPLE t1 p0,p1 # # # # # #
+< INSERT INTO t1 (a,b) VALUES (1,'a'), (2,'b'), (3,'c');
+< ALTER TABLE t1 TRUNCATE PARTITION ALL;
+< SELECT * FROM t1;
+< a b
+< DROP TABLE t1;
+---
+> ERROR HY000: Engine cannot be used in partitioned tables
+> # ERROR: Statement ended with errno 1572, errname ER_PARTITION_MERGE_ERROR (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/, b CHAR(8) /*!*/ /*Custom column options*/) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST PARTITION BY HASH(a) PARTITIONS 2 ]
+> # The statement|command finished with ER_PARTITION_MERGE_ERROR.
+> # Partitions or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
diff --git a/storage/myisammrg/mysql-test/storage_engine/repair_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/repair_table.rdiff
new file mode 100644
index 00000000000..180647323bc
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/repair_table.rdiff
@@ -0,0 +1,103 @@
+7c7
+< test.t1 repair status OK
+---
+> test.t1 repair note The storage engine for the table doesn't support repair
+12,13c12,13
+< test.t1 repair status OK
+< test.t2 repair status OK
+---
+> test.t1 repair note The storage engine for the table doesn't support repair
+> test.t2 repair note The storage engine for the table doesn't support repair
+17c17
+< test.t2 repair status OK
+---
+> test.t2 repair note The storage engine for the table doesn't support repair
+22,23c22,23
+< test.t2 repair status OK
+< test.t1 repair status OK
+---
+> test.t2 repair note The storage engine for the table doesn't support repair
+> test.t1 repair note The storage engine for the table doesn't support repair
+28,31c28,29
+< test.t1 repair warning Number of rows changed from 0 to 6
+< test.t1 repair status OK
+< test.t2 repair warning Number of rows changed from 0 to 5
+< test.t2 repair status OK
+---
+> test.t1 repair note The storage engine for the table doesn't support repair
+> test.t2 repair note The storage engine for the table doesn't support repair
+36,39c34,35
+< test.t1 repair warning Number of rows changed from 0 to 7
+< test.t1 repair status OK
+< test.t2 repair warning Number of rows changed from 0 to 6
+< test.t2 repair status OK
+---
+> test.t1 repair note The storage engine for the table doesn't support repair
+> test.t2 repair note The storage engine for the table doesn't support repair
+42c38
+< ERROR HY000: Incorrect file format 't1'
+---
+> ERROR HY000: Table 't1' is read only
+47,48c43
+< test.t1 check Error Incorrect file format 't1'
+< test.t1 check error Corrupt
+---
+> test.t1 check status OK
+50c45
+< ERROR HY000: Incorrect file format 't1'
+---
+> a b
+55,56c50
+< test.t1 repair Error Incorrect file format 't1'
+< test.t1 repair error Corrupt
+---
+> test.t1 repair note The storage engine for the table doesn't support repair
+65c59
+< test.t1 repair status OK
+---
+> test.t1 repair note The storage engine for the table doesn't support repair
+69c63
+< test.t1 repair status OK
+---
+> test.t1 repair note The storage engine for the table doesn't support repair
+73,76c67,68
+< test.t1 repair warning Number of rows changed from 0 to 3
+< test.t1 repair status OK
+< t1.MYD
+< t1.MYI
+---
+> test.t1 repair note The storage engine for the table doesn't support repair
+> t1.MRG
+82c74
+< Restoring <DATADIR>/test/t1.MYD
+---
+> Restoring <DATADIR>/test/t1.MRG
+85,86c77
+< test.t1 check error Size of datafile is: 39 Should be: 65
+< test.t1 check error Corrupt
+---
+> test.t1 check status OK
+88,103c79,84
+< ERROR HY000: Incorrect key file for table 't1'; try to repair it
+< # Statement ended with one of expected results (0,ER_NOT_KEYFILE,144).
+< # If you got a difference in error message, just add it to rdiff file
+< INSERT INTO t1 (a,b) VALUES (14,'n'),(15,'o');
+< ERROR HY000: Table './test/t1' is marked as crashed and last (automatic?) repair failed
+< # Statement ended with one of expected results (0,144).
+< # If you got a difference in error message, just add it to rdiff file
+< FLUSH TABLE t1;
+< Restoring <DATADIR>/test/t1.MYI
+< CHECK TABLE t1;
+< Table Op Msg_type Msg_text
+< test.t1 check warning Table is marked as crashed and last repair failed
+< test.t1 check error Size of datafile is: 39 Should be: 65
+< test.t1 check error Corrupt
+< SELECT * FROM t1;
+< ERROR HY000: Table './test/t1' is marked as crashed and last (automatic?) repair failed
+---
+> a b
+> 7 g
+> 8 h
+> 10 j
+> 14 n
+> 15 o
diff --git a/storage/myisammrg/mysql-test/storage_engine/show_engine.rdiff b/storage/myisammrg/mysql-test/storage_engine/show_engine.rdiff
new file mode 100644
index 00000000000..e7c9b0176b6
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/show_engine.rdiff
@@ -0,0 +1,2 @@
+7d6
+< <STORAGE_ENGINE> ### Engine status, can be long and changeable ###
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_ai.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_ai.rdiff
new file mode 100644
index 00000000000..bca6fa60d13
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_ai.rdiff
@@ -0,0 +1,8 @@
+7c7
+< ) ENGINE=<STORAGE_ENGINE> AUTO_INCREMENT=10 DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+13c13
+< ) ENGINE=<STORAGE_ENGINE> AUTO_INCREMENT=100 DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_avg_row_length.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_avg_row_length.rdiff
new file mode 100644
index 00000000000..7a3ac54fd3e
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_avg_row_length.rdiff
@@ -0,0 +1,8 @@
+8c8
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 AVG_ROW_LENGTH=300
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 AVG_ROW_LENGTH=300 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+15c15
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 AVG_ROW_LENGTH=30000000
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 AVG_ROW_LENGTH=30000000 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_checksum.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_checksum.rdiff
new file mode 100644
index 00000000000..ecb3fadb479
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_checksum.rdiff
@@ -0,0 +1,8 @@
+8c8
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 CHECKSUM=1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 CHECKSUM=1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+15c15
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_connection.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_connection.rdiff
new file mode 100644
index 00000000000..d3ebd87ad1e
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_connection.rdiff
@@ -0,0 +1,8 @@
+13c13
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 CONNECTION='test_connection'
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`) CONNECTION='test_connection'
+20c20
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 CONNECTION='test_connection2'
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`) CONNECTION='test_connection2'
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_data_index_dir.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_data_index_dir.rdiff
new file mode 100644
index 00000000000..3c15e10d1f1
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_data_index_dir.rdiff
@@ -0,0 +1,8 @@
+7c7
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 DATA DIRECTORY='<DATA_DIR>' INDEX DIRECTORY='<INDEX_DIR>'
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+15c15
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 DATA DIRECTORY='<DATA_DIR>' INDEX DIRECTORY='<INDEX_DIR>'
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_delay_key_write.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_delay_key_write.rdiff
new file mode 100644
index 00000000000..5723e425b4d
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_delay_key_write.rdiff
@@ -0,0 +1,8 @@
+8c8
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+15c15
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_insert_method.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_insert_method.rdiff
new file mode 100644
index 00000000000..2ced7647483
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_insert_method.rdiff
@@ -0,0 +1,8 @@
+8c8
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=FIRST
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=FIRST UNION=(`mrg`.`t1`)
+15c15
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_key_block_size.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_key_block_size.rdiff
new file mode 100644
index 00000000000..8378f04ebcb
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_key_block_size.rdiff
@@ -0,0 +1,8 @@
+8c8
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=8 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+15c15
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_max_rows.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_max_rows.rdiff
new file mode 100644
index 00000000000..f89147826c6
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_max_rows.rdiff
@@ -0,0 +1,8 @@
+8c8
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 MAX_ROWS=10000000
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 MAX_ROWS=10000000 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+15c15
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 MAX_ROWS=30000000
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 MAX_ROWS=30000000 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_min_rows.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_min_rows.rdiff
new file mode 100644
index 00000000000..3ce28480dcf
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_min_rows.rdiff
@@ -0,0 +1,8 @@
+8c8
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 MIN_ROWS=1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 MIN_ROWS=1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+15c15
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 MIN_ROWS=10000
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 MIN_ROWS=10000 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_pack_keys.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_pack_keys.rdiff
new file mode 100644
index 00000000000..246c7397a96
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_pack_keys.rdiff
@@ -0,0 +1,8 @@
+8c8
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 PACK_KEYS=1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 PACK_KEYS=1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+15c15
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 PACK_KEYS=0
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 PACK_KEYS=0 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_password.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_password.rdiff
new file mode 100644
index 00000000000..b1ef20c6f30
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_password.rdiff
@@ -0,0 +1,8 @@
+8c8
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+15c15
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_row_format.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_row_format.rdiff
new file mode 100644
index 00000000000..9c72c7c06ba
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_row_format.rdiff
@@ -0,0 +1,8 @@
+8c8
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
+15c15
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_opt_union.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_union.rdiff
new file mode 100644
index 00000000000..f77753f4d6b
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_opt_union.rdiff
@@ -0,0 +1,8 @@
+7c7
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 UNION=(`child1`)
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`child1`)
+13c13
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 UNION=(`child1`,`child2`)
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`child1`,`child2`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_standard_opts.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_standard_opts.rdiff
new file mode 100644
index 00000000000..9b7ffc6af76
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_standard_opts.rdiff
@@ -0,0 +1,8 @@
+11c11
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=utf8 COMMENT='standard table options'
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=utf8 INSERT_METHOD=LAST UNION=(`mrg`.`t1`) COMMENT='standard table options'
+18c18
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=utf8 COMMENT='table altered'
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=utf8 INSERT_METHOD=LAST UNION=(`mrg`.`t1`) COMMENT='table altered'
diff --git a/storage/myisammrg/mysql-test/storage_engine/tbl_temporary.rdiff b/storage/myisammrg/mysql-test/storage_engine/tbl_temporary.rdiff
new file mode 100644
index 00000000000..45a229c98eb
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/tbl_temporary.rdiff
@@ -0,0 +1,4 @@
+9c9
+< ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1
+---
+> ) ENGINE=<STORAGE_ENGINE> DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`mrg`.`t1`)
diff --git a/storage/myisammrg/mysql-test/storage_engine/truncate_table.rdiff b/storage/myisammrg/mysql-test/storage_engine/truncate_table.rdiff
new file mode 100644
index 00000000000..3a89f730540
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/truncate_table.rdiff
@@ -0,0 +1,35 @@
+12c12
+< t1 # # # # # # # # # 1 # # # # # # #
+---
+> t1 # # # # # # # # # 0 # # # # # # #
+16c16
+< t1 # # # # # # # # # 4 # # # # # # #
+---
+> t1 # # # # # # # # # 0 # # # # # # #
+20c20
+< t1 # # # # # # # # # 1 # # # # # # #
+---
+> t1 # # # # # # # # # 0 # # # # # # #
+24c24
+< t1 # # # # # # # # # 2 # # # # # # #
+---
+> t1 # # # # # # # # # 0 # # # # # # #
+32,40c32,39
+< HANDLER h1 READ FIRST;
+< a b
+< 1 a
+< TRUNCATE TABLE t1;
+< HANDLER h1 READ NEXT;
+< ERROR 42S02: Unknown table 'h1' in HANDLER
+< HANDLER t1 OPEN AS h2;
+< HANDLER h2 READ FIRST;
+< a b
+---
+> ERROR HY000: Table storage engine for 'h1' doesn't have this option
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command finished with ER_ILLEGAL_HA.
+> # HANDLER or the syntax or the mix could be unsupported.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/cons_snapshot_repeatable_read.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/cons_snapshot_repeatable_read.rdiff
new file mode 100644
index 00000000000..018b28bd24c
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/cons_snapshot_repeatable_read.rdiff
@@ -0,0 +1,9 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+13a20
+> 1
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/cons_snapshot_serializable.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/cons_snapshot_serializable.rdiff
new file mode 100644
index 00000000000..018b28bd24c
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/cons_snapshot_serializable.rdiff
@@ -0,0 +1,9 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+13a20
+> 1
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/delete.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/delete.rdiff
new file mode 100644
index 00000000000..45a3e5fb52d
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/delete.rdiff
@@ -0,0 +1,34 @@
+0a1,12
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support savepoints.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file (recommended), or add the test to disabled.def.
+> # If savepoints should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+48a61,62
+> Warnings:
+> Warning 1196 Some non-transactional changed tables couldn't be rolled back
+51,64d64
+< 10000 foobar
+< 10000 foobar
+< 2 b
+< 2 b
+< 4 d
+< 4 d
+< 5 e
+< 5 e
+< 6 f
+< 6 f
+< 7 g
+< 7 g
+< 8 h
+< 8 h
+70a71,72
+> Warnings:
+> Warning 1196 Some non-transactional changed tables couldn't be rolled back
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/insert.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/insert.rdiff
new file mode 100644
index 00000000000..69981f90e13
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/insert.rdiff
@@ -0,0 +1,32 @@
+0a1,12
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support savepoints.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file (recommended), or add the test to disabled.def.
+> # If savepoints should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+23a36,37
+> Warnings:
+> Warning 1196 Some non-transactional changed tables couldn't be rolled back
+25a40
+> 0 test
+33a49,50
+> NULL NULL
+> NULL NULL
+39a57,58
+> Warnings:
+> Warning 1196 Some non-transactional changed tables couldn't be rolled back
+43a63
+> 0 test
+49a70
+> 11 f
+54a76,78
+> NULL NULL
+> NULL NULL
+> NULL NULL
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/level_read_committed.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/level_read_committed.rdiff
new file mode 100644
index 00000000000..0837c74f5ff
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/level_read_committed.rdiff
@@ -0,0 +1,44 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+18a25
+> 1
+25a33,34
+> 1
+> 2
+30a40,43
+> 1
+> 101
+> 102
+> 2
+34a48,49
+> 101
+> 102
+39a55,56
+> 101
+> 102
+44a62,63
+> 101
+> 102
+51a71,72
+> 101
+> 102
+54a76,77
+> 301
+> 302
+58a82,83
+> 101
+> 102
+61a87,88
+> 301
+> 302
+65a93,94
+> 101
+> 102
+68a98,99
+> 301
+> 302
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/level_read_uncommitted.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/level_read_uncommitted.rdiff
new file mode 100644
index 00000000000..bd9569267e5
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/level_read_uncommitted.rdiff
@@ -0,0 +1,7 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/level_repeatable_read.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/level_repeatable_read.rdiff
new file mode 100644
index 00000000000..82f7c5c5ba6
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/level_repeatable_read.rdiff
@@ -0,0 +1,53 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+18a25
+> 1
+25a33,34
+> 1
+> 2
+27,28c36
+< ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+< # WARNING: Statement ended with errno 1205, errname 'ER_LOCK_WAIT_TIMEOUT'.
+---
+> # WARNING: Statement ended with errno 0, errname ''.
+31a40,43
+> 1
+> 101
+> 102
+> 2
+35a48,49
+> 101
+> 102
+40a55,56
+> 101
+> 102
+44a61,64
+> 1
+> 101
+> 102
+> 2
+49a70,73
+> 1
+> 101
+> 102
+> 2
+51a76,77
+> 301
+> 302
+55a82,83
+> 101
+> 102
+58a87,88
+> 301
+> 302
+62a93,94
+> 101
+> 102
+65a98,99
+> 301
+> 302
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/level_serializable.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/level_serializable.rdiff
new file mode 100644
index 00000000000..3924b3784a9
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/level_serializable.rdiff
@@ -0,0 +1,69 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+14,15c20
+< ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+< # WARNING: Statement ended with errno 1205, errname 'ER_LOCK_WAIT_TIMEOUT'.
+---
+> # WARNING: Statement ended with errno 0, errname ''.
+19a25
+> 1
+22,23c28
+< ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+< # WARNING: Statement ended with errno 1205, errname 'ER_LOCK_WAIT_TIMEOUT'.
+---
+> # WARNING: Statement ended with errno 0, errname ''.
+27a33,34
+> 1
+> 2
+32a40,43
+> 1
+> 101
+> 102
+> 2
+35a47,50
+> 1
+> 101
+> 102
+> 2
+38a54,57
+> 1
+> 101
+> 102
+> 2
+41a61,64
+> 1
+> 101
+> 102
+> 2
+46a70,77
+> 1
+> 101
+> 102
+> 2
+> 201
+> 202
+> 301
+> 302
+49a81,88
+> 1
+> 101
+> 102
+> 2
+> 201
+> 202
+> 301
+> 302
+52a92,99
+> 1
+> 101
+> 102
+> 2
+> 201
+> 202
+> 301
+> 302
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/select_for_update.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/select_for_update.rdiff
new file mode 100644
index 00000000000..f8ffe67586d
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/select_for_update.rdiff
@@ -0,0 +1,40 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+17c23,33
+< ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+---
+> a b
+> 1 a
+> 3 a
+> # ERROR: Statement succeeded (expected results: ER_LOCK_WAIT_TIMEOUT)
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command succeeded unexpectedly.
+> # SELECT .. FOR UPDATE or LOCK IN SHARE MODE or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+19c35,42
+< ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+---
+> # ERROR: Statement succeeded (expected results: ER_LOCK_WAIT_TIMEOUT)
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command succeeded unexpectedly.
+> # UPDATE or SELECT .. FOR UPDATE or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+24c47
+< 1 a
+---
+> 1 c
+26c49
+< 3 a
+---
+> 3 c
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/select_lock_in_share_mode.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/select_lock_in_share_mode.rdiff
new file mode 100644
index 00000000000..e316993830a
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/select_lock_in_share_mode.rdiff
@@ -0,0 +1,26 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+21c27,34
+< ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+---
+> # ERROR: Statement succeeded (expected results: ER_LOCK_WAIT_TIMEOUT)
+> # ------------ UNEXPECTED RESULT ------------
+> # The statement|command succeeded unexpectedly.
+> # LOCK IN SHARE MODE or UPDATE or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+26c39
+< 1 a
+---
+> 1 c
+28c41
+< 3 a
+---
+> 3 c
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/update.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/update.rdiff
new file mode 100644
index 00000000000..7ad463053eb
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/update.rdiff
@@ -0,0 +1,41 @@
+0a1,12
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support transactions.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If transactions should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support savepoints.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file (recommended), or add the test to disabled.def.
+> # If savepoints should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+26a39,40
+> Warnings:
+> Warning 1196 Some non-transactional changed tables couldn't be rolled back
+31a46,47
+> Warnings:
+> Warning 1196 Some non-transactional changed tables couldn't be rolled back
+38,47c54,63
+< 51 update2
+< 51 update2
+< 52 update2
+< 52 update2
+< 53 update2
+< 53 update2
+< 54 update2
+< 54 update2
+< 55 update2
+< 55 update2
+---
+> 51
+> 51
+> 52
+> 52
+> 53
+> 53
+> 54
+> 54
+> 55
+> 55
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/xa.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/xa.rdiff
new file mode 100644
index 00000000000..ee7c2a984be
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/xa.rdiff
@@ -0,0 +1,34 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support XA.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If XA should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+11a18
+> 1
+17a25,26
+> 1
+> 2
+22a32,33
+> 1
+> 2
+40a52
+> 3
+48a61,62
+> 3
+> 4
+67a82
+> 5
+77a93,94
+> 5
+> 6
+86a104,105
+> 5
+> 6
+88a108,109
+> Warnings:
+> Warning 1196 Some non-transactional changed tables couldn't be rolled back
+95a117,118
+> 5
+> 6
diff --git a/storage/myisammrg/mysql-test/storage_engine/trx/xa_recovery.rdiff b/storage/myisammrg/mysql-test/storage_engine/trx/xa_recovery.rdiff
new file mode 100644
index 00000000000..362e3a8914a
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/trx/xa_recovery.rdiff
@@ -0,0 +1,22 @@
+0a1,6
+> # -- WARNING ----------------------------------------------------------------
+> # According to I_S.ENGINES, MRG_MYISAM does not support XA.
+> # If it is true, the test will most likely fail; you can
+> # either create an rdiff file, or add the test to disabled.def.
+> # If XA should be supported, check the data in Information Schema.
+> # ---------------------------------------------------------------------------
+21,22d26
+< 1 3 0 xa1
+< 1 3 0 xa2
+23a28
+> ERROR XAE04: XAER_NOTA: Unknown XID
+24a30
+> ERROR XAE04: XAER_NOTA: Unknown XID
+26a33,34
+> 1
+> 2
+28a37,40
+> Warnings:
+> Error 145 Table './mrg/t1' is marked as crashed and should be repaired
+> Error 1194 Table 't1' is marked as crashed and should be repaired
+> Error 1034 1 client is using or hasn't closed the table properly
diff --git a/storage/myisammrg/mysql-test/storage_engine/type_char_indexes.rdiff b/storage/myisammrg/mysql-test/storage_engine/type_char_indexes.rdiff
new file mode 100644
index 00000000000..a0a418e0bcc
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/type_char_indexes.rdiff
@@ -0,0 +1,8 @@
+101c101
+< # # # range c_v c_v # # # Using index condition
+---
+> # # # ALL c_v NULL # # # Using where
+138c138
+< # # # range # v16 # # # #
+---
+> # # # ALL # NULL # # # #
diff --git a/storage/myisammrg/mysql-test/storage_engine/type_float_indexes.rdiff b/storage/myisammrg/mysql-test/storage_engine/type_float_indexes.rdiff
new file mode 100644
index 00000000000..640e1050a99
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/type_float_indexes.rdiff
@@ -0,0 +1,4 @@
+63c63
+< # # # # # d # # # #
+---
+> # # # # # NULL # # # #
diff --git a/storage/myisammrg/mysql-test/storage_engine/type_spatial.rdiff b/storage/myisammrg/mysql-test/storage_engine/type_spatial.rdiff
new file mode 100644
index 00000000000..a4d7d4390b8
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/type_spatial.rdiff
@@ -0,0 +1,706 @@
+5,698c5,14
+< CREATE TABLE gis_line (fid <INT_COLUMN>, g LINESTRING) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_polygon (fid <INT_COLUMN>, g POLYGON) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_multi_point (fid <INT_COLUMN>, g MULTIPOINT) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_multi_line (fid <INT_COLUMN>, g MULTILINESTRING) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_multi_polygon (fid <INT_COLUMN>, g MULTIPOLYGON) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_geometrycollection (fid <INT_COLUMN>, g GEOMETRYCOLLECTION) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_geometry (fid <INT_COLUMN>, g GEOMETRY) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< USE gis_ogs;
+< CREATE TABLE lakes (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< shore POLYGON) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE road_segments (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< aliases CHAR(64) <CUSTOM_COL_OPTIONS>,
+< num_lanes INT <CUSTOM_COL_OPTIONS>,
+< centerline LINESTRING) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE divided_routes (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< num_lanes INT <CUSTOM_COL_OPTIONS>,
+< centerlines MULTILINESTRING) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE forests (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< boundary MULTIPOLYGON) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE bridges (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< position POINT) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE streams (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< centerline LINESTRING) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE buildings (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< position POINT,
+< footprint POLYGON) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE ponds (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< type CHAR(64) <CUSTOM_COL_OPTIONS>,
+< shores MULTIPOLYGON) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE named_places (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< boundary POLYGON) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE map_neatlines (fid INT <CUSTOM_COL_OPTIONS>,
+< neatline POLYGON) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< USE test;
+< SHOW FIELDS FROM gis_point;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g point YES NULL
+< SHOW FIELDS FROM gis_line;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g linestring YES NULL
+< SHOW FIELDS FROM gis_polygon;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g polygon YES NULL
+< SHOW FIELDS FROM gis_multi_point;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g multipoint YES NULL
+< SHOW FIELDS FROM gis_multi_line;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g multilinestring YES NULL
+< SHOW FIELDS FROM gis_multi_polygon;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g multipolygon YES NULL
+< SHOW FIELDS FROM gis_geometrycollection;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g geometrycollection YES NULL
+< SHOW FIELDS FROM gis_geometry;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g geometry YES NULL
+< INSERT INTO gis_point VALUES
+< (101, PointFromText('POINT(10 10)')),
+< (102, PointFromText('POINT(20 10)')),
+< (103, PointFromText('POINT(20 20)')),
+< (104, PointFromWKB(AsWKB(PointFromText('POINT(10 20)'))));
+< INSERT INTO gis_line VALUES
+< (105, LineFromText('LINESTRING(0 0,0 10,10 0)')),
+< (106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
+< (107, LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));
+< INSERT INTO gis_polygon VALUES
+< (108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
+< (109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')),
+< (110, PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))));
+< INSERT INTO gis_multi_point VALUES
+< (111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
+< (112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
+< (113, MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));
+< INSERT INTO gis_multi_line VALUES
+< (114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),
+< (115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
+< (116, MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))));
+< INSERT INTO gis_multi_polygon VALUES
+< (117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
+< (118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
+< (119, MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));
+< INSERT INTO gis_geometrycollection VALUES
+< (120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
+< (121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))),
+< (122, GeomFromText('GeometryCollection()')),
+< (123, GeomFromText('GeometryCollection EMPTY'));
+< INSERT into gis_geometry SELECT * FROM gis_point;
+< INSERT into gis_geometry SELECT * FROM gis_line;
+< INSERT into gis_geometry SELECT * FROM gis_polygon;
+< INSERT into gis_geometry SELECT * FROM gis_multi_point;
+< INSERT into gis_geometry SELECT * FROM gis_multi_line;
+< INSERT into gis_geometry SELECT * FROM gis_multi_polygon;
+< INSERT into gis_geometry SELECT * FROM gis_geometrycollection;
+< SELECT fid, AsText(g) FROM gis_point;
+< fid AsText(g)
+< 101 POINT(10 10)
+< 102 POINT(20 10)
+< 103 POINT(20 20)
+< 104 POINT(10 20)
+< SELECT fid, AsText(g) FROM gis_line;
+< fid AsText(g)
+< 105 LINESTRING(0 0,0 10,10 0)
+< 106 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+< 107 LINESTRING(10 10,40 10)
+< SELECT fid, AsText(g) FROM gis_polygon;
+< fid AsText(g)
+< 108 POLYGON((10 10,20 10,20 20,10 20,10 10))
+< 109 POLYGON((0 0,50 0,50 50,0 50,0 0),(10 10,20 10,20 20,10 20,10 10))
+< 110 POLYGON((0 0,30 0,30 30,0 0))
+< SELECT fid, AsText(g) FROM gis_multi_point;
+< fid AsText(g)
+< 111 MULTIPOINT(0 0,10 10,10 20,20 20)
+< 112 MULTIPOINT(1 1,11 11,11 21,21 21)
+< 113 MULTIPOINT(3 6,4 10)
+< SELECT fid, AsText(g) FROM gis_multi_line;
+< fid AsText(g)
+< 114 MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))
+< 115 MULTILINESTRING((10 48,10 21,10 0))
+< 116 MULTILINESTRING((1 2,3 5),(2 5,5 8,21 7))
+< SELECT fid, AsText(g) FROM gis_multi_polygon;
+< fid AsText(g)
+< 117 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+< 118 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+< 119 MULTIPOLYGON(((0 3,3 3,3 0,0 3)))
+< SELECT fid, AsText(g) FROM gis_geometrycollection;
+< fid AsText(g)
+< 120 GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,10 10))
+< 121 GEOMETRYCOLLECTION(POINT(44 6),LINESTRING(3 6,7 9))
+< 122 GEOMETRYCOLLECTION EMPTY
+< 123 GEOMETRYCOLLECTION EMPTY
+< SELECT fid, AsText(g) FROM gis_geometry;
+< fid AsText(g)
+< 101 POINT(10 10)
+< 102 POINT(20 10)
+< 103 POINT(20 20)
+< 104 POINT(10 20)
+< 105 LINESTRING(0 0,0 10,10 0)
+< 106 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+< 107 LINESTRING(10 10,40 10)
+< 108 POLYGON((10 10,20 10,20 20,10 20,10 10))
+< 109 POLYGON((0 0,50 0,50 50,0 50,0 0),(10 10,20 10,20 20,10 20,10 10))
+< 110 POLYGON((0 0,30 0,30 30,0 0))
+< 111 MULTIPOINT(0 0,10 10,10 20,20 20)
+< 112 MULTIPOINT(1 1,11 11,11 21,21 21)
+< 113 MULTIPOINT(3 6,4 10)
+< 114 MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))
+< 115 MULTILINESTRING((10 48,10 21,10 0))
+< 116 MULTILINESTRING((1 2,3 5),(2 5,5 8,21 7))
+< 117 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+< 118 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+< 119 MULTIPOLYGON(((0 3,3 3,3 0,0 3)))
+< 120 GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,10 10))
+< 121 GEOMETRYCOLLECTION(POINT(44 6),LINESTRING(3 6,7 9))
+< 122 GEOMETRYCOLLECTION EMPTY
+< 123 GEOMETRYCOLLECTION EMPTY
+< SELECT fid, Dimension(g) FROM gis_geometry;
+< fid Dimension(g)
+< 101 0
+< 102 0
+< 103 0
+< 104 0
+< 105 1
+< 106 1
+< 107 1
+< 108 2
+< 109 2
+< 110 2
+< 111 0
+< 112 0
+< 113 0
+< 114 1
+< 115 1
+< 116 1
+< 117 2
+< 118 2
+< 119 2
+< 120 1
+< 121 1
+< 122 0
+< 123 0
+< SELECT fid, GeometryType(g) FROM gis_geometry;
+< fid GeometryType(g)
+< 101 POINT
+< 102 POINT
+< 103 POINT
+< 104 POINT
+< 105 LINESTRING
+< 106 LINESTRING
+< 107 LINESTRING
+< 108 POLYGON
+< 109 POLYGON
+< 110 POLYGON
+< 111 MULTIPOINT
+< 112 MULTIPOINT
+< 113 MULTIPOINT
+< 114 MULTILINESTRING
+< 115 MULTILINESTRING
+< 116 MULTILINESTRING
+< 117 MULTIPOLYGON
+< 118 MULTIPOLYGON
+< 119 MULTIPOLYGON
+< 120 GEOMETRYCOLLECTION
+< 121 GEOMETRYCOLLECTION
+< 122 GEOMETRYCOLLECTION
+< 123 GEOMETRYCOLLECTION
+< SELECT fid, IsEmpty(g) FROM gis_geometry;
+< fid IsEmpty(g)
+< 101 0
+< 102 0
+< 103 0
+< 104 0
+< 105 0
+< 106 0
+< 107 0
+< 108 0
+< 109 0
+< 110 0
+< 111 0
+< 112 0
+< 113 0
+< 114 0
+< 115 0
+< 116 0
+< 117 0
+< 118 0
+< 119 0
+< 120 0
+< 121 0
+< 122 0
+< 123 0
+< SELECT fid, AsText(Envelope(g)) FROM gis_geometry;
+< fid AsText(Envelope(g))
+< 101 POLYGON((10 10,10 10,10 10,10 10,10 10))
+< 102 POLYGON((20 10,20 10,20 10,20 10,20 10))
+< 103 POLYGON((20 20,20 20,20 20,20 20,20 20))
+< 104 POLYGON((10 20,10 20,10 20,10 20,10 20))
+< 105 POLYGON((0 0,10 0,10 10,0 10,0 0))
+< 106 POLYGON((10 10,20 10,20 20,10 20,10 10))
+< 107 POLYGON((10 10,40 10,40 10,10 10,10 10))
+< 108 POLYGON((10 10,20 10,20 20,10 20,10 10))
+< 109 POLYGON((0 0,50 0,50 50,0 50,0 0))
+< 110 POLYGON((0 0,30 0,30 30,0 30,0 0))
+< 111 POLYGON((0 0,20 0,20 20,0 20,0 0))
+< 112 POLYGON((1 1,21 1,21 21,1 21,1 1))
+< 113 POLYGON((3 6,4 6,4 10,3 10,3 6))
+< 114 POLYGON((10 0,16 0,16 48,10 48,10 0))
+< 115 POLYGON((10 0,10 0,10 48,10 48,10 0))
+< 116 POLYGON((1 2,21 2,21 8,1 8,1 2))
+< 117 POLYGON((28 0,84 0,84 42,28 42,28 0))
+< 118 POLYGON((28 0,84 0,84 42,28 42,28 0))
+< 119 POLYGON((0 0,3 0,3 3,0 3,0 0))
+< 120 POLYGON((0 0,10 0,10 10,0 10,0 0))
+< 121 POLYGON((3 6,44 6,44 9,3 9,3 6))
+< 122 GEOMETRYCOLLECTION EMPTY
+< 123 GEOMETRYCOLLECTION EMPTY
+< SELECT fid, X(g) FROM gis_point;
+< fid X(g)
+< 101 10
+< 102 20
+< 103 20
+< 104 10
+< SELECT fid, Y(g) FROM gis_point;
+< fid Y(g)
+< 101 10
+< 102 10
+< 103 20
+< 104 20
+< SELECT fid, AsText(StartPoint(g)) FROM gis_line;
+< fid AsText(StartPoint(g))
+< 105 POINT(0 0)
+< 106 POINT(10 10)
+< 107 POINT(10 10)
+< SELECT fid, AsText(EndPoint(g)) FROM gis_line;
+< fid AsText(EndPoint(g))
+< 105 POINT(10 0)
+< 106 POINT(10 10)
+< 107 POINT(40 10)
+< SELECT fid, GLength(g) FROM gis_line;
+< fid GLength(g)
+< 105 24.14213562373095
+< 106 40
+< 107 30
+< SELECT fid, NumPoints(g) FROM gis_line;
+< fid NumPoints(g)
+< 105 3
+< 106 5
+< 107 2
+< SELECT fid, AsText(PointN(g, 2)) FROM gis_line;
+< fid AsText(PointN(g, 2))
+< 105 POINT(0 10)
+< 106 POINT(20 10)
+< 107 POINT(40 10)
+< SELECT fid, IsClosed(g) FROM gis_line;
+< fid IsClosed(g)
+< 105 0
+< 106 1
+< 107 0
+< SELECT fid, AsText(Centroid(g)) FROM gis_polygon;
+< fid AsText(Centroid(g))
+< 108 POINT(15 15)
+< 109 POINT(25.416666666666668 25.416666666666668)
+< 110 POINT(20 10)
+< SELECT fid, Area(g) FROM gis_polygon;
+< fid Area(g)
+< 108 100
+< 109 2400
+< 110 450
+< SELECT fid, AsText(ExteriorRing(g)) FROM gis_polygon;
+< fid AsText(ExteriorRing(g))
+< 108 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+< 109 LINESTRING(0 0,50 0,50 50,0 50,0 0)
+< 110 LINESTRING(0 0,30 0,30 30,0 0)
+< SELECT fid, NumInteriorRings(g) FROM gis_polygon;
+< fid NumInteriorRings(g)
+< 108 0
+< 109 1
+< 110 0
+< SELECT fid, AsText(InteriorRingN(g, 1)) FROM gis_polygon;
+< fid AsText(InteriorRingN(g, 1))
+< 108 NULL
+< 109 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+< 110 NULL
+< SELECT fid, IsClosed(g) FROM gis_multi_line;
+< fid IsClosed(g)
+< 114 0
+< 115 0
+< 116 0
+< SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon;
+< fid AsText(Centroid(g))
+< 117 POINT(55.58852775304245 17.426536064113982)
+< 118 POINT(55.58852775304245 17.426536064113982)
+< 119 POINT(2 2)
+< SELECT fid, Area(g) FROM gis_multi_polygon;
+< fid Area(g)
+< 117 1684.5
+< 118 1684.5
+< 119 4.5
+< SELECT fid, NumGeometries(g) from gis_multi_point;
+< fid NumGeometries(g)
+< 111 4
+< 112 4
+< 113 2
+< SELECT fid, NumGeometries(g) from gis_multi_line;
+< fid NumGeometries(g)
+< 114 2
+< 115 1
+< 116 2
+< SELECT fid, NumGeometries(g) from gis_multi_polygon;
+< fid NumGeometries(g)
+< 117 2
+< 118 2
+< 119 1
+< SELECT fid, NumGeometries(g) from gis_geometrycollection;
+< fid NumGeometries(g)
+< 120 2
+< 121 2
+< 122 0
+< 123 0
+< SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point;
+< fid AsText(GeometryN(g, 2))
+< 111 POINT(10 10)
+< 112 POINT(11 11)
+< 113 POINT(4 10)
+< SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_line;
+< fid AsText(GeometryN(g, 2))
+< 114 LINESTRING(16 0,16 23,16 48)
+< 115 NULL
+< 116 LINESTRING(2 5,5 8,21 7)
+< SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_polygon;
+< fid AsText(GeometryN(g, 2))
+< 117 POLYGON((59 18,67 18,67 13,59 13,59 18))
+< 118 POLYGON((59 18,67 18,67 13,59 13,59 18))
+< 119 NULL
+< SELECT fid, AsText(GeometryN(g, 2)) from gis_geometrycollection;
+< fid AsText(GeometryN(g, 2))
+< 120 LINESTRING(0 0,10 10)
+< 121 LINESTRING(3 6,7 9)
+< 122 NULL
+< 123 NULL
+< SELECT fid, AsText(GeometryN(g, 1)) from gis_geometrycollection;
+< fid AsText(GeometryN(g, 1))
+< 120 POINT(0 0)
+< 121 POINT(44 6)
+< 122 NULL
+< 123 NULL
+< SELECT g1.fid as first, g2.fid as second,
+< Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o,
+< Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
+< Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r
+< FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
+< first second w c o e d t i r
+< 120 120 1 1 0 1 0 1 1 0
+< 120 121 0 0 1 0 0 0 1 0
+< 120 122 0 1 NULL 0 NULL 0 NULL 0
+< 120 123 0 1 NULL 0 NULL 0 NULL 0
+< 121 120 0 0 1 0 0 0 1 0
+< 121 121 1 1 0 1 0 1 1 0
+< 121 122 0 1 NULL 0 NULL 0 NULL 0
+< 121 123 0 1 NULL 0 NULL 0 NULL 0
+< 122 120 1 0 NULL 0 NULL 0 NULL 0
+< 122 121 1 0 NULL 0 NULL 0 NULL 0
+< 122 122 1 1 NULL 1 NULL 0 NULL 0
+< 122 123 1 1 NULL 1 NULL 0 NULL 0
+< 123 120 1 0 NULL 0 NULL 0 NULL 0
+< 123 121 1 0 NULL 0 NULL 0 NULL 0
+< 123 122 1 1 NULL 1 NULL 0 NULL 0
+< 123 123 1 1 NULL 1 NULL 0 NULL 0
+< DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
+< USE gis_ogs;
+< # Lakes
+< INSERT INTO lakes VALUES (
+< 101, 'BLUE LAKE',
+< PolyFromText(
+< 'POLYGON(
+< (52 18,66 23,73 9,48 6,52 18),
+< (59 18,67 18,67 13,59 13,59 18)
+< )',
+< 101));
+< # Road Segments
+< INSERT INTO road_segments VALUES(102, 'Route 5', NULL, 2,
+< LineFromText(
+< 'LINESTRING( 0 18, 10 21, 16 23, 28 26, 44 31 )' ,101));
+< INSERT INTO road_segments VALUES(103, 'Route 5', 'Main Street', 4,
+< LineFromText(
+< 'LINESTRING( 44 31, 56 34, 70 38 )' ,101));
+< INSERT INTO road_segments VALUES(104, 'Route 5', NULL, 2,
+< LineFromText(
+< 'LINESTRING( 70 38, 72 48 )' ,101));
+< INSERT INTO road_segments VALUES(105, 'Main Street', NULL, 4,
+< LineFromText(
+< 'LINESTRING( 70 38, 84 42 )' ,101));
+< INSERT INTO road_segments VALUES(106, 'Dirt Road by Green Forest', NULL,
+< 1,
+< LineFromText(
+< 'LINESTRING( 28 26, 28 0 )',101));
+< # DividedRoutes
+< INSERT INTO divided_routes VALUES(119, 'Route 75', 4,
+< MLineFromText(
+< 'MULTILINESTRING((10 48,10 21,10 0),
+< (16 0,16 23,16 48))', 101));
+< # Forests
+< INSERT INTO forests VALUES(109, 'Green Forest',
+< MPolyFromText(
+< 'MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),
+< (52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))',
+< 101));
+< # Bridges
+< INSERT INTO bridges VALUES(110, 'Cam Bridge', PointFromText(
+< 'POINT( 44 31 )', 101));
+< # Streams
+< INSERT INTO streams VALUES(111, 'Cam Stream',
+< LineFromText(
+< 'LINESTRING( 38 48, 44 41, 41 36, 44 31, 52 18 )', 101));
+< INSERT INTO streams VALUES(112, NULL,
+< LineFromText(
+< 'LINESTRING( 76 0, 78 4, 73 9 )', 101));
+< # Buildings
+< INSERT INTO buildings VALUES(113, '123 Main Street',
+< PointFromText(
+< 'POINT( 52 30 )', 101),
+< PolyFromText(
+< 'POLYGON( ( 50 31, 54 31, 54 29, 50 29, 50 31) )', 101));
+< INSERT INTO buildings VALUES(114, '215 Main Street',
+< PointFromText(
+< 'POINT( 64 33 )', 101),
+< PolyFromText(
+< 'POLYGON( ( 66 34, 62 34, 62 32, 66 32, 66 34) )', 101));
+< # Ponds
+< INSERT INTO ponds VALUES(120, NULL, 'Stock Pond',
+< MPolyFromText(
+< 'MULTIPOLYGON( ( ( 24 44, 22 42, 24 40, 24 44) ),
+< ( ( 26 44, 26 40, 28 42, 26 44) ) )', 101));
+< # Named Places
+< INSERT INTO named_places VALUES(117, 'Ashton',
+< PolyFromText(
+< 'POLYGON( ( 62 48, 84 48, 84 30, 56 30, 56 34, 62 48) )', 101));
+< INSERT INTO named_places VALUES(118, 'Goose Island',
+< PolyFromText(
+< 'POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )', 101));
+< # Map Neatlines
+< INSERT INTO map_neatlines VALUES(115,
+< PolyFromText(
+< 'POLYGON( ( 0 0, 0 48, 84 48, 84 0, 0 0 ) )', 101));
+< SELECT Dimension(shore)
+< FROM lakes
+< WHERE name = 'Blue Lake';
+< Dimension(shore)
+< 2
+< SELECT GeometryType(centerlines)
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< GeometryType(centerlines)
+< MULTILINESTRING
+< SELECT AsText(boundary)
+< FROM named_places
+< WHERE name = 'Goose Island';
+< AsText(boundary)
+< POLYGON((67 13,67 18,59 18,59 13,67 13))
+< SELECT AsText(PolyFromWKB(AsBinary(boundary),101))
+< FROM named_places
+< WHERE name = 'Goose Island';
+< AsText(PolyFromWKB(AsBinary(boundary),101))
+< POLYGON((67 13,67 18,59 18,59 13,67 13))
+< SELECT SRID(boundary)
+< FROM named_places
+< WHERE name = 'Goose Island';
+< SRID(boundary)
+< 101
+< SELECT IsEmpty(centerline)
+< FROM road_segments
+< WHERE name = 'Route 5'
+< AND aliases = 'Main Street';
+< IsEmpty(centerline)
+< 0
+< SELECT AsText(Envelope(boundary))
+< FROM named_places
+< WHERE name = 'Goose Island';
+< AsText(Envelope(boundary))
+< POLYGON((59 13,67 13,67 18,59 18,59 13))
+< SELECT X(position)
+< FROM bridges
+< WHERE name = 'Cam Bridge';
+< X(position)
+< 44
+< SELECT Y(position)
+< FROM bridges
+< WHERE name = 'Cam Bridge';
+< Y(position)
+< 31
+< SELECT AsText(StartPoint(centerline))
+< FROM road_segments
+< WHERE fid = 102;
+< AsText(StartPoint(centerline))
+< POINT(0 18)
+< SELECT AsText(EndPoint(centerline))
+< FROM road_segments
+< WHERE fid = 102;
+< AsText(EndPoint(centerline))
+< POINT(44 31)
+< SELECT GLength(centerline)
+< FROM road_segments
+< WHERE fid = 106;
+< GLength(centerline)
+< 26
+< SELECT NumPoints(centerline)
+< FROM road_segments
+< WHERE fid = 102;
+< NumPoints(centerline)
+< 5
+< SELECT AsText(PointN(centerline, 1))
+< FROM road_segments
+< WHERE fid = 102;
+< AsText(PointN(centerline, 1))
+< POINT(0 18)
+< SELECT AsText(Centroid(boundary))
+< FROM named_places
+< WHERE name = 'Goose Island';
+< AsText(Centroid(boundary))
+< POINT(63 15.5)
+< SELECT Area(boundary)
+< FROM named_places
+< WHERE name = 'Goose Island';
+< Area(boundary)
+< 40
+< SELECT AsText(ExteriorRing(shore))
+< FROM lakes
+< WHERE name = 'Blue Lake';
+< AsText(ExteriorRing(shore))
+< LINESTRING(52 18,66 23,73 9,48 6,52 18)
+< SELECT NumInteriorRings(shore)
+< FROM lakes
+< WHERE name = 'Blue Lake';
+< NumInteriorRings(shore)
+< 1
+< SELECT AsText(InteriorRingN(shore, 1))
+< FROM lakes
+< WHERE name = 'Blue Lake';
+< AsText(InteriorRingN(shore, 1))
+< LINESTRING(59 18,67 18,67 13,59 13,59 18)
+< SELECT NumGeometries(centerlines)
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< NumGeometries(centerlines)
+< 2
+< SELECT AsText(GeometryN(centerlines, 2))
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< AsText(GeometryN(centerlines, 2))
+< LINESTRING(16 0,16 23,16 48)
+< SELECT IsClosed(centerlines)
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< IsClosed(centerlines)
+< 0
+< SELECT GLength(centerlines)
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< GLength(centerlines)
+< 96
+< SELECT AsText(Centroid(shores))
+< FROM ponds
+< WHERE fid = 120;
+< AsText(Centroid(shores))
+< POINT(25 42)
+< SELECT Area(shores)
+< FROM ponds
+< WHERE fid = 120;
+< Area(shores)
+< 8
+< SELECT ST_Equals(boundary,
+< PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1))
+< FROM named_places
+< WHERE name = 'Goose Island';
+< ST_Equals(boundary,
+< PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1))
+< 1
+< SELECT ST_Disjoint(centerlines, boundary)
+< FROM divided_routes, named_places
+< WHERE divided_routes.name = 'Route 75'
+< AND named_places.name = 'Ashton';
+< ST_Disjoint(centerlines, boundary)
+< 1
+< SELECT ST_Touches(centerline, shore)
+< FROM streams, lakes
+< WHERE streams.name = 'Cam Stream'
+< AND lakes.name = 'Blue Lake';
+< ST_Touches(centerline, shore)
+< 1
+< SELECT Crosses(road_segments.centerline, divided_routes.centerlines)
+< FROM road_segments, divided_routes
+< WHERE road_segments.fid = 102
+< AND divided_routes.name = 'Route 75';
+< Crosses(road_segments.centerline, divided_routes.centerlines)
+< 1
+< SELECT ST_Intersects(road_segments.centerline, divided_routes.centerlines)
+< FROM road_segments, divided_routes
+< WHERE road_segments.fid = 102
+< AND divided_routes.name = 'Route 75';
+< ST_Intersects(road_segments.centerline, divided_routes.centerlines)
+< 1
+< SELECT ST_Contains(forests.boundary, named_places.boundary)
+< FROM forests, named_places
+< WHERE forests.name = 'Green Forest'
+< AND named_places.name = 'Ashton';
+< ST_Contains(forests.boundary, named_places.boundary)
+< 0
+< SELECT ST_Distance(position, boundary)
+< FROM bridges, named_places
+< WHERE bridges.name = 'Cam Bridge'
+< AND named_places.name = 'Ashton';
+< ST_Distance(position, boundary)
+< 12
+< SELECT AsText(ST_Difference(named_places.boundary, forests.boundary))
+< FROM named_places, forests
+< WHERE named_places.name = 'Ashton'
+< AND forests.name = 'Green Forest';
+< AsText(ST_Difference(named_places.boundary, forests.boundary))
+< POLYGON((56 34,62 48,84 48,84 42,56 34))
+< SELECT AsText(ST_Union(shore, boundary))
+< FROM lakes, named_places
+< WHERE lakes.name = 'Blue Lake'
+< AND named_places.name = 'Goose Island';
+< AsText(ST_Union(shore, boundary))
+< POLYGON((48 6,52 18,66 23,73 9,48 6))
+< SELECT AsText(ST_SymDifference(shore, boundary))
+< FROM lakes, named_places
+< WHERE lakes.name = 'Blue Lake'
+< AND named_places.name = 'Ashton';
+< AsText(ST_SymDifference(shore, boundary))
+< MULTIPOLYGON(((48 6,52 18,66 23,73 9,48 6),(59 13,59 18,67 18,67 13,59 13)),((56 30,56 34,62 48,84 48,84 30,56 30)))
+< SELECT count(*)
+< FROM buildings, bridges
+< WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1;
+< count(*)
+< 1
+---
+> ERROR 42000: The storage engine for the table doesn't support GEOMETRY
+> # ERROR: Statement ended with errno 1178, errname ER_CHECK_NOT_IMPLEMENTED (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE gis_point (fid INT(11) /*!*/ /*Custom column options*/, g POINT) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.gis_point) INSERT_METHOD=LAST ]
+> # The statement|command finished with ER_CHECK_NOT_IMPLEMENTED.
+> # Geometry types or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
diff --git a/storage/myisammrg/mysql-test/storage_engine/type_spatial_indexes.rdiff b/storage/myisammrg/mysql-test/storage_engine/type_spatial_indexes.rdiff
new file mode 100644
index 00000000000..89f1100f550
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/type_spatial_indexes.rdiff
@@ -0,0 +1,1412 @@
+5,698c5,14
+< CREATE TABLE gis_line (fid <INT_COLUMN>, g LINESTRING, <CUSTOM_INDEX> g(g(256))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_polygon (fid <INT_COLUMN>, g POLYGON, <CUSTOM_INDEX> g(g(512))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_multi_point (fid <INT_COLUMN>, g MULTIPOINT, <CUSTOM_INDEX> g(g(128))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_multi_line (fid <INT_COLUMN>, g MULTILINESTRING, <CUSTOM_INDEX> g(g(256))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_multi_polygon (fid <INT_COLUMN>, g MULTIPOLYGON) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_geometrycollection (fid <INT_COLUMN>, g GEOMETRYCOLLECTION) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_geometry (fid <INT_COLUMN>, g GEOMETRY) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< USE gis_ogs;
+< CREATE TABLE lakes (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< shore POLYGON, <CUSTOM_INDEX> s(shore(64))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE road_segments (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< aliases CHAR(64) <CUSTOM_COL_OPTIONS>,
+< num_lanes INT <CUSTOM_COL_OPTIONS>,
+< centerline LINESTRING, <CUSTOM_INDEX> c(centerline(128))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE divided_routes (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< num_lanes INT <CUSTOM_COL_OPTIONS>,
+< centerlines MULTILINESTRING, <CUSTOM_INDEX> c(centerlines(512))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE forests (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< boundary MULTIPOLYGON, <CUSTOM_INDEX> b(boundary(128))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE bridges (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< position POINT, <CUSTOM_INDEX> p(`position`(64))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE streams (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< centerline LINESTRING, <CUSTOM_INDEX> c(centerline(256))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE buildings (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< position POINT,
+< footprint POLYGON, <CUSTOM_INDEX> p(`position`(64)), <CUSTOM_INDEX> f(footprint(128))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE ponds (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< type CHAR(64) <CUSTOM_COL_OPTIONS>,
+< shores MULTIPOLYGON, <CUSTOM_INDEX> s(shores(256))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE named_places (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< boundary POLYGON, <CUSTOM_INDEX> b(boundary(512))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE map_neatlines (fid INT <CUSTOM_COL_OPTIONS>,
+< neatline POLYGON, <CUSTOM_INDEX> n(neatline(700))) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< USE test;
+< SHOW FIELDS FROM gis_point;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g point YES MUL NULL
+< SHOW FIELDS FROM gis_line;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g linestring YES MUL NULL
+< SHOW FIELDS FROM gis_polygon;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g polygon YES MUL NULL
+< SHOW FIELDS FROM gis_multi_point;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g multipoint YES MUL NULL
+< SHOW FIELDS FROM gis_multi_line;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g multilinestring YES MUL NULL
+< SHOW FIELDS FROM gis_multi_polygon;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g multipolygon YES NULL
+< SHOW FIELDS FROM gis_geometrycollection;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g geometrycollection YES NULL
+< SHOW FIELDS FROM gis_geometry;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g geometry YES NULL
+< INSERT INTO gis_point VALUES
+< (101, PointFromText('POINT(10 10)')),
+< (102, PointFromText('POINT(20 10)')),
+< (103, PointFromText('POINT(20 20)')),
+< (104, PointFromWKB(AsWKB(PointFromText('POINT(10 20)'))));
+< INSERT INTO gis_line VALUES
+< (105, LineFromText('LINESTRING(0 0,0 10,10 0)')),
+< (106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
+< (107, LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));
+< INSERT INTO gis_polygon VALUES
+< (108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
+< (109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')),
+< (110, PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))));
+< INSERT INTO gis_multi_point VALUES
+< (111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
+< (112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
+< (113, MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));
+< INSERT INTO gis_multi_line VALUES
+< (114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),
+< (115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
+< (116, MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))));
+< INSERT INTO gis_multi_polygon VALUES
+< (117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
+< (118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
+< (119, MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));
+< INSERT INTO gis_geometrycollection VALUES
+< (120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
+< (121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))),
+< (122, GeomFromText('GeometryCollection()')),
+< (123, GeomFromText('GeometryCollection EMPTY'));
+< INSERT into gis_geometry SELECT * FROM gis_point;
+< INSERT into gis_geometry SELECT * FROM gis_line;
+< INSERT into gis_geometry SELECT * FROM gis_polygon;
+< INSERT into gis_geometry SELECT * FROM gis_multi_point;
+< INSERT into gis_geometry SELECT * FROM gis_multi_line;
+< INSERT into gis_geometry SELECT * FROM gis_multi_polygon;
+< INSERT into gis_geometry SELECT * FROM gis_geometrycollection;
+< SELECT fid, AsText(g) FROM gis_point;
+< fid AsText(g)
+< 101 POINT(10 10)
+< 102 POINT(20 10)
+< 103 POINT(20 20)
+< 104 POINT(10 20)
+< SELECT fid, AsText(g) FROM gis_line;
+< fid AsText(g)
+< 105 LINESTRING(0 0,0 10,10 0)
+< 106 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+< 107 LINESTRING(10 10,40 10)
+< SELECT fid, AsText(g) FROM gis_polygon;
+< fid AsText(g)
+< 108 POLYGON((10 10,20 10,20 20,10 20,10 10))
+< 109 POLYGON((0 0,50 0,50 50,0 50,0 0),(10 10,20 10,20 20,10 20,10 10))
+< 110 POLYGON((0 0,30 0,30 30,0 0))
+< SELECT fid, AsText(g) FROM gis_multi_point;
+< fid AsText(g)
+< 111 MULTIPOINT(0 0,10 10,10 20,20 20)
+< 112 MULTIPOINT(1 1,11 11,11 21,21 21)
+< 113 MULTIPOINT(3 6,4 10)
+< SELECT fid, AsText(g) FROM gis_multi_line;
+< fid AsText(g)
+< 114 MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))
+< 115 MULTILINESTRING((10 48,10 21,10 0))
+< 116 MULTILINESTRING((1 2,3 5),(2 5,5 8,21 7))
+< SELECT fid, AsText(g) FROM gis_multi_polygon;
+< fid AsText(g)
+< 117 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+< 118 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+< 119 MULTIPOLYGON(((0 3,3 3,3 0,0 3)))
+< SELECT fid, AsText(g) FROM gis_geometrycollection;
+< fid AsText(g)
+< 120 GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,10 10))
+< 121 GEOMETRYCOLLECTION(POINT(44 6),LINESTRING(3 6,7 9))
+< 122 GEOMETRYCOLLECTION EMPTY
+< 123 GEOMETRYCOLLECTION EMPTY
+< SELECT fid, AsText(g) FROM gis_geometry;
+< fid AsText(g)
+< 101 POINT(10 10)
+< 102 POINT(20 10)
+< 103 POINT(20 20)
+< 104 POINT(10 20)
+< 105 LINESTRING(0 0,0 10,10 0)
+< 106 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+< 107 LINESTRING(10 10,40 10)
+< 108 POLYGON((10 10,20 10,20 20,10 20,10 10))
+< 109 POLYGON((0 0,50 0,50 50,0 50,0 0),(10 10,20 10,20 20,10 20,10 10))
+< 110 POLYGON((0 0,30 0,30 30,0 0))
+< 111 MULTIPOINT(0 0,10 10,10 20,20 20)
+< 112 MULTIPOINT(1 1,11 11,11 21,21 21)
+< 113 MULTIPOINT(3 6,4 10)
+< 114 MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))
+< 115 MULTILINESTRING((10 48,10 21,10 0))
+< 116 MULTILINESTRING((1 2,3 5),(2 5,5 8,21 7))
+< 117 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+< 118 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+< 119 MULTIPOLYGON(((0 3,3 3,3 0,0 3)))
+< 120 GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,10 10))
+< 121 GEOMETRYCOLLECTION(POINT(44 6),LINESTRING(3 6,7 9))
+< 122 GEOMETRYCOLLECTION EMPTY
+< 123 GEOMETRYCOLLECTION EMPTY
+< SELECT fid, Dimension(g) FROM gis_geometry;
+< fid Dimension(g)
+< 101 0
+< 102 0
+< 103 0
+< 104 0
+< 105 1
+< 106 1
+< 107 1
+< 108 2
+< 109 2
+< 110 2
+< 111 0
+< 112 0
+< 113 0
+< 114 1
+< 115 1
+< 116 1
+< 117 2
+< 118 2
+< 119 2
+< 120 1
+< 121 1
+< 122 0
+< 123 0
+< SELECT fid, GeometryType(g) FROM gis_geometry;
+< fid GeometryType(g)
+< 101 POINT
+< 102 POINT
+< 103 POINT
+< 104 POINT
+< 105 LINESTRING
+< 106 LINESTRING
+< 107 LINESTRING
+< 108 POLYGON
+< 109 POLYGON
+< 110 POLYGON
+< 111 MULTIPOINT
+< 112 MULTIPOINT
+< 113 MULTIPOINT
+< 114 MULTILINESTRING
+< 115 MULTILINESTRING
+< 116 MULTILINESTRING
+< 117 MULTIPOLYGON
+< 118 MULTIPOLYGON
+< 119 MULTIPOLYGON
+< 120 GEOMETRYCOLLECTION
+< 121 GEOMETRYCOLLECTION
+< 122 GEOMETRYCOLLECTION
+< 123 GEOMETRYCOLLECTION
+< SELECT fid, IsEmpty(g) FROM gis_geometry;
+< fid IsEmpty(g)
+< 101 0
+< 102 0
+< 103 0
+< 104 0
+< 105 0
+< 106 0
+< 107 0
+< 108 0
+< 109 0
+< 110 0
+< 111 0
+< 112 0
+< 113 0
+< 114 0
+< 115 0
+< 116 0
+< 117 0
+< 118 0
+< 119 0
+< 120 0
+< 121 0
+< 122 0
+< 123 0
+< SELECT fid, AsText(Envelope(g)) FROM gis_geometry;
+< fid AsText(Envelope(g))
+< 101 POLYGON((10 10,10 10,10 10,10 10,10 10))
+< 102 POLYGON((20 10,20 10,20 10,20 10,20 10))
+< 103 POLYGON((20 20,20 20,20 20,20 20,20 20))
+< 104 POLYGON((10 20,10 20,10 20,10 20,10 20))
+< 105 POLYGON((0 0,10 0,10 10,0 10,0 0))
+< 106 POLYGON((10 10,20 10,20 20,10 20,10 10))
+< 107 POLYGON((10 10,40 10,40 10,10 10,10 10))
+< 108 POLYGON((10 10,20 10,20 20,10 20,10 10))
+< 109 POLYGON((0 0,50 0,50 50,0 50,0 0))
+< 110 POLYGON((0 0,30 0,30 30,0 30,0 0))
+< 111 POLYGON((0 0,20 0,20 20,0 20,0 0))
+< 112 POLYGON((1 1,21 1,21 21,1 21,1 1))
+< 113 POLYGON((3 6,4 6,4 10,3 10,3 6))
+< 114 POLYGON((10 0,16 0,16 48,10 48,10 0))
+< 115 POLYGON((10 0,10 0,10 48,10 48,10 0))
+< 116 POLYGON((1 2,21 2,21 8,1 8,1 2))
+< 117 POLYGON((28 0,84 0,84 42,28 42,28 0))
+< 118 POLYGON((28 0,84 0,84 42,28 42,28 0))
+< 119 POLYGON((0 0,3 0,3 3,0 3,0 0))
+< 120 POLYGON((0 0,10 0,10 10,0 10,0 0))
+< 121 POLYGON((3 6,44 6,44 9,3 9,3 6))
+< 122 GEOMETRYCOLLECTION EMPTY
+< 123 GEOMETRYCOLLECTION EMPTY
+< SELECT fid, X(g) FROM gis_point;
+< fid X(g)
+< 101 10
+< 102 20
+< 103 20
+< 104 10
+< SELECT fid, Y(g) FROM gis_point;
+< fid Y(g)
+< 101 10
+< 102 10
+< 103 20
+< 104 20
+< SELECT fid, AsText(StartPoint(g)) FROM gis_line;
+< fid AsText(StartPoint(g))
+< 105 POINT(0 0)
+< 106 POINT(10 10)
+< 107 POINT(10 10)
+< SELECT fid, AsText(EndPoint(g)) FROM gis_line;
+< fid AsText(EndPoint(g))
+< 105 POINT(10 0)
+< 106 POINT(10 10)
+< 107 POINT(40 10)
+< SELECT fid, GLength(g) FROM gis_line;
+< fid GLength(g)
+< 105 24.14213562373095
+< 106 40
+< 107 30
+< SELECT fid, NumPoints(g) FROM gis_line;
+< fid NumPoints(g)
+< 105 3
+< 106 5
+< 107 2
+< SELECT fid, AsText(PointN(g, 2)) FROM gis_line;
+< fid AsText(PointN(g, 2))
+< 105 POINT(0 10)
+< 106 POINT(20 10)
+< 107 POINT(40 10)
+< SELECT fid, IsClosed(g) FROM gis_line;
+< fid IsClosed(g)
+< 105 0
+< 106 1
+< 107 0
+< SELECT fid, AsText(Centroid(g)) FROM gis_polygon;
+< fid AsText(Centroid(g))
+< 108 POINT(15 15)
+< 109 POINT(25.416666666666668 25.416666666666668)
+< 110 POINT(20 10)
+< SELECT fid, Area(g) FROM gis_polygon;
+< fid Area(g)
+< 108 100
+< 109 2400
+< 110 450
+< SELECT fid, AsText(ExteriorRing(g)) FROM gis_polygon;
+< fid AsText(ExteriorRing(g))
+< 108 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+< 109 LINESTRING(0 0,50 0,50 50,0 50,0 0)
+< 110 LINESTRING(0 0,30 0,30 30,0 0)
+< SELECT fid, NumInteriorRings(g) FROM gis_polygon;
+< fid NumInteriorRings(g)
+< 108 0
+< 109 1
+< 110 0
+< SELECT fid, AsText(InteriorRingN(g, 1)) FROM gis_polygon;
+< fid AsText(InteriorRingN(g, 1))
+< 108 NULL
+< 109 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+< 110 NULL
+< SELECT fid, IsClosed(g) FROM gis_multi_line;
+< fid IsClosed(g)
+< 114 0
+< 115 0
+< 116 0
+< SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon;
+< fid AsText(Centroid(g))
+< 117 POINT(55.58852775304245 17.426536064113982)
+< 118 POINT(55.58852775304245 17.426536064113982)
+< 119 POINT(2 2)
+< SELECT fid, Area(g) FROM gis_multi_polygon;
+< fid Area(g)
+< 117 1684.5
+< 118 1684.5
+< 119 4.5
+< SELECT fid, NumGeometries(g) from gis_multi_point;
+< fid NumGeometries(g)
+< 111 4
+< 112 4
+< 113 2
+< SELECT fid, NumGeometries(g) from gis_multi_line;
+< fid NumGeometries(g)
+< 114 2
+< 115 1
+< 116 2
+< SELECT fid, NumGeometries(g) from gis_multi_polygon;
+< fid NumGeometries(g)
+< 117 2
+< 118 2
+< 119 1
+< SELECT fid, NumGeometries(g) from gis_geometrycollection;
+< fid NumGeometries(g)
+< 120 2
+< 121 2
+< 122 0
+< 123 0
+< SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point;
+< fid AsText(GeometryN(g, 2))
+< 111 POINT(10 10)
+< 112 POINT(11 11)
+< 113 POINT(4 10)
+< SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_line;
+< fid AsText(GeometryN(g, 2))
+< 114 LINESTRING(16 0,16 23,16 48)
+< 115 NULL
+< 116 LINESTRING(2 5,5 8,21 7)
+< SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_polygon;
+< fid AsText(GeometryN(g, 2))
+< 117 POLYGON((59 18,67 18,67 13,59 13,59 18))
+< 118 POLYGON((59 18,67 18,67 13,59 13,59 18))
+< 119 NULL
+< SELECT fid, AsText(GeometryN(g, 2)) from gis_geometrycollection;
+< fid AsText(GeometryN(g, 2))
+< 120 LINESTRING(0 0,10 10)
+< 121 LINESTRING(3 6,7 9)
+< 122 NULL
+< 123 NULL
+< SELECT fid, AsText(GeometryN(g, 1)) from gis_geometrycollection;
+< fid AsText(GeometryN(g, 1))
+< 120 POINT(0 0)
+< 121 POINT(44 6)
+< 122 NULL
+< 123 NULL
+< SELECT g1.fid as first, g2.fid as second,
+< Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o,
+< Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
+< Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r
+< FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
+< first second w c o e d t i r
+< 120 120 1 1 0 1 0 1 1 0
+< 120 121 0 0 1 0 0 0 1 0
+< 120 122 0 1 NULL 0 NULL 0 NULL 0
+< 120 123 0 1 NULL 0 NULL 0 NULL 0
+< 121 120 0 0 1 0 0 0 1 0
+< 121 121 1 1 0 1 0 1 1 0
+< 121 122 0 1 NULL 0 NULL 0 NULL 0
+< 121 123 0 1 NULL 0 NULL 0 NULL 0
+< 122 120 1 0 NULL 0 NULL 0 NULL 0
+< 122 121 1 0 NULL 0 NULL 0 NULL 0
+< 122 122 1 1 NULL 1 NULL 0 NULL 0
+< 122 123 1 1 NULL 1 NULL 0 NULL 0
+< 123 120 1 0 NULL 0 NULL 0 NULL 0
+< 123 121 1 0 NULL 0 NULL 0 NULL 0
+< 123 122 1 1 NULL 1 NULL 0 NULL 0
+< 123 123 1 1 NULL 1 NULL 0 NULL 0
+< DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
+< USE gis_ogs;
+< # Lakes
+< INSERT INTO lakes VALUES (
+< 101, 'BLUE LAKE',
+< PolyFromText(
+< 'POLYGON(
+< (52 18,66 23,73 9,48 6,52 18),
+< (59 18,67 18,67 13,59 13,59 18)
+< )',
+< 101));
+< # Road Segments
+< INSERT INTO road_segments VALUES(102, 'Route 5', NULL, 2,
+< LineFromText(
+< 'LINESTRING( 0 18, 10 21, 16 23, 28 26, 44 31 )' ,101));
+< INSERT INTO road_segments VALUES(103, 'Route 5', 'Main Street', 4,
+< LineFromText(
+< 'LINESTRING( 44 31, 56 34, 70 38 )' ,101));
+< INSERT INTO road_segments VALUES(104, 'Route 5', NULL, 2,
+< LineFromText(
+< 'LINESTRING( 70 38, 72 48 )' ,101));
+< INSERT INTO road_segments VALUES(105, 'Main Street', NULL, 4,
+< LineFromText(
+< 'LINESTRING( 70 38, 84 42 )' ,101));
+< INSERT INTO road_segments VALUES(106, 'Dirt Road by Green Forest', NULL,
+< 1,
+< LineFromText(
+< 'LINESTRING( 28 26, 28 0 )',101));
+< # DividedRoutes
+< INSERT INTO divided_routes VALUES(119, 'Route 75', 4,
+< MLineFromText(
+< 'MULTILINESTRING((10 48,10 21,10 0),
+< (16 0,16 23,16 48))', 101));
+< # Forests
+< INSERT INTO forests VALUES(109, 'Green Forest',
+< MPolyFromText(
+< 'MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),
+< (52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))',
+< 101));
+< # Bridges
+< INSERT INTO bridges VALUES(110, 'Cam Bridge', PointFromText(
+< 'POINT( 44 31 )', 101));
+< # Streams
+< INSERT INTO streams VALUES(111, 'Cam Stream',
+< LineFromText(
+< 'LINESTRING( 38 48, 44 41, 41 36, 44 31, 52 18 )', 101));
+< INSERT INTO streams VALUES(112, NULL,
+< LineFromText(
+< 'LINESTRING( 76 0, 78 4, 73 9 )', 101));
+< # Buildings
+< INSERT INTO buildings VALUES(113, '123 Main Street',
+< PointFromText(
+< 'POINT( 52 30 )', 101),
+< PolyFromText(
+< 'POLYGON( ( 50 31, 54 31, 54 29, 50 29, 50 31) )', 101));
+< INSERT INTO buildings VALUES(114, '215 Main Street',
+< PointFromText(
+< 'POINT( 64 33 )', 101),
+< PolyFromText(
+< 'POLYGON( ( 66 34, 62 34, 62 32, 66 32, 66 34) )', 101));
+< # Ponds
+< INSERT INTO ponds VALUES(120, NULL, 'Stock Pond',
+< MPolyFromText(
+< 'MULTIPOLYGON( ( ( 24 44, 22 42, 24 40, 24 44) ),
+< ( ( 26 44, 26 40, 28 42, 26 44) ) )', 101));
+< # Named Places
+< INSERT INTO named_places VALUES(117, 'Ashton',
+< PolyFromText(
+< 'POLYGON( ( 62 48, 84 48, 84 30, 56 30, 56 34, 62 48) )', 101));
+< INSERT INTO named_places VALUES(118, 'Goose Island',
+< PolyFromText(
+< 'POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )', 101));
+< # Map Neatlines
+< INSERT INTO map_neatlines VALUES(115,
+< PolyFromText(
+< 'POLYGON( ( 0 0, 0 48, 84 48, 84 0, 0 0 ) )', 101));
+< SELECT Dimension(shore)
+< FROM lakes
+< WHERE name = 'Blue Lake';
+< Dimension(shore)
+< 2
+< SELECT GeometryType(centerlines)
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< GeometryType(centerlines)
+< MULTILINESTRING
+< SELECT AsText(boundary)
+< FROM named_places
+< WHERE name = 'Goose Island';
+< AsText(boundary)
+< POLYGON((67 13,67 18,59 18,59 13,67 13))
+< SELECT AsText(PolyFromWKB(AsBinary(boundary),101))
+< FROM named_places
+< WHERE name = 'Goose Island';
+< AsText(PolyFromWKB(AsBinary(boundary),101))
+< POLYGON((67 13,67 18,59 18,59 13,67 13))
+< SELECT SRID(boundary)
+< FROM named_places
+< WHERE name = 'Goose Island';
+< SRID(boundary)
+< 101
+< SELECT IsEmpty(centerline)
+< FROM road_segments
+< WHERE name = 'Route 5'
+< AND aliases = 'Main Street';
+< IsEmpty(centerline)
+< 0
+< SELECT AsText(Envelope(boundary))
+< FROM named_places
+< WHERE name = 'Goose Island';
+< AsText(Envelope(boundary))
+< POLYGON((59 13,67 13,67 18,59 18,59 13))
+< SELECT X(position)
+< FROM bridges
+< WHERE name = 'Cam Bridge';
+< X(position)
+< 44
+< SELECT Y(position)
+< FROM bridges
+< WHERE name = 'Cam Bridge';
+< Y(position)
+< 31
+< SELECT AsText(StartPoint(centerline))
+< FROM road_segments
+< WHERE fid = 102;
+< AsText(StartPoint(centerline))
+< POINT(0 18)
+< SELECT AsText(EndPoint(centerline))
+< FROM road_segments
+< WHERE fid = 102;
+< AsText(EndPoint(centerline))
+< POINT(44 31)
+< SELECT GLength(centerline)
+< FROM road_segments
+< WHERE fid = 106;
+< GLength(centerline)
+< 26
+< SELECT NumPoints(centerline)
+< FROM road_segments
+< WHERE fid = 102;
+< NumPoints(centerline)
+< 5
+< SELECT AsText(PointN(centerline, 1))
+< FROM road_segments
+< WHERE fid = 102;
+< AsText(PointN(centerline, 1))
+< POINT(0 18)
+< SELECT AsText(Centroid(boundary))
+< FROM named_places
+< WHERE name = 'Goose Island';
+< AsText(Centroid(boundary))
+< POINT(63 15.5)
+< SELECT Area(boundary)
+< FROM named_places
+< WHERE name = 'Goose Island';
+< Area(boundary)
+< 40
+< SELECT AsText(ExteriorRing(shore))
+< FROM lakes
+< WHERE name = 'Blue Lake';
+< AsText(ExteriorRing(shore))
+< LINESTRING(52 18,66 23,73 9,48 6,52 18)
+< SELECT NumInteriorRings(shore)
+< FROM lakes
+< WHERE name = 'Blue Lake';
+< NumInteriorRings(shore)
+< 1
+< SELECT AsText(InteriorRingN(shore, 1))
+< FROM lakes
+< WHERE name = 'Blue Lake';
+< AsText(InteriorRingN(shore, 1))
+< LINESTRING(59 18,67 18,67 13,59 13,59 18)
+< SELECT NumGeometries(centerlines)
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< NumGeometries(centerlines)
+< 2
+< SELECT AsText(GeometryN(centerlines, 2))
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< AsText(GeometryN(centerlines, 2))
+< LINESTRING(16 0,16 23,16 48)
+< SELECT IsClosed(centerlines)
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< IsClosed(centerlines)
+< 0
+< SELECT GLength(centerlines)
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< GLength(centerlines)
+< 96
+< SELECT AsText(Centroid(shores))
+< FROM ponds
+< WHERE fid = 120;
+< AsText(Centroid(shores))
+< POINT(25 42)
+< SELECT Area(shores)
+< FROM ponds
+< WHERE fid = 120;
+< Area(shores)
+< 8
+< SELECT ST_Equals(boundary,
+< PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1))
+< FROM named_places
+< WHERE name = 'Goose Island';
+< ST_Equals(boundary,
+< PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1))
+< 1
+< SELECT ST_Disjoint(centerlines, boundary)
+< FROM divided_routes, named_places
+< WHERE divided_routes.name = 'Route 75'
+< AND named_places.name = 'Ashton';
+< ST_Disjoint(centerlines, boundary)
+< 1
+< SELECT ST_Touches(centerline, shore)
+< FROM streams, lakes
+< WHERE streams.name = 'Cam Stream'
+< AND lakes.name = 'Blue Lake';
+< ST_Touches(centerline, shore)
+< 1
+< SELECT Crosses(road_segments.centerline, divided_routes.centerlines)
+< FROM road_segments, divided_routes
+< WHERE road_segments.fid = 102
+< AND divided_routes.name = 'Route 75';
+< Crosses(road_segments.centerline, divided_routes.centerlines)
+< 1
+< SELECT ST_Intersects(road_segments.centerline, divided_routes.centerlines)
+< FROM road_segments, divided_routes
+< WHERE road_segments.fid = 102
+< AND divided_routes.name = 'Route 75';
+< ST_Intersects(road_segments.centerline, divided_routes.centerlines)
+< 1
+< SELECT ST_Contains(forests.boundary, named_places.boundary)
+< FROM forests, named_places
+< WHERE forests.name = 'Green Forest'
+< AND named_places.name = 'Ashton';
+< ST_Contains(forests.boundary, named_places.boundary)
+< 0
+< SELECT ST_Distance(position, boundary)
+< FROM bridges, named_places
+< WHERE bridges.name = 'Cam Bridge'
+< AND named_places.name = 'Ashton';
+< ST_Distance(position, boundary)
+< 12
+< SELECT AsText(ST_Difference(named_places.boundary, forests.boundary))
+< FROM named_places, forests
+< WHERE named_places.name = 'Ashton'
+< AND forests.name = 'Green Forest';
+< AsText(ST_Difference(named_places.boundary, forests.boundary))
+< POLYGON((56 34,62 48,84 48,84 42,56 34))
+< SELECT AsText(ST_Union(shore, boundary))
+< FROM lakes, named_places
+< WHERE lakes.name = 'Blue Lake'
+< AND named_places.name = 'Goose Island';
+< AsText(ST_Union(shore, boundary))
+< POLYGON((48 6,52 18,66 23,73 9,48 6))
+< SELECT AsText(ST_SymDifference(shore, boundary))
+< FROM lakes, named_places
+< WHERE lakes.name = 'Blue Lake'
+< AND named_places.name = 'Ashton';
+< AsText(ST_SymDifference(shore, boundary))
+< MULTIPOLYGON(((48 6,52 18,66 23,73 9,48 6),(59 13,59 18,67 18,67 13,59 13)),((56 30,56 34,62 48,84 48,84 30,56 30)))
+< SELECT count(*)
+< FROM buildings, bridges
+< WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1;
+< count(*)
+< 1
+---
+> ERROR 42000: The storage engine for the table doesn't support GEOMETRY
+> # ERROR: Statement ended with errno 1178, errname ER_CHECK_NOT_IMPLEMENTED (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE gis_point (fid INT(11) /*!*/ /*Custom column options*/, g POINT, /*!INDEX*/ /*Custom index*/ g(g(128))) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.gis_point) INSERT_METHOD=LAST ]
+> # The statement|command finished with ER_CHECK_NOT_IMPLEMENTED.
+> # Geometry types or indexes on them or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
+705,1398c21,30
+< CREATE TABLE gis_line (fid <INT_COLUMN>, g LINESTRING NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_polygon (fid <INT_COLUMN>, g POLYGON NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_multi_point (fid <INT_COLUMN>, g MULTIPOINT NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_multi_line (fid <INT_COLUMN>, g MULTILINESTRING NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_multi_polygon (fid <INT_COLUMN>, g MULTIPOLYGON NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_geometrycollection (fid <INT_COLUMN>, g GEOMETRYCOLLECTION NOT NULL, SPATIAL INDEX(g)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE gis_geometry (fid <INT_COLUMN>, g GEOMETRY NOT NULL) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< USE gis_ogs;
+< CREATE TABLE lakes (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< shore POLYGON NOT NULL, SPATIAL INDEX s(shore)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE road_segments (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< aliases CHAR(64) <CUSTOM_COL_OPTIONS>,
+< num_lanes INT <CUSTOM_COL_OPTIONS>,
+< centerline LINESTRING NOT NULL, SPATIAL INDEX c(centerline)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE divided_routes (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< num_lanes INT <CUSTOM_COL_OPTIONS>,
+< centerlines MULTILINESTRING NOT NULL, SPATIAL INDEX c(centerlines)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE forests (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< boundary MULTIPOLYGON NOT NULL, SPATIAL INDEX b(boundary)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE bridges (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< position POINT NOT NULL, SPATIAL INDEX p(position)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE streams (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< centerline LINESTRING NOT NULL, SPATIAL INDEX c(centerline)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE buildings (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< position POINT NOT NULL,
+< footprint POLYGON NOT NULL, SPATIAL INDEX p(position), SPATIAL INDEX f(footprint)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE ponds (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< type CHAR(64) <CUSTOM_COL_OPTIONS>,
+< shores MULTIPOLYGON NOT NULL, SPATIAL INDEX s(shores)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE named_places (fid INT <CUSTOM_COL_OPTIONS>,
+< name CHAR(64) <CUSTOM_COL_OPTIONS>,
+< boundary POLYGON NOT NULL, SPATIAL INDEX b(boundary)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< CREATE TABLE map_neatlines (fid INT <CUSTOM_COL_OPTIONS>,
+< neatline POLYGON NOT NULL, SPATIAL INDEX n(neatline)) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< USE test;
+< SHOW FIELDS FROM gis_point;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g point NO MUL NULL
+< SHOW FIELDS FROM gis_line;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g linestring NO MUL NULL
+< SHOW FIELDS FROM gis_polygon;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g polygon NO MUL NULL
+< SHOW FIELDS FROM gis_multi_point;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g multipoint NO MUL NULL
+< SHOW FIELDS FROM gis_multi_line;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g multilinestring NO MUL NULL
+< SHOW FIELDS FROM gis_multi_polygon;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g multipolygon NO MUL NULL
+< SHOW FIELDS FROM gis_geometrycollection;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g geometrycollection NO MUL NULL
+< SHOW FIELDS FROM gis_geometry;
+< Field Type Null Key Default Extra
+< fid int(11) YES NULL
+< g geometry NO NULL
+< INSERT INTO gis_point VALUES
+< (101, PointFromText('POINT(10 10)')),
+< (102, PointFromText('POINT(20 10)')),
+< (103, PointFromText('POINT(20 20)')),
+< (104, PointFromWKB(AsWKB(PointFromText('POINT(10 20)'))));
+< INSERT INTO gis_line VALUES
+< (105, LineFromText('LINESTRING(0 0,0 10,10 0)')),
+< (106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
+< (107, LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));
+< INSERT INTO gis_polygon VALUES
+< (108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
+< (109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')),
+< (110, PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))));
+< INSERT INTO gis_multi_point VALUES
+< (111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
+< (112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
+< (113, MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));
+< INSERT INTO gis_multi_line VALUES
+< (114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),
+< (115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
+< (116, MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))));
+< INSERT INTO gis_multi_polygon VALUES
+< (117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
+< (118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
+< (119, MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));
+< INSERT INTO gis_geometrycollection VALUES
+< (120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
+< (121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))))),
+< (122, GeomFromText('GeometryCollection()')),
+< (123, GeomFromText('GeometryCollection EMPTY'));
+< INSERT into gis_geometry SELECT * FROM gis_point;
+< INSERT into gis_geometry SELECT * FROM gis_line;
+< INSERT into gis_geometry SELECT * FROM gis_polygon;
+< INSERT into gis_geometry SELECT * FROM gis_multi_point;
+< INSERT into gis_geometry SELECT * FROM gis_multi_line;
+< INSERT into gis_geometry SELECT * FROM gis_multi_polygon;
+< INSERT into gis_geometry SELECT * FROM gis_geometrycollection;
+< SELECT fid, AsText(g) FROM gis_point;
+< fid AsText(g)
+< 101 POINT(10 10)
+< 102 POINT(20 10)
+< 103 POINT(20 20)
+< 104 POINT(10 20)
+< SELECT fid, AsText(g) FROM gis_line;
+< fid AsText(g)
+< 105 LINESTRING(0 0,0 10,10 0)
+< 106 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+< 107 LINESTRING(10 10,40 10)
+< SELECT fid, AsText(g) FROM gis_polygon;
+< fid AsText(g)
+< 108 POLYGON((10 10,20 10,20 20,10 20,10 10))
+< 109 POLYGON((0 0,50 0,50 50,0 50,0 0),(10 10,20 10,20 20,10 20,10 10))
+< 110 POLYGON((0 0,30 0,30 30,0 0))
+< SELECT fid, AsText(g) FROM gis_multi_point;
+< fid AsText(g)
+< 111 MULTIPOINT(0 0,10 10,10 20,20 20)
+< 112 MULTIPOINT(1 1,11 11,11 21,21 21)
+< 113 MULTIPOINT(3 6,4 10)
+< SELECT fid, AsText(g) FROM gis_multi_line;
+< fid AsText(g)
+< 114 MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))
+< 115 MULTILINESTRING((10 48,10 21,10 0))
+< 116 MULTILINESTRING((1 2,3 5),(2 5,5 8,21 7))
+< SELECT fid, AsText(g) FROM gis_multi_polygon;
+< fid AsText(g)
+< 117 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+< 118 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+< 119 MULTIPOLYGON(((0 3,3 3,3 0,0 3)))
+< SELECT fid, AsText(g) FROM gis_geometrycollection;
+< fid AsText(g)
+< 120 GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,10 10))
+< 121 GEOMETRYCOLLECTION(POINT(44 6),LINESTRING(3 6,7 9))
+< 122 GEOMETRYCOLLECTION EMPTY
+< 123 GEOMETRYCOLLECTION EMPTY
+< SELECT fid, AsText(g) FROM gis_geometry;
+< fid AsText(g)
+< 101 POINT(10 10)
+< 102 POINT(20 10)
+< 103 POINT(20 20)
+< 104 POINT(10 20)
+< 105 LINESTRING(0 0,0 10,10 0)
+< 106 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+< 107 LINESTRING(10 10,40 10)
+< 108 POLYGON((10 10,20 10,20 20,10 20,10 10))
+< 109 POLYGON((0 0,50 0,50 50,0 50,0 0),(10 10,20 10,20 20,10 20,10 10))
+< 110 POLYGON((0 0,30 0,30 30,0 0))
+< 111 MULTIPOINT(0 0,10 10,10 20,20 20)
+< 112 MULTIPOINT(1 1,11 11,11 21,21 21)
+< 113 MULTIPOINT(3 6,4 10)
+< 114 MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))
+< 115 MULTILINESTRING((10 48,10 21,10 0))
+< 116 MULTILINESTRING((1 2,3 5),(2 5,5 8,21 7))
+< 117 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+< 118 MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))
+< 119 MULTIPOLYGON(((0 3,3 3,3 0,0 3)))
+< 120 GEOMETRYCOLLECTION(POINT(0 0),LINESTRING(0 0,10 10))
+< 121 GEOMETRYCOLLECTION(POINT(44 6),LINESTRING(3 6,7 9))
+< 122 GEOMETRYCOLLECTION EMPTY
+< 123 GEOMETRYCOLLECTION EMPTY
+< SELECT fid, Dimension(g) FROM gis_geometry;
+< fid Dimension(g)
+< 101 0
+< 102 0
+< 103 0
+< 104 0
+< 105 1
+< 106 1
+< 107 1
+< 108 2
+< 109 2
+< 110 2
+< 111 0
+< 112 0
+< 113 0
+< 114 1
+< 115 1
+< 116 1
+< 117 2
+< 118 2
+< 119 2
+< 120 1
+< 121 1
+< 122 0
+< 123 0
+< SELECT fid, GeometryType(g) FROM gis_geometry;
+< fid GeometryType(g)
+< 101 POINT
+< 102 POINT
+< 103 POINT
+< 104 POINT
+< 105 LINESTRING
+< 106 LINESTRING
+< 107 LINESTRING
+< 108 POLYGON
+< 109 POLYGON
+< 110 POLYGON
+< 111 MULTIPOINT
+< 112 MULTIPOINT
+< 113 MULTIPOINT
+< 114 MULTILINESTRING
+< 115 MULTILINESTRING
+< 116 MULTILINESTRING
+< 117 MULTIPOLYGON
+< 118 MULTIPOLYGON
+< 119 MULTIPOLYGON
+< 120 GEOMETRYCOLLECTION
+< 121 GEOMETRYCOLLECTION
+< 122 GEOMETRYCOLLECTION
+< 123 GEOMETRYCOLLECTION
+< SELECT fid, IsEmpty(g) FROM gis_geometry;
+< fid IsEmpty(g)
+< 101 0
+< 102 0
+< 103 0
+< 104 0
+< 105 0
+< 106 0
+< 107 0
+< 108 0
+< 109 0
+< 110 0
+< 111 0
+< 112 0
+< 113 0
+< 114 0
+< 115 0
+< 116 0
+< 117 0
+< 118 0
+< 119 0
+< 120 0
+< 121 0
+< 122 0
+< 123 0
+< SELECT fid, AsText(Envelope(g)) FROM gis_geometry;
+< fid AsText(Envelope(g))
+< 101 POLYGON((10 10,10 10,10 10,10 10,10 10))
+< 102 POLYGON((20 10,20 10,20 10,20 10,20 10))
+< 103 POLYGON((20 20,20 20,20 20,20 20,20 20))
+< 104 POLYGON((10 20,10 20,10 20,10 20,10 20))
+< 105 POLYGON((0 0,10 0,10 10,0 10,0 0))
+< 106 POLYGON((10 10,20 10,20 20,10 20,10 10))
+< 107 POLYGON((10 10,40 10,40 10,10 10,10 10))
+< 108 POLYGON((10 10,20 10,20 20,10 20,10 10))
+< 109 POLYGON((0 0,50 0,50 50,0 50,0 0))
+< 110 POLYGON((0 0,30 0,30 30,0 30,0 0))
+< 111 POLYGON((0 0,20 0,20 20,0 20,0 0))
+< 112 POLYGON((1 1,21 1,21 21,1 21,1 1))
+< 113 POLYGON((3 6,4 6,4 10,3 10,3 6))
+< 114 POLYGON((10 0,16 0,16 48,10 48,10 0))
+< 115 POLYGON((10 0,10 0,10 48,10 48,10 0))
+< 116 POLYGON((1 2,21 2,21 8,1 8,1 2))
+< 117 POLYGON((28 0,84 0,84 42,28 42,28 0))
+< 118 POLYGON((28 0,84 0,84 42,28 42,28 0))
+< 119 POLYGON((0 0,3 0,3 3,0 3,0 0))
+< 120 POLYGON((0 0,10 0,10 10,0 10,0 0))
+< 121 POLYGON((3 6,44 6,44 9,3 9,3 6))
+< 122 GEOMETRYCOLLECTION EMPTY
+< 123 GEOMETRYCOLLECTION EMPTY
+< SELECT fid, X(g) FROM gis_point;
+< fid X(g)
+< 101 10
+< 102 20
+< 103 20
+< 104 10
+< SELECT fid, Y(g) FROM gis_point;
+< fid Y(g)
+< 101 10
+< 102 10
+< 103 20
+< 104 20
+< SELECT fid, AsText(StartPoint(g)) FROM gis_line;
+< fid AsText(StartPoint(g))
+< 105 POINT(0 0)
+< 106 POINT(10 10)
+< 107 POINT(10 10)
+< SELECT fid, AsText(EndPoint(g)) FROM gis_line;
+< fid AsText(EndPoint(g))
+< 105 POINT(10 0)
+< 106 POINT(10 10)
+< 107 POINT(40 10)
+< SELECT fid, GLength(g) FROM gis_line;
+< fid GLength(g)
+< 105 24.14213562373095
+< 106 40
+< 107 30
+< SELECT fid, NumPoints(g) FROM gis_line;
+< fid NumPoints(g)
+< 105 3
+< 106 5
+< 107 2
+< SELECT fid, AsText(PointN(g, 2)) FROM gis_line;
+< fid AsText(PointN(g, 2))
+< 105 POINT(0 10)
+< 106 POINT(20 10)
+< 107 POINT(40 10)
+< SELECT fid, IsClosed(g) FROM gis_line;
+< fid IsClosed(g)
+< 105 0
+< 106 1
+< 107 0
+< SELECT fid, AsText(Centroid(g)) FROM gis_polygon;
+< fid AsText(Centroid(g))
+< 108 POINT(15 15)
+< 109 POINT(25.416666666666668 25.416666666666668)
+< 110 POINT(20 10)
+< SELECT fid, Area(g) FROM gis_polygon;
+< fid Area(g)
+< 108 100
+< 109 2400
+< 110 450
+< SELECT fid, AsText(ExteriorRing(g)) FROM gis_polygon;
+< fid AsText(ExteriorRing(g))
+< 108 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+< 109 LINESTRING(0 0,50 0,50 50,0 50,0 0)
+< 110 LINESTRING(0 0,30 0,30 30,0 0)
+< SELECT fid, NumInteriorRings(g) FROM gis_polygon;
+< fid NumInteriorRings(g)
+< 108 0
+< 109 1
+< 110 0
+< SELECT fid, AsText(InteriorRingN(g, 1)) FROM gis_polygon;
+< fid AsText(InteriorRingN(g, 1))
+< 108 NULL
+< 109 LINESTRING(10 10,20 10,20 20,10 20,10 10)
+< 110 NULL
+< SELECT fid, IsClosed(g) FROM gis_multi_line;
+< fid IsClosed(g)
+< 114 0
+< 115 0
+< 116 0
+< SELECT fid, AsText(Centroid(g)) FROM gis_multi_polygon;
+< fid AsText(Centroid(g))
+< 117 POINT(55.58852775304245 17.426536064113982)
+< 118 POINT(55.58852775304245 17.426536064113982)
+< 119 POINT(2 2)
+< SELECT fid, Area(g) FROM gis_multi_polygon;
+< fid Area(g)
+< 117 1684.5
+< 118 1684.5
+< 119 4.5
+< SELECT fid, NumGeometries(g) from gis_multi_point;
+< fid NumGeometries(g)
+< 111 4
+< 112 4
+< 113 2
+< SELECT fid, NumGeometries(g) from gis_multi_line;
+< fid NumGeometries(g)
+< 114 2
+< 115 1
+< 116 2
+< SELECT fid, NumGeometries(g) from gis_multi_polygon;
+< fid NumGeometries(g)
+< 117 2
+< 118 2
+< 119 1
+< SELECT fid, NumGeometries(g) from gis_geometrycollection;
+< fid NumGeometries(g)
+< 120 2
+< 121 2
+< 122 0
+< 123 0
+< SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_point;
+< fid AsText(GeometryN(g, 2))
+< 111 POINT(10 10)
+< 112 POINT(11 11)
+< 113 POINT(4 10)
+< SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_line;
+< fid AsText(GeometryN(g, 2))
+< 114 LINESTRING(16 0,16 23,16 48)
+< 115 NULL
+< 116 LINESTRING(2 5,5 8,21 7)
+< SELECT fid, AsText(GeometryN(g, 2)) from gis_multi_polygon;
+< fid AsText(GeometryN(g, 2))
+< 117 POLYGON((59 18,67 18,67 13,59 13,59 18))
+< 118 POLYGON((59 18,67 18,67 13,59 13,59 18))
+< 119 NULL
+< SELECT fid, AsText(GeometryN(g, 2)) from gis_geometrycollection;
+< fid AsText(GeometryN(g, 2))
+< 120 LINESTRING(0 0,10 10)
+< 121 LINESTRING(3 6,7 9)
+< 122 NULL
+< 123 NULL
+< SELECT fid, AsText(GeometryN(g, 1)) from gis_geometrycollection;
+< fid AsText(GeometryN(g, 1))
+< 120 POINT(0 0)
+< 121 POINT(44 6)
+< 122 NULL
+< 123 NULL
+< SELECT g1.fid as first, g2.fid as second,
+< Within(g1.g, g2.g) as w, Contains(g1.g, g2.g) as c, Overlaps(g1.g, g2.g) as o,
+< Equals(g1.g, g2.g) as e, Disjoint(g1.g, g2.g) as d, Touches(g1.g, g2.g) as t,
+< Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r
+< FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second;
+< first second w c o e d t i r
+< 120 120 1 1 0 1 0 1 1 0
+< 120 121 0 0 1 0 0 0 1 0
+< 120 122 0 1 NULL 0 NULL 0 NULL 0
+< 120 123 0 1 NULL 0 NULL 0 NULL 0
+< 121 120 0 0 1 0 0 0 1 0
+< 121 121 1 1 0 1 0 1 1 0
+< 121 122 0 1 NULL 0 NULL 0 NULL 0
+< 121 123 0 1 NULL 0 NULL 0 NULL 0
+< 122 120 1 0 NULL 0 NULL 0 NULL 0
+< 122 121 1 0 NULL 0 NULL 0 NULL 0
+< 122 122 1 1 NULL 1 NULL 0 NULL 0
+< 122 123 1 1 NULL 1 NULL 0 NULL 0
+< 123 120 1 0 NULL 0 NULL 0 NULL 0
+< 123 121 1 0 NULL 0 NULL 0 NULL 0
+< 123 122 1 1 NULL 1 NULL 0 NULL 0
+< 123 123 1 1 NULL 1 NULL 0 NULL 0
+< DROP TABLE gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry;
+< USE gis_ogs;
+< # Lakes
+< INSERT INTO lakes VALUES (
+< 101, 'BLUE LAKE',
+< PolyFromText(
+< 'POLYGON(
+< (52 18,66 23,73 9,48 6,52 18),
+< (59 18,67 18,67 13,59 13,59 18)
+< )',
+< 101));
+< # Road Segments
+< INSERT INTO road_segments VALUES(102, 'Route 5', NULL, 2,
+< LineFromText(
+< 'LINESTRING( 0 18, 10 21, 16 23, 28 26, 44 31 )' ,101));
+< INSERT INTO road_segments VALUES(103, 'Route 5', 'Main Street', 4,
+< LineFromText(
+< 'LINESTRING( 44 31, 56 34, 70 38 )' ,101));
+< INSERT INTO road_segments VALUES(104, 'Route 5', NULL, 2,
+< LineFromText(
+< 'LINESTRING( 70 38, 72 48 )' ,101));
+< INSERT INTO road_segments VALUES(105, 'Main Street', NULL, 4,
+< LineFromText(
+< 'LINESTRING( 70 38, 84 42 )' ,101));
+< INSERT INTO road_segments VALUES(106, 'Dirt Road by Green Forest', NULL,
+< 1,
+< LineFromText(
+< 'LINESTRING( 28 26, 28 0 )',101));
+< # DividedRoutes
+< INSERT INTO divided_routes VALUES(119, 'Route 75', 4,
+< MLineFromText(
+< 'MULTILINESTRING((10 48,10 21,10 0),
+< (16 0,16 23,16 48))', 101));
+< # Forests
+< INSERT INTO forests VALUES(109, 'Green Forest',
+< MPolyFromText(
+< 'MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),
+< (52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))',
+< 101));
+< # Bridges
+< INSERT INTO bridges VALUES(110, 'Cam Bridge', PointFromText(
+< 'POINT( 44 31 )', 101));
+< # Streams
+< INSERT INTO streams VALUES(111, 'Cam Stream',
+< LineFromText(
+< 'LINESTRING( 38 48, 44 41, 41 36, 44 31, 52 18 )', 101));
+< INSERT INTO streams VALUES(112, NULL,
+< LineFromText(
+< 'LINESTRING( 76 0, 78 4, 73 9 )', 101));
+< # Buildings
+< INSERT INTO buildings VALUES(113, '123 Main Street',
+< PointFromText(
+< 'POINT( 52 30 )', 101),
+< PolyFromText(
+< 'POLYGON( ( 50 31, 54 31, 54 29, 50 29, 50 31) )', 101));
+< INSERT INTO buildings VALUES(114, '215 Main Street',
+< PointFromText(
+< 'POINT( 64 33 )', 101),
+< PolyFromText(
+< 'POLYGON( ( 66 34, 62 34, 62 32, 66 32, 66 34) )', 101));
+< # Ponds
+< INSERT INTO ponds VALUES(120, NULL, 'Stock Pond',
+< MPolyFromText(
+< 'MULTIPOLYGON( ( ( 24 44, 22 42, 24 40, 24 44) ),
+< ( ( 26 44, 26 40, 28 42, 26 44) ) )', 101));
+< # Named Places
+< INSERT INTO named_places VALUES(117, 'Ashton',
+< PolyFromText(
+< 'POLYGON( ( 62 48, 84 48, 84 30, 56 30, 56 34, 62 48) )', 101));
+< INSERT INTO named_places VALUES(118, 'Goose Island',
+< PolyFromText(
+< 'POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )', 101));
+< # Map Neatlines
+< INSERT INTO map_neatlines VALUES(115,
+< PolyFromText(
+< 'POLYGON( ( 0 0, 0 48, 84 48, 84 0, 0 0 ) )', 101));
+< SELECT Dimension(shore)
+< FROM lakes
+< WHERE name = 'Blue Lake';
+< Dimension(shore)
+< 2
+< SELECT GeometryType(centerlines)
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< GeometryType(centerlines)
+< MULTILINESTRING
+< SELECT AsText(boundary)
+< FROM named_places
+< WHERE name = 'Goose Island';
+< AsText(boundary)
+< POLYGON((67 13,67 18,59 18,59 13,67 13))
+< SELECT AsText(PolyFromWKB(AsBinary(boundary),101))
+< FROM named_places
+< WHERE name = 'Goose Island';
+< AsText(PolyFromWKB(AsBinary(boundary),101))
+< POLYGON((67 13,67 18,59 18,59 13,67 13))
+< SELECT SRID(boundary)
+< FROM named_places
+< WHERE name = 'Goose Island';
+< SRID(boundary)
+< 101
+< SELECT IsEmpty(centerline)
+< FROM road_segments
+< WHERE name = 'Route 5'
+< AND aliases = 'Main Street';
+< IsEmpty(centerline)
+< 0
+< SELECT AsText(Envelope(boundary))
+< FROM named_places
+< WHERE name = 'Goose Island';
+< AsText(Envelope(boundary))
+< POLYGON((59 13,67 13,67 18,59 18,59 13))
+< SELECT X(position)
+< FROM bridges
+< WHERE name = 'Cam Bridge';
+< X(position)
+< 44
+< SELECT Y(position)
+< FROM bridges
+< WHERE name = 'Cam Bridge';
+< Y(position)
+< 31
+< SELECT AsText(StartPoint(centerline))
+< FROM road_segments
+< WHERE fid = 102;
+< AsText(StartPoint(centerline))
+< POINT(0 18)
+< SELECT AsText(EndPoint(centerline))
+< FROM road_segments
+< WHERE fid = 102;
+< AsText(EndPoint(centerline))
+< POINT(44 31)
+< SELECT GLength(centerline)
+< FROM road_segments
+< WHERE fid = 106;
+< GLength(centerline)
+< 26
+< SELECT NumPoints(centerline)
+< FROM road_segments
+< WHERE fid = 102;
+< NumPoints(centerline)
+< 5
+< SELECT AsText(PointN(centerline, 1))
+< FROM road_segments
+< WHERE fid = 102;
+< AsText(PointN(centerline, 1))
+< POINT(0 18)
+< SELECT AsText(Centroid(boundary))
+< FROM named_places
+< WHERE name = 'Goose Island';
+< AsText(Centroid(boundary))
+< POINT(63 15.5)
+< SELECT Area(boundary)
+< FROM named_places
+< WHERE name = 'Goose Island';
+< Area(boundary)
+< 40
+< SELECT AsText(ExteriorRing(shore))
+< FROM lakes
+< WHERE name = 'Blue Lake';
+< AsText(ExteriorRing(shore))
+< LINESTRING(52 18,66 23,73 9,48 6,52 18)
+< SELECT NumInteriorRings(shore)
+< FROM lakes
+< WHERE name = 'Blue Lake';
+< NumInteriorRings(shore)
+< 1
+< SELECT AsText(InteriorRingN(shore, 1))
+< FROM lakes
+< WHERE name = 'Blue Lake';
+< AsText(InteriorRingN(shore, 1))
+< LINESTRING(59 18,67 18,67 13,59 13,59 18)
+< SELECT NumGeometries(centerlines)
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< NumGeometries(centerlines)
+< 2
+< SELECT AsText(GeometryN(centerlines, 2))
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< AsText(GeometryN(centerlines, 2))
+< LINESTRING(16 0,16 23,16 48)
+< SELECT IsClosed(centerlines)
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< IsClosed(centerlines)
+< 0
+< SELECT GLength(centerlines)
+< FROM divided_routes
+< WHERE name = 'Route 75';
+< GLength(centerlines)
+< 96
+< SELECT AsText(Centroid(shores))
+< FROM ponds
+< WHERE fid = 120;
+< AsText(Centroid(shores))
+< POINT(25 42)
+< SELECT Area(shores)
+< FROM ponds
+< WHERE fid = 120;
+< Area(shores)
+< 8
+< SELECT ST_Equals(boundary,
+< PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1))
+< FROM named_places
+< WHERE name = 'Goose Island';
+< ST_Equals(boundary,
+< PolyFromText('POLYGON( ( 67 13, 67 18, 59 18, 59 13, 67 13) )',1))
+< 1
+< SELECT ST_Disjoint(centerlines, boundary)
+< FROM divided_routes, named_places
+< WHERE divided_routes.name = 'Route 75'
+< AND named_places.name = 'Ashton';
+< ST_Disjoint(centerlines, boundary)
+< 1
+< SELECT ST_Touches(centerline, shore)
+< FROM streams, lakes
+< WHERE streams.name = 'Cam Stream'
+< AND lakes.name = 'Blue Lake';
+< ST_Touches(centerline, shore)
+< 1
+< SELECT Crosses(road_segments.centerline, divided_routes.centerlines)
+< FROM road_segments, divided_routes
+< WHERE road_segments.fid = 102
+< AND divided_routes.name = 'Route 75';
+< Crosses(road_segments.centerline, divided_routes.centerlines)
+< 1
+< SELECT ST_Intersects(road_segments.centerline, divided_routes.centerlines)
+< FROM road_segments, divided_routes
+< WHERE road_segments.fid = 102
+< AND divided_routes.name = 'Route 75';
+< ST_Intersects(road_segments.centerline, divided_routes.centerlines)
+< 1
+< SELECT ST_Contains(forests.boundary, named_places.boundary)
+< FROM forests, named_places
+< WHERE forests.name = 'Green Forest'
+< AND named_places.name = 'Ashton';
+< ST_Contains(forests.boundary, named_places.boundary)
+< 0
+< SELECT ST_Distance(position, boundary)
+< FROM bridges, named_places
+< WHERE bridges.name = 'Cam Bridge'
+< AND named_places.name = 'Ashton';
+< ST_Distance(position, boundary)
+< 12
+< SELECT AsText(ST_Difference(named_places.boundary, forests.boundary))
+< FROM named_places, forests
+< WHERE named_places.name = 'Ashton'
+< AND forests.name = 'Green Forest';
+< AsText(ST_Difference(named_places.boundary, forests.boundary))
+< POLYGON((56 34,62 48,84 48,84 42,56 34))
+< SELECT AsText(ST_Union(shore, boundary))
+< FROM lakes, named_places
+< WHERE lakes.name = 'Blue Lake'
+< AND named_places.name = 'Goose Island';
+< AsText(ST_Union(shore, boundary))
+< POLYGON((48 6,52 18,66 23,73 9,48 6))
+< SELECT AsText(ST_SymDifference(shore, boundary))
+< FROM lakes, named_places
+< WHERE lakes.name = 'Blue Lake'
+< AND named_places.name = 'Ashton';
+< AsText(ST_SymDifference(shore, boundary))
+< MULTIPOLYGON(((48 6,52 18,66 23,73 9,48 6),(59 13,59 18,67 18,67 13,59 13)),((56 30,56 34,62 48,84 48,84 30,56 30)))
+< SELECT count(*)
+< FROM buildings, bridges
+< WHERE ST_Contains(ST_Buffer(bridges.position, 15.0), buildings.footprint) = 1;
+< count(*)
+< 1
+---
+> ERROR 42000: The storage engine for the table doesn't support GEOMETRY
+> # ERROR: Statement ended with errno 1178, errname ER_CHECK_NOT_IMPLEMENTED (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE gis_point (fid INT(11) /*!*/ /*Custom column options*/, g POINT NOT NULL, SPATIAL INDEX(g)) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.gis_point) INSERT_METHOD=LAST ]
+> # The statement|command finished with ER_CHECK_NOT_IMPLEMENTED.
+> # Geometry types or spatial indexes or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
diff --git a/storage/myisammrg/mysql-test/storage_engine/vcol.rdiff b/storage/myisammrg/mysql-test/storage_engine/vcol.rdiff
new file mode 100644
index 00000000000..20431a9c713
--- /dev/null
+++ b/storage/myisammrg/mysql-test/storage_engine/vcol.rdiff
@@ -0,0 +1,79 @@
+3,69c3,12
+< SHOW COLUMNS IN t1;
+< Field Type Null Key Default Extra
+< a int(11) # #
+< b int(11) # # VIRTUAL
+< INSERT INTO t1 (a) VALUES (1),(2);
+< INSERT INTO t1 (a,b) VALUES (3,3),(4,4);
+< Warnings:
+< Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+< Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+< SELECT * FROM t1;
+< a b
+< 1 2
+< 2 3
+< 3 4
+< 4 5
+< DROP TABLE t1;
+< CREATE TABLE t1 (a <INT_COLUMN>, b <INT_COLUMN> GENERATED ALWAYS AS (a+1) PERSISTENT) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< SHOW COLUMNS IN t1;
+< Field Type Null Key Default Extra
+< a int(11) # #
+< b int(11) # # PERSISTENT
+< INSERT INTO t1 (a) VALUES (1),(2);
+< INSERT INTO t1 (a,b) VALUES (3,3),(4,4);
+< Warnings:
+< Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+< Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+< SELECT * FROM t1;
+< a b
+< 1 2
+< 2 3
+< 3 4
+< 4 5
+< DROP TABLE t1;
+< CREATE TABLE t1 (a <INT_COLUMN>, b <INT_COLUMN> GENERATED ALWAYS AS (a+1) VIRTUAL) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< SHOW COLUMNS IN t1;
+< Field Type Null Key Default Extra
+< a int(11) # #
+< b int(11) # # VIRTUAL
+< INSERT INTO t1 (a) VALUES (1),(2);
+< INSERT INTO t1 (a,b) VALUES (3,3),(4,4);
+< Warnings:
+< Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+< Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+< SELECT * FROM t1;
+< a b
+< 1 2
+< 2 3
+< 3 4
+< 4 5
+< DROP TABLE t1;
+< CREATE TABLE t1 (a <INT_COLUMN>, b <INT_COLUMN> AS (a+1) PERSISTENT) ENGINE=<STORAGE_ENGINE> <CUSTOM_TABLE_OPTIONS>;
+< SHOW COLUMNS IN t1;
+< Field Type Null Key Default Extra
+< a int(11) # #
+< b int(11) # # PERSISTENT
+< INSERT INTO t1 (a) VALUES (1),(2);
+< INSERT INTO t1 (a,b) VALUES (3,3),(4,4);
+< Warnings:
+< Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+< Warning 1906 The value specified for computed column 'b' in table 't1' ignored
+< SELECT * FROM t1;
+< a b
+< 1 2
+< 2 3
+< 3 4
+< 4 5
+< DROP TABLE t1;
+---
+> ERROR HY000: MRG_MYISAM storage engine does not support computed columns
+> # ERROR: Statement ended with errno 1910, errname ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS (expected to succeed)
+> # ------------ UNEXPECTED RESULT ------------
+> # [ CREATE TABLE t1 (a INT(11) /*!*/ /*Custom column options*/, b INT(11) /*!*/ /*Custom column options*/ GENERATED ALWAYS AS (a+1)) ENGINE=MRG_MYISAM /*!*/ /*Custom table options*/ UNION(mrg.t1) INSERT_METHOD=LAST ]
+> # The statement|command finished with ER_UNSUPPORTED_ENGINE_FOR_VIRTUAL_COLUMNS.
+> # Virtual columns or the mix could be unsupported|malfunctioning, or the problem was caused by previous errors.
+> # You can change the engine code, or create an rdiff, or disable the test by adding it to disabled.def.
+> # Further in this test, the message might sometimes be suppressed; a part of the test might be skipped.
+> # Also, this problem may cause a chain effect (more errors of different kinds in the test).
+> # -------------------------------------------
diff --git a/storage/oqgraph/CMakeLists.txt b/storage/oqgraph/CMakeLists.txt
index 4b8dac20350..83acb99b2a2 100644
--- a/storage/oqgraph/CMakeLists.txt
+++ b/storage/oqgraph/CMakeLists.txt
@@ -1,14 +1,24 @@
-FIND_PACKAGE(Boost 1.45.0) # we need at least 1.45 if we want -fno-rtti for the server
+FIND_PACKAGE(Boost 1.40.0)
IF(NOT Boost_FOUND)
RETURN()
ENDIF()
INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS})
-# lp:756966 OQGRAPH on Win64 does not compile
-IF(MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 8)
- SET(BOOST_OK 0)
+IF(MSVC)
+ # lp:756966 OQGRAPH on Win64 does not compile
+ IF (CMAKE_SIZEOF_VOID_P EQUAL 8)
+ SET(BOOST_OK 0)
+ ELSE()
+ SET(BOOST_OK 1)
+ ENDIF()
ELSE()
- SET(BOOST_OK 1)
+# See if that works. On old gcc it'll fail because of -fno-rtti
+CHECK_CXX_SOURCE_COMPILES(
+"
+#include <boost/config.hpp>
+#include <boost/property_map/property_map.hpp>
+int main() { return 0; }
+" BOOST_OK)
ENDIF()
IF(BOOST_OK)
@@ -16,7 +26,7 @@ IF(BOOST_OK)
IF(MSVC)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
ELSE(MSVC)
- SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated")
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated -fno-strict-aliasing")
STRING(REPLACE "-fno-exceptions" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
STRING(REPLACE "-fno-implicit-templates" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
ENDIF(MSVC)
diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc
index 27a463bf61f..97e83cd9221 100644
--- a/storage/sphinx/ha_sphinx.cc
+++ b/storage/sphinx/ha_sphinx.cc
@@ -3591,12 +3591,12 @@ struct st_mysql_storage_engine sphinx_storage_engine =
struct st_mysql_show_var sphinx_status_vars[] =
{
- {"sphinx_total", (char *)sphinx_showfunc_total, SHOW_FUNC},
- {"sphinx_total_found", (char *)sphinx_showfunc_total_found, SHOW_FUNC},
- {"sphinx_time", (char *)sphinx_showfunc_time, SHOW_FUNC},
- {"sphinx_word_count", (char *)sphinx_showfunc_word_count, SHOW_FUNC},
- {"sphinx_words", (char *)sphinx_showfunc_words, SHOW_FUNC},
- {"sphinx_error", (char *)sphinx_showfunc_error, SHOW_FUNC},
+ {"sphinx_total", (char *)sphinx_showfunc_total, SHOW_SIMPLE_FUNC},
+ {"sphinx_total_found", (char *)sphinx_showfunc_total_found, SHOW_SIMPLE_FUNC},
+ {"sphinx_time", (char *)sphinx_showfunc_time, SHOW_SIMPLE_FUNC},
+ {"sphinx_word_count", (char *)sphinx_showfunc_word_count, SHOW_SIMPLE_FUNC},
+ {"sphinx_words", (char *)sphinx_showfunc_words, SHOW_SIMPLE_FUNC},
+ {"sphinx_error", (char *)sphinx_showfunc_error, SHOW_SIMPLE_FUNC},
{0, 0, (enum_mysql_show_type)0}
};
diff --git a/storage/xtradb/btr/btr0btr.c b/storage/xtradb/btr/btr0btr.c
index 1fa6df44f7c..3f11684cb34 100644
--- a/storage/xtradb/btr/btr0btr.c
+++ b/storage/xtradb/btr/btr0btr.c
@@ -42,6 +42,7 @@ Created 6/2/1994 Heikki Tuuri
#include "ibuf0ibuf.h"
#include "trx0trx.h"
+#endif /* UNIV_HOTBACKUP */
/**************************************************************//**
Report that an index page is corrupted. */
UNIV_INTERN
@@ -61,9 +62,10 @@ btr_corruption_report(
buf_block_get_zip_size(block),
BUF_PAGE_PRINT_NO_CRASH);
}
- buf_page_print(buf_block_get_frame(block), 0, 0);
+ buf_page_print(buf_block_get_frame_fast(block), 0, 0);
}
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_BLOB_DEBUG
# include "srv0srv.h"
# include "ut0rbt.h"
@@ -1622,7 +1624,9 @@ btr_page_reorganize_low(
dict_index_t* index, /*!< in: record descriptor */
mtr_t* mtr) /*!< in: mtr */
{
+#ifndef UNIV_HOTBACKUP
buf_pool_t* buf_pool = buf_pool_from_bpage(&block->page);
+#endif /* !UNIV_HOTBACKUP */
page_t* page = buf_block_get_frame(block);
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
buf_block_t* temp_block;
diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c
index e093dabebf1..26db7329b7e 100644
--- a/storage/xtradb/btr/btr0cur.c
+++ b/storage/xtradb/btr/btr0cur.c
@@ -3604,6 +3604,8 @@ btr_estimate_n_rows_in_range(
n_rows = n_rows * 2;
}
+ DBUG_EXECUTE_IF("bug14007649", return(n_rows););
+
/* Do not estimate the number of rows in the range
to over 1 / 2 of the estimated rows in the whole
table */
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c
index fd7b8959473..a2ff171e0c5 100644
--- a/storage/xtradb/buf/buf0buf.c
+++ b/storage/xtradb/buf/buf0buf.c
@@ -344,7 +344,6 @@ be effective only if PFS_GROUP_BUFFER_SYNC is defined. */
// was allocated for the frames */
// buf_block_t* blocks; /*!< array of buffer control blocks */
//};
-#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Gets the smallest oldest_modification lsn for any page in the pool. Returns
@@ -482,6 +481,7 @@ buf_block_alloc(
return(block);
}
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Calculates a page checksum which is stored to the page when it is written
@@ -3907,9 +3907,10 @@ buf_mark_space_corrupt(
/********************************************************************//**
Completes an asynchronous read or write request of a file page to or from
-the buffer pool. */
+the buffer pool.
+@return TRUE if successful */
UNIV_INTERN
-void
+ibool
buf_page_io_complete(
/*=================*/
buf_page_t* bpage) /*!< in: pointer to the block in question */
@@ -4057,7 +4058,7 @@ corrupt:
table as corrupted instead of crashing server */
if (bpage->space > TRX_SYS_SPACE
&& buf_mark_space_corrupt(bpage)) {
- return;
+ return(FALSE);
} else {
fputs("InnoDB: Ending processing"
" because of"
@@ -4176,6 +4177,8 @@ retry_mutex:
buf_pool_mutex_exit(buf_pool);
mutex_exit(block_mutex);
+
+ return(TRUE);
}
/********************************************************************//**
diff --git a/storage/xtradb/buf/buf0flu.c b/storage/xtradb/buf/buf0flu.c
index bb921928653..39351cd3678 100644
--- a/storage/xtradb/buf/buf0flu.c
+++ b/storage/xtradb/buf/buf0flu.c
@@ -1846,8 +1846,6 @@ buf_flush_batch(
}
#endif /* UNIV_DEBUG */
- srv_buf_pool_flushed += count;
-
return(count);
}
@@ -1874,13 +1872,6 @@ buf_flush_common(
#endif /* UNIV_DEBUG */
srv_buf_pool_flushed += page_count;
-
- if (flush_type == BUF_FLUSH_LRU) {
- /* We keep track of all flushes happening as part of LRU
- flush. When estimating the desired rate at which flush_list
- should be flushed we factor in this value. */
- buf_lru_flush_page_count += page_count;
- }
}
/******************************************************************//**
diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c
index f7b5db2d0cc..16a91358080 100644
--- a/storage/xtradb/buf/buf0lru.c
+++ b/storage/xtradb/buf/buf0lru.c
@@ -374,7 +374,7 @@ next_page:
/******************************************************************//**
While flushing (or removing dirty) pages from a tablespace we don't
-want to hog the CPU and resources. Release the buffer pool and block
+want to hog the CPU and resources. Release the LRU list and block
mutex and try to force a context switch. Then reacquire the same mutexes.
The current page is "fixed" before the release of the mutexes and then
"unfixed" again once we have reacquired the mutexes. */
@@ -387,7 +387,7 @@ buf_flush_yield(
{
mutex_t* block_mutex;
- ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
ut_ad(buf_page_in_file(bpage));
block_mutex = buf_page_get_mutex(bpage);
@@ -399,13 +399,13 @@ buf_flush_yield(
buf_page_set_sticky(bpage);
/* Now it is safe to release the buf_pool->mutex. */
- buf_pool_mutex_exit(buf_pool);
+ mutex_exit(&buf_pool->LRU_list_mutex);
mutex_exit(block_mutex);
/* Try and force a context switch. */
os_thread_yield();
- buf_pool_mutex_enter(buf_pool);
+ mutex_enter(&buf_pool->LRU_list_mutex);
mutex_enter(block_mutex);
/* "Unfix" the block now that we have both the
@@ -415,9 +415,9 @@ buf_flush_yield(
}
/******************************************************************//**
-If we have hogged the resources for too long then release the buffer
-pool and flush list mutex and do a thread yield. Set the current page
-to "sticky" so that it is not relocated during the yield.
+If we have hogged the resources for too long then release the LRU list
+and flush list mutex and do a thread yield. Set the current page to
+"sticky" so that it is not relocated during the yield.
@return TRUE if yielded */
static
ibool
@@ -439,7 +439,7 @@ buf_flush_try_yield(
buf_flush_list_mutex_exit(buf_pool);
- /* Release the buffer pool and block mutex
+ /* Release the LRU list and block mutex
to give the other threads a go. */
buf_flush_yield(buf_pool, bpage);
@@ -472,7 +472,7 @@ buf_flush_or_remove_page(
mutex_t* block_mutex;
ibool processed = FALSE;
- ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
ut_ad(buf_flush_list_mutex_own(buf_pool));
block_mutex = buf_page_get_mutex(bpage);
@@ -595,11 +595,11 @@ buf_flush_dirty_pages(
ibool all_freed;
do {
- buf_pool_mutex_enter(buf_pool);
+ mutex_enter(&buf_pool->LRU_list_mutex);
all_freed = buf_flush_or_remove_pages(buf_pool, id);
- buf_pool_mutex_exit(buf_pool);
+ mutex_exit(&buf_pool->LRU_list_mutex);
ut_ad(buf_flush_validate(buf_pool));
@@ -659,8 +659,16 @@ scan_again:
goto next_page;
} else {
- block_mutex = buf_page_get_mutex(bpage);
- mutex_enter(block_mutex);
+ block_mutex = buf_page_get_mutex_enter(bpage);
+
+ if (!block_mutex) {
+ /* It may be impossible case...
+ Something wrong, so will be scan_again */
+
+ all_freed = FALSE;
+ goto next_page;
+ }
+
if (bpage->buf_fix_count > 0) {
@@ -694,7 +702,8 @@ scan_again:
ulint page_no;
ulint zip_size;
- buf_pool_mutex_exit(buf_pool);
+ mutex_exit(&buf_pool->LRU_list_mutex);
+ rw_lock_x_unlock(&buf_pool->page_hash_latch);
zip_size = buf_page_get_zip_size(bpage);
page_no = buf_page_get_page_no(bpage);
@@ -2370,9 +2379,23 @@ buf_LRU_free_one_page(
be in a state where it can be freed; there
may or may not be a hash index to the page */
{
+#ifdef UNIV_DEBUG
+ buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+#endif
+ mutex_t* block_mutex = buf_page_get_mutex(bpage);
+
+ ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(block_mutex));
+
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
!= BUF_BLOCK_ZIP_FREE) {
buf_LRU_block_free_hashed_page((buf_block_t*) bpage, TRUE);
+ } else {
+ /* The block_mutex should have been released by
+ buf_LRU_block_remove_hashed_page() when it returns
+ BUF_BLOCK_ZIP_FREE. */
+ ut_ad(block_mutex == &buf_pool->zip_mutex);
+ mutex_enter(block_mutex);
}
}
diff --git a/storage/xtradb/buf/buf0rea.c b/storage/xtradb/buf/buf0rea.c
index 4ba0d2cf577..c29dcbf0444 100644
--- a/storage/xtradb/buf/buf0rea.c
+++ b/storage/xtradb/buf/buf0rea.c
@@ -51,6 +51,44 @@ i/o-fixed buffer blocks */
#define BUF_READ_AHEAD_PEND_LIMIT 2
/********************************************************************//**
+Unfixes the pages, unlatches the page,
+removes it from page_hash and removes it from LRU. */
+static
+void
+buf_read_page_handle_error(
+/*=======================*/
+ buf_page_t* bpage) /*!< in: pointer to the block */
+{
+ buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+ const ibool uncompressed = (buf_page_get_state(bpage)
+ == BUF_BLOCK_FILE_PAGE);
+
+ /* First unfix and release lock on the bpage */
+ buf_pool_mutex_enter(buf_pool);
+ mutex_enter(buf_page_get_mutex(bpage));
+ ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ);
+ ut_ad(bpage->buf_fix_count == 0);
+
+ /* Set BUF_IO_NONE before we remove the block from LRU list */
+ buf_page_set_io_fix(bpage, BUF_IO_NONE);
+
+ if (uncompressed) {
+ rw_lock_x_unlock_gen(
+ &((buf_block_t*) bpage)->lock,
+ BUF_IO_READ);
+ }
+
+ /* remove the block from LRU list */
+ buf_LRU_free_one_page(bpage);
+
+ ut_ad(buf_pool->n_pend_reads > 0);
+ buf_pool->n_pend_reads--;
+
+ mutex_exit(buf_page_get_mutex(bpage));
+ buf_pool_mutex_exit(buf_pool);
+}
+
+/********************************************************************//**
Low-level function which reads a page asynchronously from a file to the
buffer buf_pool if it is not already there, in which case does nothing.
Sets the io_fix flag and sets an exclusive lock on the buffer frame. The
@@ -198,6 +236,11 @@ not_to_recover:
((buf_block_t*) bpage)->frame, bpage, trx);
}
+ if (*err == DB_TABLESPACE_DELETED) {
+ buf_read_page_handle_error(bpage);
+ return(0);
+ }
+
if (srv_pass_corrupt_table) {
if (*err != DB_SUCCESS) {
bpage->is_corrupt = TRUE;
@@ -210,7 +253,9 @@ not_to_recover:
thd_wait_end(NULL);
/* The i/o is already completed when we arrive from
fil_read */
- buf_page_io_complete(bpage);
+ if (!buf_page_io_complete(bpage)) {
+ return(0);
+ }
}
return(1);
diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c
index 3ee045807ed..516b6e927e0 100644
--- a/storage/xtradb/dict/dict0dict.c
+++ b/storage/xtradb/dict/dict0dict.c
@@ -170,6 +170,7 @@ void
dict_field_print_low(
/*=================*/
const dict_field_t* field); /*!< in: field */
+#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Frees a foreign key struct. */
static
@@ -183,7 +184,7 @@ and unique key errors */
UNIV_INTERN FILE* dict_foreign_err_file = NULL;
/* mutex protecting the foreign and unique error buffers */
UNIV_INTERN mutex_t dict_foreign_err_mutex;
-
+#endif /* !UNIV_HOTBACKUP */
/******************************************************************//**
Makes all characters in a NUL-terminated UTF-8 string lower case. */
UNIV_INTERN
@@ -2318,6 +2319,7 @@ dict_index_build_internal_non_clust(
return(new_index);
}
+#ifndef UNIV_HOTBACKUP
/*====================== FOREIGN KEY PROCESSING ========================*/
/*********************************************************************//**
@@ -2582,6 +2584,7 @@ dict_foreign_find_equiv_index(
FALSE/* allow columns to be NULL */));
}
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Returns an index object by matching on the name and column names and
if more than one index matches return the index with the max id
@@ -2641,6 +2644,7 @@ dict_table_get_index_by_max_id(
return(found);
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Report an error in a foreign key definition. */
static
@@ -2806,6 +2810,7 @@ dict_foreign_add_to_cache(
return(DB_SUCCESS);
}
+#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
Scans from pointer onwards. Stops if is at the start of a copy of
'string' where characters are compared without case sensitivity, and
@@ -3285,6 +3290,7 @@ end_of_string:
}
}
+#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Finds the highest [number] for foreign key constraints of the table. Looks
only at the >= 4.0.18-format id's, which are of the form
@@ -4121,7 +4127,7 @@ syntax_error:
}
/*==================== END OF FOREIGN KEY PROCESSING ====================*/
-
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Returns an index object if it is found in the dictionary cache.
Assumes that dict_sys->mutex is already being held.
@@ -4654,12 +4660,6 @@ next_rec:
}
btr_pcur_close(&pcur);
mtr_commit(&mtr);
-
- if (rests) {
- fprintf(stderr, "InnoDB: Warning: failed to store %lu stats entries"
- " of %s/%s to SYS_STATS system table.\n",
- rests, index->table_name, index->name);
- }
}
/*===========================================*/
@@ -4895,6 +4895,7 @@ next_rec:
}
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Prints info of a foreign key constraint. */
static
@@ -4925,6 +4926,7 @@ dict_foreign_print_low(
fputs(" )\n", stderr);
}
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Prints a table data. */
UNIV_INTERN
@@ -5107,6 +5109,7 @@ dict_field_print_low(
}
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Outputs info on a foreign key of a table in a format suitable for
CREATE TABLE. */
@@ -5295,6 +5298,7 @@ dict_print_info_on_foreign_keys(
mutex_exit(&(dict_sys->mutex));
}
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Displays the names of the index and the table. */
UNIV_INTERN
@@ -5425,6 +5429,28 @@ dict_table_replace_index_in_foreign_list(
foreign->foreign_index = new_index;
}
}
+
+
+ for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
+ foreign;
+ foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
+
+ dict_index_t* new_index;
+
+ if (foreign->referenced_index == index) {
+ ut_ad(foreign->referenced_table == index->table);
+
+ new_index = dict_foreign_find_index(
+ foreign->referenced_table,
+ foreign->referenced_col_names,
+ foreign->n_fields, index,
+ /*check_charsets=*/TRUE, /*check_null=*/FALSE);
+ ut_ad(new_index || !trx->check_foreigns);
+ ut_ad(!new_index || new_index->table == index->table);
+
+ foreign->referenced_index = new_index;
+ }
+ }
}
/**********************************************************************//**
diff --git a/storage/xtradb/dict/dict0load.c b/storage/xtradb/dict/dict0load.c
index 44492960bb8..0ef74ea8b7c 100644
--- a/storage/xtradb/dict/dict0load.c
+++ b/storage/xtradb/dict/dict0load.c
@@ -178,7 +178,7 @@ dict_print(void)
monitor printout */
mutex_enter(&kernel_mutex);
- srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
+ srv_fatal_semaphore_wait_threshold += SRV_SEMAPHORE_WAIT_EXTENSION;
mutex_exit(&kernel_mutex);
heap = mem_heap_create(1000);
@@ -215,7 +215,7 @@ dict_print(void)
/* Restore the fatal semaphore wait timeout */
mutex_enter(&kernel_mutex);
- srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
+ srv_fatal_semaphore_wait_threshold -= SRV_SEMAPHORE_WAIT_EXTENSION;
mutex_exit(&kernel_mutex);
}
diff --git a/storage/xtradb/dict/dict0mem.c b/storage/xtradb/dict/dict0mem.c
index 617c68925cb..6b8c11dfa7a 100644
--- a/storage/xtradb/dict/dict0mem.c
+++ b/storage/xtradb/dict/dict0mem.c
@@ -33,8 +33,8 @@ Created 1/8/1996 Heikki Tuuri
#include "data0type.h"
#include "mach0data.h"
#include "dict0dict.h"
-#include "ha_prototypes.h" /* innobase_casedn_str()*/
#ifndef UNIV_HOTBACKUP
+# include "ha_prototypes.h" /* innobase_casedn_str()*/
# include "lock0lock.h"
#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_BLOB_DEBUG
@@ -274,6 +274,7 @@ dict_mem_index_create(
return(index);
}
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Creates and initializes a foreign constraint memory object.
@return own: foreign constraint struct */
@@ -348,6 +349,7 @@ dict_mem_referenced_table_name_lookup_set(
}
}
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Adds a field definition to an index. NOTE: does not take a copy
of the column name if the field is a column. The memory occupied
diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c
index 2b67bdafeb9..4ab2c16d41f 100644
--- a/storage/xtradb/fil/fil0fil.c
+++ b/storage/xtradb/fil/fil0fil.c
@@ -867,8 +867,10 @@ fil_node_close_file(
ut_a(node->open);
ut_a(node->n_pending == 0 || node->space->is_being_deleted);
ut_a(node->n_pending_flushes == 0);
+#ifndef UNIV_HOTBACKUP
ut_a(node->modification_counter == node->flush_counter
|| srv_fast_shutdown == 2);
+#endif /* !UNIV_HOTBACKUP */
ret = os_file_close(node->handle);
ut_a(ret);
@@ -1932,7 +1934,7 @@ fil_inc_pending_ops(
if (space == NULL) {
fprintf(stderr,
- "InnoDB: Error: trying to do ibuf merge to a"
+ "InnoDB: Error: trying to do an operation on a"
" dropped tablespace %lu\n",
(ulong) id);
}
@@ -3440,6 +3442,7 @@ skip_info:
for (offset = 0; offset < free_limit_bytes;
offset += zip_size ? zip_size : UNIV_PAGE_SIZE) {
ibool page_is_corrupt;
+ ibool is_descr_page = FALSE;
success = os_file_read(file, page,
(ulint)(offset & 0xFFFFFFFFUL),
@@ -3478,6 +3481,7 @@ skip_info:
/* store as descr page */
memcpy(descr_page, page, (zip_size ? zip_size : UNIV_PAGE_SIZE));
+ is_descr_page = TRUE;
} else if (descr_is_corrupt) {
/* unknown state of the page */
@@ -3554,7 +3558,8 @@ skip_info:
}
}
- if (fil_page_get_type(page) == FIL_PAGE_INDEX) {
+ if (fil_page_get_type(page) ==
+ FIL_PAGE_INDEX && !is_descr_page) {
index_id_t tmp = mach_read_from_8(page + (PAGE_HEADER + PAGE_INDEX_ID));
for (i = 0; i < n_index; i++) {
diff --git a/storage/xtradb/ha/ha0ha.c b/storage/xtradb/ha/ha0ha.c
index 2f5051e541f..b9499607bce 100644
--- a/storage/xtradb/ha/ha0ha.c
+++ b/storage/xtradb/ha/ha0ha.c
@@ -28,6 +28,7 @@ Created 8/22/1994 Heikki Tuuri
#include "ha0ha.ic"
#endif
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_DEBUG
# include "buf0buf.h"
#endif /* UNIV_DEBUG */
@@ -51,17 +52,13 @@ ha_create_func(
hash table: must be a power of 2, or 0 */
{
hash_table_t* table;
-#ifndef UNIV_HOTBACKUP
ulint i;
-#endif /* !UNIV_HOTBACKUP */
ut_ad(ut_is_2pow(n_mutexes));
table = hash_create(n);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
table->adaptive = TRUE;
-# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
/* Creating MEM_HEAP_BTR_SEARCH type heaps can potentially fail,
but in practise it never should in this case, hence the asserts. */
@@ -74,7 +71,6 @@ ha_create_func(
return(table);
}
-#ifndef UNIV_HOTBACKUP
hash_create_mutexes(table, n_mutexes, mutex_level);
table->heaps = mem_alloc(n_mutexes * sizeof(void*));
@@ -83,7 +79,6 @@ ha_create_func(
table->heaps[i] = mem_heap_create_in_btr_search(4096);
ut_a(table->heaps[i]);
}
-#endif /* !UNIV_HOTBACKUP */
return(table);
}
@@ -134,7 +129,6 @@ ha_insert_for_fold_func(
while (prev_node != NULL) {
if (prev_node->fold == fold) {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
buf_block_t* prev_block = prev_node->block;
ut_a(prev_block->frame
@@ -143,7 +137,6 @@ ha_insert_for_fold_func(
prev_block->n_pointers--;
block->n_pointers++;
}
-# endif /* !UNIV_HOTBACKUP */
prev_node->block = block;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -171,11 +164,9 @@ ha_insert_for_fold_func(
ha_node_set_data(node, block, data);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
block->n_pointers++;
}
-# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
node->fold = fold;
@@ -217,13 +208,11 @@ ha_delete_hash_node(
#endif /* UNIV_SYNC_DEBUG */
ut_ad(btr_search_enabled);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
ut_a(del_node->block->frame = page_align(del_node->data));
ut_a(del_node->block->n_pointers > 0);
del_node->block->n_pointers--;
}
-# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node);
@@ -264,13 +253,11 @@ ha_search_and_update_if_found_func(
if (node) {
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
-# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
ut_a(node->block->n_pointers > 0);
node->block->n_pointers--;
new_block->n_pointers++;
}
-# endif /* !UNIV_HOTBACKUP */
node->block = new_block;
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
@@ -278,7 +265,6 @@ ha_search_and_update_if_found_func(
}
}
-#ifndef UNIV_HOTBACKUP
/*****************************************************************//**
Removes from the chain determined by fold all nodes whose data pointer
points to the page given. */
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index cd11e46358b..39d6fb4bf11 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -49,6 +49,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#include <sql_acl.h> // PROCESS_ACL
#include <m_ctype.h>
+#include <debug_sync.h> // DEBUG_SYNC
#include <mysys_err.h>
#include <mysql/plugin.h>
#include <innodb_priv.h>
@@ -383,6 +384,7 @@ static int innobase_rollback_to_savepoint(handlerton *hton, THD* thd,
static int innobase_savepoint(handlerton *hton, THD* thd, void *savepoint);
static int innobase_release_savepoint(handlerton *hton, THD* thd,
void *savepoint);
+static void innobase_checkpoint_request(handlerton *hton, void *cookie);
static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
MEM_ROOT *mem_root);
@@ -483,10 +485,17 @@ static MYSQL_THDVAR_ULONG(lock_wait_timeout, PLUGIN_VAR_RQCMDARG,
NULL, NULL, 50, 1, 1024 * 1024 * 1024, 0);
static MYSQL_THDVAR_ULONG(flush_log_at_trx_commit, PLUGIN_VAR_OPCMDARG,
- "Set to 0 (write and flush once per second),"
- " 1 (write and flush at each commit)"
- " or 2 (write at commit, flush once per second).",
- NULL, NULL, 1, 0, 2, 0);
+ "Controls the durability/speed trade-off for commits."
+ " Set to 0 (write and flush redo log to disk only once per second),"
+ " 1 (flush to disk at each commit),"
+ " 2 (write to log at commit but flush to disk only once per second)"
+ " or 3 (flush to disk at prepare and at commit, slower and usually redundant)."
+ " 1 and 3 guarantees that after a crash, committed transactions will"
+ " not be lost and will be consistent with the binlog and other transactional"
+ " engines. 2 can get inconsistent and lose transactions if there is a"
+ " power failure or kernel crash but not if mysqld crashes. 0 has no"
+ " guarantees in case of crash. 0 and 2 can be faster than 1 or 3.",
+ NULL, NULL, 1, 0, 3, 0);
static MYSQL_THDVAR_BOOL(fake_changes, PLUGIN_VAR_OPCMDARG,
"In the transaction after enabled, UPDATE, INSERT and DELETE only move the cursor to the records "
@@ -494,6 +503,9 @@ static MYSQL_THDVAR_BOOL(fake_changes, PLUGIN_VAR_OPCMDARG,
"This is to cause replication prefetch IO. ATTENTION: the transaction started after enabled is affected.",
NULL, NULL, FALSE);
+static MYSQL_THDVAR_ULONG(merge_sort_block_size, PLUGIN_VAR_RQCMDARG,
+ "The block size used doing external merge-sort for secondary index creation.",
+ NULL, NULL, 1UL << 20, 1UL << 20, 1UL << 30, 0);
static handler *innobase_create_handler(handlerton *hton,
TABLE_SHARE *table,
@@ -1010,6 +1022,20 @@ thd_flush_log_at_trx_commit(
return(THDVAR((THD*) thd, flush_log_at_trx_commit));
}
+/******************************************************************//**
+Returns the merge-sort block size used for the secondary index creation
+for the current connection.
+@return the merge-sort block size, in bytes */
+extern "C" UNIV_INTERN
+ulong
+thd_merge_sort_block_size(
+/*================================*/
+ void* thd) /*!< in: thread handle (THD*), or NULL to query
++ the global merge_sort_block_size */
+{
+ return(THDVAR((THD*) thd, merge_sort_block_size));
+}
+
/********************************************************************//**
Obtain the InnoDB transaction of a MySQL thread.
@return reference to transaction pointer */
@@ -1646,6 +1672,15 @@ innobase_next_autoinc(
ut_a(block > 0);
ut_a(max_value > 0);
+ /*
+ Allow auto_increment to go over max_value up to max ulonglong.
+ This allows us to detect that all values are exhausted.
+ If we don't do this, we will return max_value several times
+ and get duplicate key errors instead of auto increment value
+ out of range.
+ */
+ max_value= (~(ulonglong) 0);
+
/* Current value should never be greater than the maximum. */
ut_a(current <= max_value);
@@ -2469,6 +2504,7 @@ innobase_init(
innobase_hton->recover=innobase_xa_recover;
innobase_hton->commit_by_xid=innobase_commit_by_xid;
innobase_hton->rollback_by_xid=innobase_rollback_by_xid;
+ innobase_hton->commit_checkpoint_request=innobase_checkpoint_request;
innobase_hton->checkpoint_state= innobase_checkpoint_state;
innobase_hton->create_cursor_read_view=innobase_create_cursor_view;
innobase_hton->set_cursor_read_view=innobase_set_cursor_view;
@@ -2870,6 +2906,7 @@ innobase_change_buffering_inited_ok:
srv_read_ahead &= 3;
srv_adaptive_flushing_method %= 3;
+ srv_flush_neighbor_pages %= 3;
srv_force_recovery = (ulint) innobase_force_recovery;
@@ -3153,7 +3190,9 @@ innobase_commit_low(
#ifdef MYSQL_SERVER
THD *thd=current_thd;
- if (thd && thd_is_replication_slave_thread(thd)) {
+ if (innobase_overwrite_relay_log_info &&
+ thd && thd_is_replication_slave_thread(thd) &&
+ thd->connection_name.length) {
/* Update the replication position info inside InnoDB.
In embedded server, does nothing. */
const char *log_file_name, *group_relay_log_name;
@@ -3492,6 +3531,19 @@ innobase_rollback_trx(
}
/*****************************************************************//**
+Handle a commit checkpoint request from server layer.
+We simply flush the redo log immediately and do the notify call.*/
+static
+void
+innobase_checkpoint_request(
+ handlerton *hton,
+ void *cookie)
+{
+ log_buffer_flush_to_disk();
+ commit_checkpoint_notify_ha(hton, cookie);
+}
+
+/*****************************************************************//**
Rolls back a transaction to a savepoint.
@return 0 if success, HA_ERR_NO_SAVEPOINT if no savepoint with the
given name */
@@ -4701,6 +4753,27 @@ table_opened:
}
UNIV_INTERN
+handler*
+ha_innobase::clone(
+/*===============*/
+ const char* name, /*!< in: table name */
+ MEM_ROOT* mem_root) /*!< in: memory context */
+{
+ ha_innobase* new_handler;
+
+ DBUG_ENTER("ha_innobase::clone");
+
+ new_handler = static_cast<ha_innobase*>(handler::clone(name,
+ mem_root));
+ if (new_handler) {
+ new_handler->prebuilt->select_lock_type
+ = prebuilt->select_lock_type;
+ }
+
+ DBUG_RETURN(new_handler);
+}
+
+UNIV_INTERN
uint
ha_innobase::max_supported_key_part_length() const
{
@@ -5957,7 +6030,10 @@ no_commit:
goto report_error;
}
- /* MySQL errors are passed straight back. */
+ /* MySQL errors are passed straight back. except for
+ HA_ERR_AUTO_INC_READ_FAILED. This can only happen
+ for values out of range.
+ */
error_result = (int) error;
goto func_exit;
}
@@ -6661,6 +6737,7 @@ ha_innobase::index_read(
ulint ret;
DBUG_ENTER("index_read");
+ DEBUG_SYNC_C("ha_innobase_index_read_begin");
ut_a(prebuilt->trx == thd_to_trx(user_thd));
ut_ad(key_len != 0 || find_flag != HA_READ_KEY_EXACT);
@@ -8538,6 +8615,8 @@ ha_innobase::rename_table(
error = innobase_rename_table(trx, from, to, TRUE);
+ DEBUG_SYNC(thd, "after_innobase_rename_table");
+
/* Tell the InnoDB server that there might be work for
utility threads: */
@@ -8865,10 +8944,15 @@ innobase_get_mysql_key_number_for_index(
}
}
- /* Print an error message if we cannot find the index
- ** in the "index translation table". */
- sql_print_error("Cannot find index %s in InnoDB index "
- "translation table.", index->name);
+ /* If index_count in translation table is set to 0, it
+ is possible we are in the process of rebuilding table,
+ do not spit error in this case */
+ if (share->idx_trans_tbl.index_count) {
+ /* Print an error message if we cannot find the index
+ ** in the "index translation table". */
+ sql_print_error("Cannot find index %s in InnoDB index "
+ "translation table.", index->name);
+ }
}
/* If we do not have an "index translation table", or not able
@@ -9262,9 +9346,10 @@ ha_innobase::info_low(
}
else if (rec_per_key > 1) {
rec_per_key =
- (ha_rows) (k_rec_per_key *
- (double)rec_per_key /
- n_rows);
+ (ha_rows)
+ (k_rec_per_key *
+ (double)rec_per_key /
+ n_rows);
}
key_info->rec_per_key[k++]=
@@ -9432,7 +9517,7 @@ ha_innobase::check(
/* Enlarge the fatal lock wait timeout during CHECK TABLE. */
mutex_enter(&kernel_mutex);
- srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
+ srv_fatal_semaphore_wait_threshold += SRV_SEMAPHORE_WAIT_EXTENSION;
mutex_exit(&kernel_mutex);
for (index = dict_table_get_first_index(prebuilt->table);
@@ -9573,7 +9658,7 @@ ha_innobase::check(
/* Restore the fatal lock wait timeout after CHECK TABLE. */
mutex_enter(&kernel_mutex);
- srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
+ srv_fatal_semaphore_wait_threshold -= SRV_SEMAPHORE_WAIT_EXTENSION;
mutex_exit(&kernel_mutex);
prebuilt->trx->op_info = "";
@@ -10455,6 +10540,7 @@ innodb_show_status(
const long MAX_STATUS_SIZE = 1048576;
ulint trx_list_start = ULINT_UNDEFINED;
ulint trx_list_end = ULINT_UNDEFINED;
+ bool res;
DBUG_ENTER("innodb_show_status");
DBUG_ASSERT(hton == innodb_hton_ptr);
@@ -10518,12 +10604,13 @@ innodb_show_status(
mutex_exit(&srv_monitor_file_mutex);
- stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name),
- STRING_WITH_LEN(""), str, flen);
+ res= stat_print(thd, innobase_hton_name,
+ (uint) strlen(innobase_hton_name),
+ STRING_WITH_LEN(""), str, flen);
my_free(str);
- DBUG_RETURN(FALSE);
+ DBUG_RETURN(res);
}
/************************************************************************//**
@@ -11135,13 +11222,17 @@ ha_innobase::get_auto_increment(
/* Not in the middle of a mult-row INSERT. */
} else if (prebuilt->autoinc_last_value == 0) {
set_if_bigger(*first_value, autoinc);
- /* Check for -ve values. */
- } else if (*first_value > col_max_value && trx->n_autoinc_rows > 0) {
- /* Set to next logical value. */
- ut_a(autoinc > trx->n_autoinc_rows);
- *first_value = (autoinc - trx->n_autoinc_rows) - 1;
}
+ if (*first_value > col_max_value)
+ {
+ /* Out of range number. Let handler::update_auto_increment()
+ take care of this */
+ prebuilt->autoinc_last_value = 0;
+ dict_table_autoinc_unlock(prebuilt->table);
+ *nb_reserved_values = 0;
+ return;
+ }
*nb_reserved_values = trx->n_autoinc_rows;
/* With old style AUTOINC locking we only update the table's
@@ -11150,7 +11241,7 @@ ha_innobase::get_auto_increment(
ulonglong current;
ulonglong next_value;
- current = *first_value > col_max_value ? autoinc : *first_value;
+ current = *first_value;
/* Compute the last value in the interval */
next_value = innobase_next_autoinc(
@@ -12368,7 +12459,7 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite,
static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity,
PLUGIN_VAR_RQCMDARG,
"Number of IOPs the server can do. Tunes the background IO rate",
- NULL, NULL, 200, 100, ~0L, 0);
+ NULL, NULL, 200, 100, ~0UL, 0);
static MYSQL_SYSVAR_ULONG(purge_batch_size, srv_purge_batch_size,
PLUGIN_VAR_OPCMDARG,
@@ -12501,7 +12592,7 @@ static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing,
static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag,
PLUGIN_VAR_RQCMDARG,
"Desired maximum length of the purge queue (0 = no limit)",
- NULL, NULL, 0, 0, ~0L, 0);
+ NULL, NULL, 0, 0, ~0UL, 0);
static MYSQL_SYSVAR_BOOL(rollback_on_timeout, innobase_rollback_on_timeout,
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
@@ -12605,7 +12696,7 @@ static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
PLUGIN_VAR_RQCMDARG,
"Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket",
- NULL, NULL, 500L, 1L, ~0L, 0);
+ NULL, NULL, 500L, 1L, ~0UL, 0);
#ifdef EXTENDED_FOR_KILLIDLE
#define kill_idle_help_text "If non-zero value, the idle session with transaction which is idle over the value in seconds is killed by InnoDB."
@@ -12675,12 +12766,12 @@ static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
PLUGIN_VAR_RQCMDARG,
"Count of spin-loop rounds in InnoDB mutexes (30 by default)",
- NULL, NULL, 30L, 0L, ~0L, 0);
+ NULL, NULL, 30L, 0L, ~0UL, 0);
static MYSQL_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay,
PLUGIN_VAR_OPCMDARG,
"Maximum delay between polling for a spin lock (6 by default)",
- NULL, NULL, 6L, 0L, ~0L, 0);
+ NULL, NULL, 6L, 0L, ~0UL, 0);
static MYSQL_SYSVAR_BOOL(thread_concurrency_timer_based,
innobase_thread_concurrency_timer_based,
@@ -12696,7 +12787,7 @@ static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency,
static MYSQL_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay,
PLUGIN_VAR_RQCMDARG,
"Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep",
- NULL, NULL, 10000L, 0L, ~0L, 0);
+ NULL, NULL, 10000L, 0L, ~0UL, 0);
static MYSQL_SYSVAR_STR(data_file_path, innobase_data_file_path,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
@@ -12871,7 +12962,7 @@ innodb_adaptive_flushing_method_update(
void* var_ptr,
const void* save)
{
- *(long *)var_ptr= (*(long *)save) % 4;
+ *(long *)var_ptr= (*(long *)save) % 3;
}
const char *adaptive_flushing_method_names[]=
{
@@ -12934,7 +13025,7 @@ static MYSQL_SYSVAR_ENUM(corrupt_table_action, srv_pass_corrupt_table,
"Warn corruptions of user tables as 'corrupt table' instead of not crashing itself, "
"when used with file_per_table. "
"All file io for the datafile after detected as corrupt are disabled, "
- "except for the deletion.",
+ "except for the deletion. Possible options are 'assert', 'warn' & 'salvage'",
NULL, NULL, 0, &corrupt_table_action_typelib);
static MYSQL_SYSVAR_ULINT(lazy_drop_table, srv_lazy_drop_table,
@@ -13049,6 +13140,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(corrupt_table_action),
MYSQL_SYSVAR(lazy_drop_table),
MYSQL_SYSVAR(fake_changes),
+ MYSQL_SYSVAR(merge_sort_block_size),
NULL
};
@@ -13069,6 +13161,7 @@ maria_declare_plugin(xtradb)
MariaDB_PLUGIN_MATURITY_STABLE /* maturity */
},
i_s_innodb_rseg_maria,
+i_s_innodb_undo_logs_maria,
i_s_innodb_trx_maria,
i_s_innodb_locks_maria,
i_s_innodb_lock_waits_maria,
diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h
index b48805ad0a5..933d75cf0d2 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -134,6 +134,7 @@ class ha_innobase: public handler
const key_map* keys_to_use_for_scanning();
int open(const char *name, int mode, uint test_if_locked);
+ handler* clone(const char *name, MEM_ROOT *mem_root);
int close(void);
double scan_time();
double read_time(uint index, uint ranges, ha_rows rows);
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 92e51d37d7d..0496cb98080 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -713,6 +713,10 @@ ha_innobase::add_index(
ut_a(indexed_table == prebuilt->table);
+ if (indexed_table->tablespace_discarded) {
+ DBUG_RETURN(-1);
+ }
+
/* Check that index keys are sensible */
error = innobase_check_index_keys(key_info, num_of_keys, prebuilt->table);
@@ -781,7 +785,7 @@ ha_innobase::add_index(
row_mysql_lock_data_dictionary(trx);
dict_locked = TRUE;
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
/* If a new primary key is defined for the table we need
to drop the original table and rebuild all indexes. */
@@ -817,7 +821,7 @@ ha_innobase::add_index(
}
ut_d(dict_table_check_for_dup_indexes(prebuilt->table,
- FALSE));
+ TRUE));
mem_heap_free(heap);
trx_general_rollback_for_mysql(trx, NULL);
row_mysql_unlock_data_dictionary(trx);
@@ -1071,7 +1075,7 @@ ha_innobase::final_add_index(
trx_commit_for_mysql(prebuilt->trx);
}
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
row_mysql_unlock_data_dictionary(trx);
trx_free_for_mysql(trx);
@@ -1118,7 +1122,7 @@ ha_innobase::prepare_drop_index(
/* Test and mark all the indexes to be dropped */
row_mysql_lock_data_dictionary(trx);
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
/* Check that none of the indexes have previously been flagged
for deletion. */
@@ -1289,7 +1293,7 @@ func_exit:
} while (index);
}
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
row_mysql_unlock_data_dictionary(trx);
DBUG_RETURN(err);
@@ -1342,7 +1346,7 @@ ha_innobase::final_drop_index(
prebuilt->table->flags, user_thd);
row_mysql_lock_data_dictionary(trx);
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
if (UNIV_UNLIKELY(err)) {
@@ -1386,7 +1390,7 @@ ha_innobase::final_drop_index(
share->idx_trans_tbl.index_count = 0;
func_exit:
- ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE));
+ ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE));
trx_commit_for_mysql(trx);
trx_commit_for_mysql(prebuilt->trx);
row_mysql_unlock_data_dictionary(trx);
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index 1c40b87bbbd..5d86ea98d27 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -49,6 +49,7 @@ extern "C" {
#include "trx0i_s.h"
#include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */
#include "trx0rseg.h" /* for trx_rseg_struct */
+#include "trx0undo.h" /* for trx_undo_struct */
#include "trx0sys.h" /* for trx_sys */
#include "dict0dict.h" /* for dict_sys */
#include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
@@ -1578,6 +1579,8 @@ i_s_sys_tables_fill_table(
DBUG_ENTER("i_s_sys_tables_fill_table");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -1833,6 +1836,8 @@ i_s_sys_tables_fill_table_stats(
DBUG_ENTER("i_s_sys_tables_fill_table_stats");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -2029,6 +2034,8 @@ i_s_sys_indexes_fill_table(
DBUG_ENTER("i_s_sys_indexes_fill_table");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -2218,6 +2225,8 @@ i_s_sys_columns_fill_table(
DBUG_ENTER("i_s_sys_columns_fill_table");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -2372,6 +2381,8 @@ i_s_sys_fields_fill_table(
DBUG_ENTER("i_s_sys_fields_fill_table");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -2553,6 +2564,8 @@ i_s_sys_foreign_fill_table(
DBUG_ENTER("i_s_sys_foreign_fill_table");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
@@ -2716,6 +2729,8 @@ i_s_sys_foreign_cols_fill_table(
DBUG_ENTER("i_s_sys_foreign_cols_fill_table");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
@@ -2883,6 +2898,8 @@ i_s_sys_stats_fill_table(
DBUG_ENTER("i_s_sys_stats_fill_table");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
@@ -3199,6 +3216,8 @@ i_s_innodb_table_stats_fill(
DBUG_ENTER("i_s_innodb_table_stats_fill");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
@@ -3262,6 +3281,8 @@ i_s_innodb_index_stats_fill(
DBUG_ENTER("i_s_innodb_index_stats_fill");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
@@ -3422,6 +3443,8 @@ i_s_innodb_admin_command_fill(
DBUG_ENTER("i_s_innodb_admin_command_fill");
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
/* deny access to non-superusers */
if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
@@ -4415,3 +4438,292 @@ UNIV_INTERN struct st_maria_plugin i_s_innodb_buffer_pool_pages_blob_maria =
NULL,
INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE
};
+
+
+static ST_FIELD_INFO i_s_innodb_undo_logs_fields_info[] =
+{
+#define IDX_USEG_TRX_ID 0
+ {STRUCT_FLD(field_name, "trx_id"),
+ STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+#define IDX_USEG_RSEG_ID 1
+ {STRUCT_FLD(field_name, "rseg_id"),
+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+#define IDX_USEG_USEG_ID 2
+ {STRUCT_FLD(field_name, "useg_id"),
+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+#define IDX_USEG_TYPE 3
+#define USEG_TYPE_MAX_LEN 256
+ {STRUCT_FLD(field_name, "type"),
+ STRUCT_FLD(field_length, USEG_TYPE_MAX_LEN),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ #define IDX_USEG_STATE 4
+ #define USEG_STATE_MAX_LEN 256
+ {STRUCT_FLD(field_name, "state"),
+ STRUCT_FLD(field_length, USEG_STATE_MAX_LEN),
+ STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, 0),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+#define IDX_USEG_SIZE 5
+ {STRUCT_FLD(field_name, "size"),
+ STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
+ STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
+ STRUCT_FLD(value, 0),
+ STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
+ STRUCT_FLD(old_name, ""),
+ STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
+
+ END_OF_ST_FIELD_INFO
+};
+static
+int
+i_s_innodb_undo_logs_fill_store(
+/*=================*/
+ THD* thd, /* in: thread */
+ TABLE* table, /* in/out: table to fill */
+ trx_undo_t* useg) /* in: useg to fill from */
+{
+ char trx_id[TRX_ID_MAX_LEN + 1];
+
+ DBUG_ENTER("i_s_innodb_undo_logs_fill_store");
+
+ switch (useg->type) {
+ case TRX_UNDO_INSERT:
+ OK(field_store_string(table->field[IDX_USEG_TYPE], "INSERT"));
+ break;
+ case TRX_UNDO_UPDATE:
+ OK(field_store_string(table->field[IDX_USEG_TYPE], "UPDATE"));
+ break;
+ default:
+ OK(field_store_string(table->field[IDX_USEG_TYPE], "UNKNOWN"));
+ break;
+ }
+
+ ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, useg->trx_id);
+
+ switch (useg->state) {
+ case TRX_UNDO_ACTIVE:
+ OK(field_store_string(table->field[IDX_USEG_TRX_ID], trx_id));
+ OK(field_store_string(table->field[IDX_USEG_STATE], "ACTIVE"));
+ break;
+ case TRX_UNDO_CACHED:
+ OK(field_store_string(table->field[IDX_USEG_TRX_ID], NULL));
+ OK(field_store_string(table->field[IDX_USEG_STATE], "CACHED"));
+ break;
+ case TRX_UNDO_TO_FREE:
+ OK(field_store_string(table->field[IDX_USEG_TRX_ID], NULL));
+ OK(field_store_string(table->field[IDX_USEG_STATE], "TO_FREE"));
+ break;
+ case TRX_UNDO_TO_PURGE:
+ OK(field_store_string(table->field[IDX_USEG_TRX_ID], NULL));
+ OK(field_store_string(table->field[IDX_USEG_STATE], "TO_PURGE"));
+ break;
+ case TRX_UNDO_PREPARED:
+ OK(field_store_string(table->field[IDX_USEG_TRX_ID], trx_id));
+ OK(field_store_string(table->field[IDX_USEG_STATE], "PREPARED"));
+ break;
+ default:
+ OK(field_store_string(table->field[IDX_USEG_TRX_ID], trx_id));
+ OK(field_store_string(table->field[IDX_USEG_STATE], "UNKNOWN"));
+ break;
+ }
+
+ table->field[IDX_USEG_RSEG_ID]->store(useg->rseg->id);
+ table->field[IDX_USEG_USEG_ID]->store(useg->id);
+ table->field[IDX_USEG_SIZE]->store(useg->size);
+ if (schema_table_store_record(thd, table)) {
+ DBUG_RETURN(1);
+ }
+ DBUG_RETURN(0);
+}
+static
+int
+i_s_innodb_undo_logs_fill(
+/*=================*/
+ THD* thd, /* in: thread */
+ TABLE_LIST* tables, /* in/out: tables to fill */
+ COND* cond) /* in: condition (ignored) */
+{
+ TABLE* table = (TABLE *) tables->table;
+ int status = 0;
+ trx_rseg_t* rseg;
+ trx_undo_t* useg;
+
+ DBUG_ENTER("i_s_innodb_undo_logs_fill");
+
+ /* deny access to non-superusers */
+ if (check_global_access(thd, PROCESS_ACL)) {
+ DBUG_RETURN(0);
+ }
+
+ RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
+ rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
+ while (rseg && status == 0) {
+ mutex_enter(&(rseg->mutex));
+ useg = UT_LIST_GET_FIRST(rseg->update_undo_list);
+ while (useg && status == 0) {
+ status = i_s_innodb_undo_logs_fill_store(thd, table, useg);
+ useg = UT_LIST_GET_NEXT(undo_list, useg);
+ }
+
+ useg = UT_LIST_GET_FIRST(rseg->update_undo_cached);
+ while (useg && status == 0) {
+ status = i_s_innodb_undo_logs_fill_store(thd, table, useg);
+ useg = UT_LIST_GET_NEXT(undo_list, useg);
+ }
+
+ useg = UT_LIST_GET_FIRST(rseg->insert_undo_list);
+ while (useg && status == 0) {
+ status = i_s_innodb_undo_logs_fill_store(thd, table, useg);
+ useg = UT_LIST_GET_NEXT(undo_list, useg);
+ }
+
+ useg = UT_LIST_GET_FIRST(rseg->insert_undo_cached);
+ while (useg && status == 0) {
+ status = i_s_innodb_undo_logs_fill_store(thd, table, useg);
+ useg = UT_LIST_GET_NEXT(undo_list, useg);
+ }
+ mutex_exit(&(rseg->mutex));
+ rseg = UT_LIST_GET_NEXT(rseg_list, rseg);
+ }
+
+ DBUG_RETURN(status);
+}
+
+static
+int
+i_s_innodb_undo_logs_init(
+/*=================*/
+ /* out: 0 on success */
+ void* p) /* in/out: table schema object */
+{
+ DBUG_ENTER("i_s_innodb_undo_logs_init");
+ ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
+
+ schema->fields_info = i_s_innodb_undo_logs_fields_info;
+ schema->fill_table = i_s_innodb_undo_logs_fill;
+
+ DBUG_RETURN(0);
+}
+
+UNIV_INTERN struct st_mysql_plugin i_s_innodb_undo_logs =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_UNDO_LOGS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Percona"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB rollback undo segment information"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_undo_logs_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ /* reserved for dependency checking */
+ /* void* */
+ STRUCT_FLD(__reserved1, NULL),
+
+ /* Plugin flags */
+ /* unsigned long */
+ STRUCT_FLD(flags, 0UL),
+};
+
+UNIV_INTERN struct st_maria_plugin i_s_innodb_undo_logs_maria =
+{
+ /* the plugin type (a MYSQL_XXX_PLUGIN value) */
+ /* int */
+ STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+
+ /* pointer to type-specific plugin descriptor */
+ /* void* */
+ STRUCT_FLD(info, &i_s_info),
+
+ /* plugin name */
+ /* const char* */
+ STRUCT_FLD(name, "INNODB_UNDO_LOGS"),
+
+ /* plugin author (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(author, "Percona"),
+
+ /* general descriptive text (for SHOW PLUGINS) */
+ /* const char* */
+ STRUCT_FLD(descr, "InnoDB rollback undo segment information"),
+
+ /* the plugin license (PLUGIN_LICENSE_XXX) */
+ /* int */
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+
+ /* the function to invoke when plugin is loaded */
+ /* int (*)(void*); */
+ STRUCT_FLD(init, i_s_innodb_undo_logs_init),
+
+ /* the function to invoke when plugin is unloaded */
+ /* int (*)(void*); */ STRUCT_FLD(deinit, i_s_common_deinit),
+
+ /* plugin version (for SHOW PLUGINS) */
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+
+ /* struct st_mysql_show_var* */
+ STRUCT_FLD(status_vars, NULL),
+
+ /* struct st_mysql_sys_var** */
+ STRUCT_FLD(system_vars, NULL),
+
+ INNODB_VERSION_STR, MariaDB_PLUGIN_MATURITY_STABLE
+};
diff --git a/storage/xtradb/handler/i_s.h b/storage/xtradb/handler/i_s.h
index f39172ea0a9..329cc2f5f91 100644
--- a/storage/xtradb/handler/i_s.h
+++ b/storage/xtradb/handler/i_s.h
@@ -43,6 +43,7 @@ extern struct st_mysql_plugin i_s_innodb_sys_fields;
extern struct st_mysql_plugin i_s_innodb_sys_foreign;
extern struct st_mysql_plugin i_s_innodb_sys_foreign_cols;
extern struct st_mysql_plugin i_s_innodb_rseg;
+extern struct st_mysql_plugin i_s_innodb_undo_logs;
extern struct st_mysql_plugin i_s_innodb_sys_stats;
extern struct st_mysql_plugin i_s_innodb_table_stats;
extern struct st_mysql_plugin i_s_innodb_index_stats;
@@ -67,6 +68,7 @@ extern struct st_maria_plugin i_s_innodb_sys_foreign_maria;
extern struct st_maria_plugin i_s_innodb_sys_foreign_cols_maria;
extern struct st_maria_plugin i_s_innodb_sys_stats_maria;
extern struct st_maria_plugin i_s_innodb_rseg_maria;
+extern struct st_maria_plugin i_s_innodb_undo_logs_maria;
extern struct st_maria_plugin i_s_innodb_table_stats_maria;
extern struct st_maria_plugin i_s_innodb_index_stats_maria;
extern struct st_maria_plugin i_s_innodb_admin_command_maria;
diff --git a/storage/xtradb/include/btr0btr.h b/storage/xtradb/include/btr0btr.h
index 520527d0375..03e89ae3f7d 100644
--- a/storage/xtradb/include/btr0btr.h
+++ b/storage/xtradb/include/btr0btr.h
@@ -92,6 +92,8 @@ insert/delete buffer when the record is not in the buffer pool. */
buffer when the record is not in the buffer pool. */
#define BTR_DELETE 8192
+#endif /* UNIV_HOTBACKUP */
+
/**************************************************************//**
Report that an index page is corrupted. */
UNIV_INTERN
@@ -112,6 +114,7 @@ btr_corruption_report(
ut_error; \
}
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_BLOB_DEBUG
# include "ut0rbt.h"
/** An index->blobs entry for keeping track of off-page column references */
diff --git a/storage/xtradb/include/btr0types.h b/storage/xtradb/include/btr0types.h
index 6f515c3f58c..43c6b425688 100644
--- a/storage/xtradb/include/btr0types.h
+++ b/storage/xtradb/include/btr0types.h
@@ -39,6 +39,8 @@ typedef struct btr_cur_struct btr_cur_t;
/** B-tree search information for the adaptive hash index */
typedef struct btr_search_struct btr_search_t;
+#ifndef UNIV_HOTBACKUP
+
/** @brief The latch protecting the adaptive search system
This latch protects the
@@ -56,6 +58,8 @@ Bear in mind (3) and (4) when using the hash index.
extern rw_lock_t** btr_search_latch_part;
+#endif /* UNIV_HOTBACKUP */
+
/** The latch protecting the adaptive search system */
//#define btr_search_latch (*btr_search_latch_temp)
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index 7502942d681..1a4990be69f 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -608,34 +608,34 @@ ib_uint64_t
buf_block_get_modify_clock(
/*=======================*/
buf_block_t* block); /*!< in: block */
-#else /* !UNIV_HOTBACKUP */
-# define buf_block_modify_clock_inc(block) ((void) 0)
-#endif /* !UNIV_HOTBACKUP */
/*******************************************************************//**
Increments the bufferfix count. */
UNIV_INLINE
void
buf_block_buf_fix_inc_func(
/*=======================*/
-#ifdef UNIV_SYNC_DEBUG
+# ifdef UNIV_SYNC_DEBUG
const char* file, /*!< in: file name */
ulint line, /*!< in: line */
-#endif /* UNIV_SYNC_DEBUG */
+# endif /* UNIV_SYNC_DEBUG */
buf_block_t* block) /*!< in/out: block to bufferfix */
__attribute__((nonnull));
-#ifdef UNIV_SYNC_DEBUG
+# ifdef UNIV_SYNC_DEBUG
/** Increments the bufferfix count.
@param b in/out: block to bufferfix
@param f in: file name where requested
@param l in: line number where requested */
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
-#else /* UNIV_SYNC_DEBUG */
+# else /* UNIV_SYNC_DEBUG */
/** Increments the bufferfix count.
@param b in/out: block to bufferfix
@param f in: file name where requested
@param l in: line number where requested */
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
-#endif /* UNIV_SYNC_DEBUG */
+# endif /* UNIV_SYNC_DEBUG */
+#else /* !UNIV_HOTBACKUP */
+# define buf_block_modify_clock_inc(block) ((void) 0)
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Calculates a page checksum which is stored to the page when it is written
to a file. Note that we must be careful to calculate the same value
@@ -1063,8 +1063,10 @@ buf_block_get_frame(
/*================*/
const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
+# define buf_block_get_frame_fast(block) buf_block_get_frame(block)
#else /* UNIV_DEBUG */
# define buf_block_get_frame(block) (block ? (block)->frame : 0)
+# define buf_block_get_frame_fast(block) (block)->frame
#endif /* UNIV_DEBUG */
/*********************************************************************//**
Gets the space id of a block.
@@ -1191,9 +1193,10 @@ buf_page_init_for_read(
ulint offset);/*!< in: page number */
/********************************************************************//**
Completes an asynchronous read or write request of a file page to or from
-the buffer pool. */
+the buffer pool.
+@return TRUE if successful */
UNIV_INTERN
-void
+ibool
buf_page_io_complete(
/*=================*/
buf_page_t* bpage); /*!< in: pointer to the block in question */
diff --git a/storage/xtradb/include/buf0buf.ic b/storage/xtradb/include/buf0buf.ic
index 66006d366c6..6595e86a8fe 100644
--- a/storage/xtradb/include/buf0buf.ic
+++ b/storage/xtradb/include/buf0buf.ic
@@ -31,6 +31,7 @@ Created 11/5/1995 Heikki Tuuri
*******************************************************/
#include "mtr0mtr.h"
+#ifndef UNIV_HOTBACKUP
#include "buf0flu.h"
#include "buf0lru.h"
#include "buf0rea.h"
@@ -180,6 +181,7 @@ buf_page_peek_if_too_old(
return(!buf_page_peek_if_young(bpage));
}
}
+#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
Gets the state of a block.
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index 6974e480144..de3605b1dfb 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -750,6 +750,7 @@ ulint
dict_table_zip_size(
/*================*/
const dict_table_t* table); /*!< in: table */
+#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Obtain exclusive locks on all index trees of the table. This is to prevent
accessing index trees while InnoDB is updating internal metadata for
@@ -766,6 +767,7 @@ void
dict_table_x_unlock_indexes(
/*========================*/
dict_table_t* table); /*!< in: table */
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Checks if a column is in the ordering columns of the clustered index of a
table. Column prefixes are treated like whole columns.
@@ -1278,7 +1280,7 @@ UNIV_INTERN
void
dict_close(void);
/*============*/
-
+#ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Check whether the table is corrupted.
@return nonzero for corrupted table, zero for valid tables */
@@ -1299,6 +1301,7 @@ dict_index_is_corrupted(
const dict_index_t* index) /*!< in: index */
__attribute__((nonnull, pure, warn_unused_result));
+#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
Flags an index and table corrupted both in the data dictionary cache
and in the system table SYS_INDEXES. */
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index 5ed9b182d6c..02eafcc5d9c 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -491,6 +491,7 @@ dict_table_zip_size(
return(dict_table_flags_to_zip_size(table->flags));
}
+#ifndef UNIV_HOTBACKUP
/*********************************************************************//**
Obtain exclusive locks on all index trees of the table. This is to prevent
accessing index trees while InnoDB is updating internal metadata for
@@ -533,6 +534,7 @@ dict_table_x_unlock_indexes(
rw_lock_x_unlock(dict_index_get_lock(index));
}
}
+#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
Gets the number of fields in the internal representation of an index,
including fields added by the dictionary system.
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index 2e200ba7f43..2907365a32a 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -312,4 +312,15 @@ innobase_get_lower_case_table_names(void);
/*=====================================*/
+/********************************************************************//**
+Returns the merge-sort block size used for the secondary index creation
+for the current connection.
+@return the merge-sort block size, in bytes */
+
+ulong
+thd_merge_sort_block_size(
+/*======================*/
+ void* thd); /*!< in: thread handle (THD*), or NULL to query
+ the global merge_sort_block_size */
+
#endif
diff --git a/storage/xtradb/include/log0log.h b/storage/xtradb/include/log0log.h
index 6b1c2859cf7..857ec0946c2 100644
--- a/storage/xtradb/include/log0log.h
+++ b/storage/xtradb/include/log0log.h
@@ -780,7 +780,6 @@ struct log_struct{
buffer */
#ifndef UNIV_HOTBACKUP
mutex_t mutex; /*!< mutex protecting the log */
-#endif /* !UNIV_HOTBACKUP */
mutex_t log_flush_order_mutex;/*!< mutex to serialize access to
the flush list when we are putting
@@ -790,6 +789,7 @@ struct log_struct{
mtr_commit and still ensure that
insertions in the flush_list happen
in the LSN order. */
+#endif /* !UNIV_HOTBACKUP */
byte* buf_ptr; /* unaligned log buffer */
byte* buf; /*!< log buffer */
ulint buf_size; /*!< log buffer size in bytes */
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index b153b0dba7f..5b1f9339845 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -316,7 +316,7 @@ to original un-instrumented file I/O APIs */
os_file_create_func(name, create, purpose, type, success)
# define os_file_create_simple(key, name, create, access, success) \
- os_file_create_simple_func(name, create_mode, access, success)
+ os_file_create_simple_func(name, create, access, success)
# define os_file_create_simple_no_error_handling( \
key, name, create_mode, access, success) \
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index e6db7fab158..a40683e00f1 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -117,13 +117,13 @@ extern ulint srv_max_file_format_at_startup;
/** Place locks to records only i.e. do not use next-key locking except
on duplicate key checking and foreign key checking */
extern ibool srv_locks_unsafe_for_binlog;
-#endif /* !UNIV_HOTBACKUP */
/* If this flag is TRUE, then we will use the native aio of the
OS (provided we compiled Innobase with it in), otherwise we will
use simulated aio we build below with threads.
Currently we support native aio on windows and linux */
extern my_bool srv_use_native_aio;
+#endif /* !UNIV_HOTBACKUP */
#ifdef __WIN__
extern ibool srv_use_native_conditions;
#endif
@@ -301,6 +301,7 @@ extern ibool srv_print_latch_waits;
extern ulint srv_activity_count;
extern ulint srv_fatal_semaphore_wait_threshold;
+#define SRV_SEMAPHORE_WAIT_EXTENSION 7200
extern ulint srv_dml_needed_delay;
extern long long srv_kill_idle_transaction;
diff --git a/storage/xtradb/include/trx0sys.h b/storage/xtradb/include/trx0sys.h
index 976cb31563f..c933fb405e1 100644
--- a/storage/xtradb/include/trx0sys.h
+++ b/storage/xtradb/include/trx0sys.h
@@ -248,7 +248,6 @@ UNIV_INLINE
trx_id_t
trx_sys_get_new_trx_id(void);
/*========================*/
-#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_DEBUG
/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
@@ -265,7 +264,6 @@ trx_write_trx_id(
/*=============*/
byte* ptr, /*!< in: pointer to memory where written */
trx_id_t id); /*!< in: id */
-#ifndef UNIV_HOTBACKUP
/*****************************************************************//**
Reads a trx id from an index page. In case that the id size changes in
some future version, this function should be used instead of
@@ -603,7 +601,6 @@ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO. */
#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
/* @} */
-#ifndef UNIV_HOTBACKUP
/** File format tag */
/* @{ */
/** The offset of the file format tag on the trx system header page
@@ -622,6 +619,7 @@ identifier is added to this 64-bit constant. */
| TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW)
/* @} */
+#ifndef UNIV_HOTBACKUP
/** Doublewrite control struct */
struct trx_doublewrite_struct{
mutex_t mutex; /*!< mutex protecting the first_free field and
diff --git a/storage/xtradb/include/trx0trx.h b/storage/xtradb/include/trx0trx.h
index eded5c303fa..a03f7aceafa 100644
--- a/storage/xtradb/include/trx0trx.h
+++ b/storage/xtradb/include/trx0trx.h
@@ -494,7 +494,6 @@ struct trx_struct{
this is set to 1 then registered should
also be set to 1. This is used in the
XA code */
- unsigned called_commit_ordered:1;/* 1 if innobase_commit_ordered has run. */
/*------------------------------*/
ulint isolation_level;/* TRX_ISO_REPEATABLE_READ, ... */
ulint check_foreigns; /* normally TRUE, but if the user
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index f4b06ccefa4..ce59a3f2741 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -54,10 +54,7 @@ Created 1/20/1994 Heikki Tuuri
#define INNODB_VERSION_BUGFIX 8
#ifndef PERCONA_INNODB_VERSION
-/* this is *not* the version of XtraDB as in Percona-Server sources,
- but the version of Percona-Server, where this XtraDB was taken from.
- Because Percona does not update XtraDB version for every release */
-#define PERCONA_INNODB_VERSION 26.0
+#define PERCONA_INNODB_VERSION 28.1
#endif
/* The following is the InnoDB version as shown in
diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c
index c4429af5112..a554c576b6d 100644
--- a/storage/xtradb/log/log0recv.c
+++ b/storage/xtradb/log/log0recv.c
@@ -2980,7 +2980,7 @@ recv_recovery_from_checkpoint_start_func(
ib_uint64_t checkpoint_lsn;
ib_uint64_t checkpoint_no;
ib_uint64_t old_scanned_lsn;
- ib_uint64_t group_scanned_lsn;
+ ib_uint64_t group_scanned_lsn= 0;
ib_uint64_t contiguous_lsn;
#ifdef UNIV_LOG_ARCHIVE
ib_uint64_t archived_lsn;
diff --git a/storage/xtradb/mem/mem0dbg.c b/storage/xtradb/mem/mem0dbg.c
index ae43d6097a6..0909b7c9a64 100644
--- a/storage/xtradb/mem/mem0dbg.c
+++ b/storage/xtradb/mem/mem0dbg.c
@@ -24,7 +24,9 @@ but is included in mem0mem.* !
Created 6/9/1994 Heikki Tuuri
*************************************************************************/
-#include "ha_prototypes.h"
+#ifndef UNIV_HOTBACKUP
+# include "ha_prototypes.h"
+#endif /* !UNIV_HOTBACKUP */
#ifdef UNIV_MEM_DEBUG
# ifndef UNIV_HOTBACKUP
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index 5d249d52ce9..061d556c6e7 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -303,6 +303,7 @@ UNIV_INTERN ulint os_n_pending_writes = 0;
UNIV_INTERN ulint os_n_pending_reads = 0;
#ifdef UNIV_DEBUG
+# ifndef UNIV_HOTBACKUP
/**********************************************************************//**
Validates the consistency the aio system some of the time.
@return TRUE if ok or the check was skipped */
@@ -329,6 +330,7 @@ os_aio_validate_skip(void)
os_aio_validate_count = OS_AIO_VALIDATE_SKIP;
return(os_aio_validate());
}
+# endif /* !UNIV_HOTBACKUP */
#endif /* UNIV_DEBUG */
#ifdef _WIN32
diff --git a/storage/xtradb/page/page0zip.c b/storage/xtradb/page/page0zip.c
index d4b0dd8339d..4751f4816a9 100644
--- a/storage/xtradb/page/page0zip.c
+++ b/storage/xtradb/page/page0zip.c
@@ -4437,7 +4437,9 @@ page_zip_reorganize(
dict_index_t* index, /*!< in: index of the B-tree node */
mtr_t* mtr) /*!< in: mini-transaction */
{
+#ifndef UNIV_HOTBACKUP
buf_pool_t* buf_pool = buf_pool_from_block(block);
+#endif /* !UNIV_HOTBACKUP */
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
page_t* page = buf_block_get_frame(block);
buf_block_t* temp_block;
diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c
index a629a4fb195..b21d48c7552 100644
--- a/storage/xtradb/row/row0ins.c
+++ b/storage/xtradb/row/row0ins.c
@@ -1281,7 +1281,8 @@ run_again:
check_index = foreign->foreign_index;
}
- if (check_table == NULL || check_table->ibd_file_missing) {
+ if (check_table == NULL || check_table->ibd_file_missing
+ || check_index == NULL) {
if (check_ref) {
FILE* ef = dict_foreign_err_file;
@@ -1316,9 +1317,6 @@ run_again:
goto exit_func;
}
- ut_a(check_table);
- ut_a(check_index);
-
if (check_table != table) {
/* We already have a LOCK_IX on table, but not necessarily
on check_table */
diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c
index f00706da0d3..c7d6304d6a7 100644
--- a/storage/xtradb/row/row0merge.c
+++ b/storage/xtradb/row/row0merge.c
@@ -89,8 +89,9 @@ rounded to a power of 2.
When not creating a PRIMARY KEY that contains column prefixes, this
can be set as small as UNIV_PAGE_SIZE / 2. See the comment above
-ut_ad(data_size < sizeof(row_merge_block_t)). */
-typedef byte row_merge_block_t[1048576];
+ut_ad(data_size < sizeof(row_merge_block_t)).
+1MB is the default merge-sort block size for innodb */
+typedef byte* row_merge_block_t;
/** @brief Secondary buffer for I/O operations of merge records.
@@ -184,7 +185,6 @@ row_merge_buf_create_low(
row_merge_buf_t* buf;
ut_ad(max_tuples > 0);
- ut_ad(max_tuples <= sizeof(row_merge_block_t));
ut_ad(max_tuples < buf_size);
buf = mem_heap_zalloc(heap, buf_size);
@@ -205,19 +205,19 @@ static
row_merge_buf_t*
row_merge_buf_create(
/*=================*/
- dict_index_t* index) /*!< in: secondary index */
+ dict_index_t* index, /*!< in: secondary index */
+ ulint block_size) /*!< in: merge block buffer size */
{
row_merge_buf_t* buf;
ulint max_tuples;
ulint buf_size;
mem_heap_t* heap;
- max_tuples = sizeof(row_merge_block_t)
- / ut_max(1, dict_index_get_min_size(index));
+ max_tuples = block_size / ut_max(1, dict_index_get_min_size(index));
buf_size = (sizeof *buf) + (max_tuples - 1) * sizeof *buf->tuples;
- heap = mem_heap_create(buf_size + sizeof(row_merge_block_t));
+ heap = mem_heap_create(buf_size + block_size);
buf = row_merge_buf_create_low(heap, index, max_tuples, buf_size);
@@ -265,8 +265,10 @@ row_merge_buf_add(
/*==============*/
row_merge_buf_t* buf, /*!< in/out: sort buffer */
const dtuple_t* row, /*!< in: row in clustered index */
- const row_ext_t* ext) /*!< in: cache of externally stored
+ const row_ext_t* ext, /*!< in: cache of externally stored
column prefixes, or NULL */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
ulint i;
ulint n_fields;
@@ -391,10 +393,10 @@ row_merge_buf_add(
page_zip_rec_needs_ext() limit. However, no further columns
will be moved to external storage until the record is inserted
to the clustered index B-tree. */
- ut_ad(data_size < sizeof(row_merge_block_t));
+ ut_ad(data_size < block_size);
/* Reserve one byte for the end marker of row_merge_block_t. */
- if (buf->total_size + data_size >= sizeof(row_merge_block_t) - 1) {
+ if (buf->total_size + data_size >= block_size - 1) {
return(FALSE);
}
@@ -700,9 +702,11 @@ row_merge_read(
ulint offset, /*!< in: offset where to read
in number of row_merge_block_t
elements */
- row_merge_block_t* buf) /*!< out: data */
+ row_merge_block_t buf, /*!< out: data */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
- ib_uint64_t ofs = ((ib_uint64_t) offset) * sizeof *buf;
+ ib_uint64_t ofs = ((ib_uint64_t) offset) * block_size;
ibool success;
#ifdef UNIV_DEBUG
@@ -715,7 +719,7 @@ row_merge_read(
success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf,
(ulint) (ofs & 0xFFFFFFFF),
(ulint) (ofs >> 32),
- sizeof *buf);
+ block_size);
#ifdef POSIX_FADV_DONTNEED
/* Each block is read exactly once. Free up the file cache. */
posix_fadvise(fd, ofs, sizeof *buf, POSIX_FADV_DONTNEED);
@@ -740,16 +744,17 @@ row_merge_write(
int fd, /*!< in: file descriptor */
ulint offset, /*!< in: offset where to write,
in number of row_merge_block_t elements */
- const void* buf) /*!< in: data */
+ const void* buf, /*!< in: data */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
- size_t buf_len = sizeof(row_merge_block_t);
- ib_uint64_t ofs = buf_len * (ib_uint64_t) offset;
+ ib_uint64_t ofs = block_size * (ib_uint64_t) offset;
ibool ret;
ret = os_file_write("(merge)", OS_FILE_FROM_FD(fd), buf,
(ulint) (ofs & 0xFFFFFFFF),
(ulint) (ofs >> 32),
- buf_len);
+ block_size);
#ifdef UNIV_DEBUG
if (row_merge_print_block_write) {
@@ -761,7 +766,7 @@ row_merge_write(
#ifdef POSIX_FADV_DONTNEED
/* The block will be needed on the next merge pass,
but it can be evicted from the file cache meanwhile. */
- posix_fadvise(fd, ofs, buf_len, POSIX_FADV_DONTNEED);
+ posix_fadvise(fd, ofs, block_size, POSIX_FADV_DONTNEED);
#endif /* POSIX_FADV_DONTNEED */
return(UNIV_LIKELY(ret));
@@ -783,7 +788,9 @@ row_merge_read_rec(
const mrec_t** mrec, /*!< out: pointer to merge record,
or NULL on end of list
(non-NULL on I/O error) */
- ulint* offsets)/*!< out: offsets of mrec */
+ ulint* offsets,/*!< out: offsets of mrec */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
ulint extra_size;
ulint data_size;
@@ -820,7 +827,8 @@ row_merge_read_rec(
/* Read another byte of extra_size. */
if (UNIV_UNLIKELY(b >= block[1])) {
- if (!row_merge_read(fd, ++(*foffs), block)) {
+ if (!row_merge_read(fd, ++(*foffs), block[0],
+ block_size)) {
err_exit:
/* Signal I/O error. */
*mrec = b;
@@ -849,7 +857,8 @@ err_exit:
memcpy(*buf, b, avail_size);
- if (!row_merge_read(fd, ++(*foffs), block)) {
+ if (!row_merge_read(fd, ++(*foffs), block[0],
+ block_size)) {
goto err_exit;
}
@@ -870,7 +879,7 @@ err_exit:
/* These overflows should be impossible given that
records are much smaller than either buffer, and
the record starts near the beginning of each buffer. */
- ut_a(extra_size + data_size < sizeof *buf);
+ ut_a(extra_size + data_size < block_size);
ut_a(b + data_size < block[1]);
/* Copy the data bytes. */
@@ -885,7 +894,7 @@ err_exit:
rec_init_offsets_comp_ordinary(*mrec, 0, index, offsets);
data_size = rec_offs_data_size(offsets);
- ut_ad(extra_size + data_size < sizeof *buf);
+ ut_ad(extra_size + data_size < block_size);
b += extra_size + data_size;
@@ -910,7 +919,8 @@ err_exit:
offsets[3] = (ulint) index;
#endif /* UNIV_DEBUG */
- if (!row_merge_read(fd, ++(*foffs), block)) {
+ if (!row_merge_read(fd, ++(*foffs), block[0],
+ block_size)) {
goto err_exit;
}
@@ -992,7 +1002,9 @@ row_merge_write_rec(
int fd, /*!< in: file descriptor */
ulint* foffs, /*!< in/out: file offset */
const mrec_t* mrec, /*!< in: record to write */
- const ulint* offsets)/*!< in: offsets of mrec */
+ const ulint* offsets,/*!< in: offsets of mrec */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
ulint extra_size;
ulint size;
@@ -1027,11 +1039,12 @@ row_merge_write_rec(
record to the head of the new block. */
memcpy(b, buf[0], avail_size);
- if (!row_merge_write(fd, (*foffs)++, block)) {
+ if (!row_merge_write(fd, (*foffs)++, block[0],
+ block_size)) {
return(NULL);
}
- UNIV_MEM_INVALID(block[0], sizeof block[0]);
+ UNIV_MEM_INVALID(block[0], block_size);
/* Copy the rest. */
b = block[0];
@@ -1056,7 +1069,9 @@ row_merge_write_eof(
row_merge_block_t* block, /*!< in/out: file buffer */
byte* b, /*!< in: pointer to end of block */
int fd, /*!< in: file descriptor */
- ulint* foffs) /*!< in/out: file offset */
+ ulint* foffs, /*!< in/out: file offset */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
ut_ad(block);
ut_ad(b >= block[0]);
@@ -1071,18 +1086,19 @@ row_merge_write_eof(
*b++ = 0;
UNIV_MEM_ASSERT_RW(block[0], b - block[0]);
- UNIV_MEM_ASSERT_W(block[0], sizeof block[0]);
+ UNIV_MEM_ASSERT_W(block[0], block_size);
#ifdef UNIV_DEBUG_VALGRIND
/* The rest of the block is uninitialized. Initialize it
to avoid bogus warnings. */
memset(b, 0xff, block[1] - b);
#endif /* UNIV_DEBUG_VALGRIND */
- if (!row_merge_write(fd, (*foffs)++, block)) {
+ if (!row_merge_write(fd, (*foffs)++, block[0],
+ block_size)) {
return(NULL);
}
- UNIV_MEM_INVALID(block[0], sizeof block[0]);
+ UNIV_MEM_INVALID(block[0], block_size);
return(block[0]);
}
@@ -1140,7 +1156,9 @@ row_merge_read_clustered_index(
dict_index_t** index, /*!< in: indexes to be created */
merge_file_t* files, /*!< in: temporary files */
ulint n_index,/*!< in: number of indexes to create */
- row_merge_block_t* block) /*!< in/out: file buffer */
+ row_merge_block_t* block, /*!< in/out: file buffer */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
dict_index_t* clust_index; /* Clustered index */
mem_heap_t* row_heap; /* Heap memory to create
@@ -1168,7 +1186,7 @@ row_merge_read_clustered_index(
merge_buf = mem_alloc(n_index * sizeof *merge_buf);
for (i = 0; i < n_index; i++) {
- merge_buf[i] = row_merge_buf_create(index[i]);
+ merge_buf[i] = row_merge_buf_create(index[i], block_size);
}
mtr_start(&mtr);
@@ -1300,7 +1318,8 @@ row_merge_read_clustered_index(
const dict_index_t* index = buf->index;
if (UNIV_LIKELY
- (row && row_merge_buf_add(buf, row, ext))) {
+ (row && row_merge_buf_add(buf, row, ext,
+ block_size))) {
file->n_rec++;
continue;
}
@@ -1335,12 +1354,12 @@ err_exit:
row_merge_buf_write(buf, file, block);
if (!row_merge_write(file->fd, file->offset++,
- block)) {
+ block[0], block_size)) {
err = DB_OUT_OF_FILE_SPACE;
goto err_exit;
}
- UNIV_MEM_INVALID(block[0], sizeof block[0]);
+ UNIV_MEM_INVALID(block[0], block_size);
merge_buf[i] = row_merge_buf_empty(buf);
if (UNIV_LIKELY(row != NULL)) {
@@ -1349,7 +1368,8 @@ err_exit:
and emptied. */
if (UNIV_UNLIKELY
- (!row_merge_buf_add(buf, row, ext))) {
+ (!row_merge_buf_add(buf, row, ext,
+ block_size))) {
/* An empty buffer should have enough
room for at least one record. */
ut_error;
@@ -1393,14 +1413,16 @@ func_exit:
do { \
b2 = row_merge_write_rec(&block[2], &buf[2], b2, \
of->fd, &of->offset, \
- mrec##N, offsets##N); \
+ mrec##N, offsets##N, \
+ block_size); \
if (UNIV_UNLIKELY(!b2 || ++of->n_rec > file->n_rec)) { \
goto corrupt; \
} \
b##N = row_merge_read_rec(&block[N], &buf[N], \
b##N, index, \
file->fd, foffs##N, \
- &mrec##N, offsets##N); \
+ &mrec##N, offsets##N, \
+ block_size); \
if (UNIV_UNLIKELY(!b##N)) { \
if (mrec##N) { \
goto corrupt; \
@@ -1425,9 +1447,11 @@ row_merge_blocks(
ulint* foffs1, /*!< in/out: offset of second
source list in the file */
merge_file_t* of, /*!< in/out: output file */
- struct TABLE* table) /*!< in/out: MySQL table, for
+ struct TABLE* table, /*!< in/out: MySQL table, for
reporting erroneous key value
if applicable */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
@@ -1457,8 +1481,10 @@ row_merge_blocks(
/* Write a record and read the next record. Split the output
file in two halves, which can be merged on the following pass. */
- if (!row_merge_read(file->fd, *foffs0, &block[0])
- || !row_merge_read(file->fd, *foffs1, &block[1])) {
+ if (!row_merge_read(file->fd, *foffs0, block[0],
+ block_size)
+ || !row_merge_read(file->fd, *foffs1, block[1],
+ block_size)) {
corrupt:
mem_heap_free(heap);
return(DB_CORRUPTION);
@@ -1469,9 +1495,9 @@ corrupt:
b2 = block[2];
b0 = row_merge_read_rec(&block[0], &buf[0], b0, index, file->fd,
- foffs0, &mrec0, offsets0);
+ foffs0, &mrec0, offsets0, block_size);
b1 = row_merge_read_rec(&block[1], &buf[1], b1, index, file->fd,
- foffs1, &mrec1, offsets1);
+ foffs1, &mrec1, offsets1, block_size);
if (UNIV_UNLIKELY(!b0 && mrec0)
|| UNIV_UNLIKELY(!b1 && mrec1)) {
@@ -1521,7 +1547,8 @@ done0:
done1:
mem_heap_free(heap);
- b2 = row_merge_write_eof(&block[2], b2, of->fd, &of->offset);
+ b2 = row_merge_write_eof(&block[2], b2, of->fd, &of->offset,
+ block_size);
return(b2 ? DB_SUCCESS : DB_CORRUPTION);
}
@@ -1536,7 +1563,9 @@ row_merge_blocks_copy(
const merge_file_t* file, /*!< in: input file */
row_merge_block_t* block, /*!< in/out: 3 buffers */
ulint* foffs0, /*!< in/out: input file offset */
- merge_file_t* of) /*!< in/out: output file */
+ merge_file_t* of, /*!< in/out: output file */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
mem_heap_t* heap; /*!< memory heap for offsets0, offsets1 */
@@ -1563,7 +1592,7 @@ row_merge_blocks_copy(
/* Write a record and read the next record. Split the output
file in two halves, which can be merged on the following pass. */
- if (!row_merge_read(file->fd, *foffs0, &block[0])) {
+ if (!row_merge_read(file->fd, *foffs0, block[0], block_size)) {
corrupt:
mem_heap_free(heap);
return(FALSE);
@@ -1573,7 +1602,7 @@ corrupt:
b2 = block[2];
b0 = row_merge_read_rec(&block[0], &buf[0], b0, index, file->fd,
- foffs0, &mrec0, offsets0);
+ foffs0, &mrec0, offsets0, block_size);
if (UNIV_UNLIKELY(!b0 && mrec0)) {
goto corrupt;
@@ -1592,8 +1621,8 @@ done0:
(*foffs0)++;
mem_heap_free(heap);
- return(row_merge_write_eof(&block[2], b2, of->fd, &of->offset)
- != NULL);
+ return(row_merge_write_eof(&block[2], b2, of->fd, &of->offset,
+ block_size) != NULL);
}
/*************************************************************//**
@@ -1614,9 +1643,10 @@ row_merge(
if applicable */
ulint* num_run,/*!< in/out: Number of runs remain
to be merged */
- ulint* run_offset) /*!< in/out: Array contains the
+ ulint* run_offset, /*!< in/out: Array contains the
first offset number for each merge
run */
+ ulint block_size) /*!< in: merge block buffer size */
{
ulint foffs0; /*!< first input offset */
ulint foffs1; /*!< second input offset */
@@ -1627,7 +1657,7 @@ row_merge(
ulint n_run = 0;
/*!< num of runs generated from this merge */
- UNIV_MEM_ASSERT_W(block[0], 3 * sizeof block[0]);
+ UNIV_MEM_ASSERT_W(block[0], 3 * block_size);
ut_ad(ihalf < file->offset);
@@ -1659,7 +1689,8 @@ row_merge(
run_offset[n_run++] = of.offset;
error = row_merge_blocks(index, file, block,
- &foffs0, &foffs1, &of, table);
+ &foffs0, &foffs1, &of, table,
+ block_size);
if (error != DB_SUCCESS) {
return(error);
@@ -1677,7 +1708,8 @@ row_merge(
/* Remember the offset number for this run */
run_offset[n_run++] = of.offset;
- if (!row_merge_blocks_copy(index, file, block, &foffs0, &of)) {
+ if (!row_merge_blocks_copy(index, file, block, &foffs0, &of,
+ block_size)) {
return(DB_CORRUPTION);
}
}
@@ -1692,7 +1724,8 @@ row_merge(
/* Remember the offset number for this run */
run_offset[n_run++] = of.offset;
- if (!row_merge_blocks_copy(index, file, block, &foffs1, &of)) {
+ if (!row_merge_blocks_copy(index, file, block, &foffs1, &of,
+ block_size)) {
return(DB_CORRUPTION);
}
}
@@ -1721,7 +1754,7 @@ row_merge(
*tmpfd = file->fd;
*file = of;
- UNIV_MEM_INVALID(block[0], 3 * sizeof block[0]);
+ UNIV_MEM_INVALID(block[0], 3 * block_size);
return(DB_SUCCESS);
}
@@ -1739,9 +1772,11 @@ row_merge_sort(
index entries */
row_merge_block_t* block, /*!< in/out: 3 buffers */
int* tmpfd, /*!< in/out: temporary file handle */
- struct TABLE* table) /*!< in/out: MySQL table, for
+ struct TABLE* table, /*!< in/out: MySQL table, for
reporting erroneous key value
if applicable */
+ ulint block_size)
+ /*!< in: merge block buffer size */
{
ulint half = file->offset / 2;
ulint num_runs;
@@ -1770,7 +1805,7 @@ row_merge_sort(
/* Merge the runs until we have one big run */
do {
error = row_merge(trx, index, file, block, tmpfd,
- table, &num_runs, run_offset);
+ table, &num_runs, run_offset, block_size);
UNIV_MEM_ASSERT_RW(run_offset, num_runs * sizeof *run_offset);
@@ -1841,7 +1876,9 @@ row_merge_insert_index_tuples(
ulint zip_size,/*!< in: compressed page size of
the old table, or 0 if uncompressed */
int fd, /*!< in: file descriptor */
- row_merge_block_t* block) /*!< in/out: file buffer */
+ row_merge_block_t* block, /*!< in/out: file buffer */
+ ulint block_size)
+ /*! in: merge block buffer size */
{
const byte* b;
que_thr_t* thr;
@@ -1880,7 +1917,7 @@ row_merge_insert_index_tuples(
b = *block;
- if (!row_merge_read(fd, foffs, block)) {
+ if (!row_merge_read(fd, foffs, block[0], block_size)) {
error = DB_CORRUPTION;
} else {
mrec_buf_t* buf = mem_heap_alloc(graph_heap, sizeof *buf);
@@ -1891,7 +1928,8 @@ row_merge_insert_index_tuples(
ulint n_ext;
b = row_merge_read_rec(block, buf, b, index,
- fd, &foffs, &mrec, offsets);
+ fd, &foffs, &mrec, offsets,
+ block_size);
if (UNIV_UNLIKELY(!b)) {
/* End of list, or I/O error */
if (mrec) {
@@ -2656,11 +2694,16 @@ row_merge_build_indexes(
if applicable */
{
merge_file_t* merge_files;
- row_merge_block_t* block;
+ /* Some code uses block[1] as the synonym for block + block_size. So
+ we initialize block[3] to the address boundary of block[2], even
+ though space for 3 only buffers is allocated. */
+ row_merge_block_t block[4];
ulint block_size;
ulint i;
ulint error;
int tmpfd;
+ ulint merge_sort_block_size;
+ void* block_mem;
ut_ad(trx);
ut_ad(old_table);
@@ -2668,14 +2711,21 @@ row_merge_build_indexes(
ut_ad(indexes);
ut_ad(n_indexes);
+ merge_sort_block_size = thd_merge_sort_block_size(trx->mysql_thd);
+
trx_start_if_not_started(trx);
/* Allocate memory for merge file data structure and initialize
fields */
merge_files = mem_alloc(n_indexes * sizeof *merge_files);
- block_size = 3 * sizeof *block;
- block = os_mem_alloc_large(&block_size);
+ block_size = 3 * merge_sort_block_size;
+ block_mem = os_mem_alloc_large(&block_size);
+
+ for (i = 0; i < UT_ARR_SIZE(block); i++) {
+ block[i] = (row_merge_block_t ) ((byte *) block_mem +
+ i * merge_sort_block_size);
+ }
for (i = 0; i < n_indexes; i++) {
@@ -2693,7 +2743,7 @@ row_merge_build_indexes(
error = row_merge_read_clustered_index(
trx, table, old_table, new_table, indexes,
- merge_files, n_indexes, block);
+ merge_files, n_indexes, block, merge_sort_block_size);
if (error != DB_SUCCESS) {
@@ -2705,13 +2755,15 @@ row_merge_build_indexes(
for (i = 0; i < n_indexes; i++) {
error = row_merge_sort(trx, indexes[i], &merge_files[i],
- block, &tmpfd, table);
+ block, &tmpfd, table,
+ merge_sort_block_size);
if (error == DB_SUCCESS) {
error = row_merge_insert_index_tuples(
trx, indexes[i], new_table,
dict_table_zip_size(old_table),
- merge_files[i].fd, block);
+ merge_files[i].fd, block,
+ merge_sort_block_size);
}
/* Close the temporary file to free up space. */
@@ -2731,7 +2783,7 @@ func_exit:
}
mem_free(merge_files);
- os_mem_free_large(block, block_size);
+ os_mem_free_large(block_mem, block_size);
return(error);
}
diff --git a/storage/xtradb/row/row0vers.c b/storage/xtradb/row/row0vers.c
index 5fd7d082194..6d83dbaf8ee 100644
--- a/storage/xtradb/row/row0vers.c
+++ b/storage/xtradb/row/row0vers.c
@@ -209,17 +209,6 @@ row_vers_impl_x_locked_off_kernel(
prev_trx_id = row_get_rec_trx_id(prev_version, clust_index,
clust_offsets);
- /* If the trx_id and prev_trx_id are different and if
- the prev_version is marked deleted then the
- prev_trx_id must have already committed for the trx_id
- to be able to modify the row. Therefore, prev_trx_id
- cannot hold any implicit lock. */
- if (vers_del && trx_id != prev_trx_id) {
-
- mutex_enter(&kernel_mutex);
- break;
- }
-
/* The stack of versions is locked by mtr. Thus, it
is safe to fetch the prefixes for externally stored
columns. */
diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c
index 75e8097ee0b..d1329f445aa 100644
--- a/storage/xtradb/srv/srv0start.c
+++ b/storage/xtradb/srv/srv0start.c
@@ -1512,8 +1512,7 @@ innobase_start_or_create_for_mysql(void)
if (!os_aio_init(io_limit,
srv_n_read_io_threads,
srv_n_write_io_threads,
- SRV_MAX_N_PENDING_SYNC_IOS))
- {
+ SRV_MAX_N_PENDING_SYNC_IOS)) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Fatal error: cannot initialize AIO"
diff --git a/storage/xtradb/sync/sync0arr.c b/storage/xtradb/sync/sync0arr.c
index b47c32f5bbf..5f293ad6a55 100644
--- a/storage/xtradb/sync/sync0arr.c
+++ b/storage/xtradb/sync/sync0arr.c
@@ -926,6 +926,11 @@ sync_array_print_long_waits(
ibool fatal = FALSE;
double longest_diff = 0;
+ /* For huge tables, skip the check during CHECK TABLE etc... */
+ if (fatal_timeout > SRV_SEMAPHORE_WAIT_EXTENSION) {
+ return(FALSE);
+ }
+
#ifdef UNIV_DEBUG_VALGRIND
/* Increase the timeouts if running under valgrind because it executes
extremely slowly. UNIV_DEBUG_VALGRIND does not necessary mean that
diff --git a/storage/xtradb/trx/trx0sys.c b/storage/xtradb/trx/trx0sys.c
index dd869a787bd..7d303c2563c 100644
--- a/storage/xtradb/trx/trx0sys.c
+++ b/storage/xtradb/trx/trx0sys.c
@@ -137,12 +137,12 @@ UNIV_INTERN mysql_pfs_key_t trx_doublewrite_mutex_key;
UNIV_INTERN mysql_pfs_key_t file_format_max_mutex_key;
#endif /* UNIV_PFS_MUTEX */
+#ifndef UNIV_HOTBACKUP
#ifdef UNIV_DEBUG
/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
uint trx_rseg_n_slots_debug = 0;
#endif
-#ifndef UNIV_HOTBACKUP
/** This is used to track the maximum file format id known to InnoDB. It's
updated via SET GLOBAL innodb_file_format_max = 'x' or when we open
or create a table. */
diff --git a/storage/xtradb/trx/trx0trx.c b/storage/xtradb/trx/trx0trx.c
index c9fccaad16b..b703a04b1b0 100644
--- a/storage/xtradb/trx/trx0trx.c
+++ b/storage/xtradb/trx/trx0trx.c
@@ -1099,7 +1099,8 @@ trx_commit_off_kernel(
trx->must_flush_log_later = TRUE;
} else if (flush_log_at_trx_commit == 0) {
/* Do nothing */
- } else if (flush_log_at_trx_commit == 1) {
+ } else if (flush_log_at_trx_commit == 1 ||
+ flush_log_at_trx_commit == 3) {
if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
/* Write the log but do not flush it to disk */
@@ -1809,7 +1810,11 @@ trx_commit_complete_for_mysql(
/* Do nothing */
} else if (flush_log_at_trx_commit == 0) {
/* Do nothing */
- } else if (flush_log_at_trx_commit == 1) {
+ } else if (flush_log_at_trx_commit == 1 && trx->active_commit_ordered) {
+ /* Do nothing - we already flushed the prepare and binlog write
+ to disk, so transaction is durable (will be recovered from
+ binlog if necessary) */
+ } else if (flush_log_at_trx_commit == 1 || flush_log_at_trx_commit == 3) {
if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
/* Write the log but do not flush it to disk */
@@ -2097,7 +2102,7 @@ trx_prepare_off_kernel(
if (flush_log_at_trx_commit == 0) {
/* Do nothing */
- } else if (flush_log_at_trx_commit == 1) {
+ } else if (flush_log_at_trx_commit == 1 || flush_log_at_trx_commit == 3) {
if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) {
/* Write the log but do not flush it to disk */
diff --git a/storage/xtradb/ut/ut0dbg.c b/storage/xtradb/ut/ut0dbg.c
index 64fadd76d1c..53ed4a53044 100644
--- a/storage/xtradb/ut/ut0dbg.c
+++ b/storage/xtradb/ut/ut0dbg.c
@@ -25,7 +25,9 @@ Created 1/30/1994 Heikki Tuuri
#include "univ.i"
#include "ut0dbg.h"
-#include "ha_prototypes.h"
+#ifndef UNIV_HOTBACKUP
+# include "ha_prototypes.h"
+#endif /* !UNIV_HOTBACKUP */
#if defined(__GNUC__) && (__GNUC__ > 2)
#else
@@ -56,7 +58,7 @@ ut_dbg_assertion_failed(
ut_print_timestamp(stderr);
#ifdef UNIV_HOTBACKUP
fprintf(stderr, " InnoDB: Assertion failure in file %s line %lu\n",
- innobase_basename(file), line);
+ file, line);
#else /* UNIV_HOTBACKUP */
fprintf(stderr,
" InnoDB: Assertion failure in thread %lu"
diff --git a/storage/xtradb/ut/ut0ut.c b/storage/xtradb/ut/ut0ut.c
index 60def59193a..31c8351a518 100644
--- a/storage/xtradb/ut/ut0ut.c
+++ b/storage/xtradb/ut/ut0ut.c
@@ -245,7 +245,9 @@ ut_print_timestamp(
(int)cal_tm.wMinute,
(int)cal_tm.wSecond);
#else
+#ifdef HAVE_LOCALTIME_R
struct tm cal_tm;
+#endif
struct tm* cal_tm_ptr;
time_t tm;
@@ -288,7 +290,9 @@ ut_sprintf_timestamp(
(int)cal_tm.wMinute,
(int)cal_tm.wSecond);
#else
+#ifdef HAVE_LOCALTIME_R
struct tm cal_tm;
+#endif
struct tm* cal_tm_ptr;
time_t tm;
@@ -333,7 +337,9 @@ ut_sprintf_timestamp_without_extra_chars(
(int)cal_tm.wMinute,
(int)cal_tm.wSecond);
#else
+#ifdef HAVE_LOCALTIME_R
struct tm cal_tm;
+#endif
struct tm* cal_tm_ptr;
time_t tm;
@@ -374,7 +380,9 @@ ut_get_year_month_day(
*month = (ulint)cal_tm.wMonth;
*day = (ulint)cal_tm.wDay;
#else
+#ifdef HAVE_LOCALTIME_R
struct tm cal_tm;
+#endif
struct tm* cal_tm_ptr;
time_t tm;