summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <lars@mysql.com>2005-12-22 06:39:02 +0100
committerunknown <lars@mysql.com>2005-12-22 06:39:02 +0100
commit09346e6e2de57fadc94f70beb29eabe5186dbe62 (patch)
tree192a6c65973c50f6a436a8c6e6bb19efa2ed2419
parent65c560e9b836953bba66307268430f0faf50ca3c (diff)
downloadmariadb-git-09346e6e2de57fadc94f70beb29eabe5186dbe62.tar.gz
WL#1012: All changes as one single changeset.
This includes both code and test cases. BitKeeper/deleted/.del-ctype_ucs_binlog.result~280d136b1a0bcf17: Delete: mysql-test/r/ctype_ucs_binlog.result BitKeeper/deleted/.del-rpl_delete_all.result~7c050d592614b3f: Delete: mysql-test/r/rpl_delete_all.result BitKeeper/deleted/.del-rpl000013-slave.opt~18266ad8a2403e8d: Delete: mysql-test/t/rpl000013-slave.opt BitKeeper/deleted/.del-rpl_delete_all.test~700a1490277780e0: Delete: mysql-test/t/rpl_delete_all.test mysql-test/extra/binlog_tests/binlog.test: Import patch wl1012.patch mysql-test/extra/binlog_tests/blackhole.test: Import patch wl1012.patch mysql-test/extra/binlog_tests/ctype_cp932.test: Import patch wl1012.patch mysql-test/extra/binlog_tests/ctype_cp932_binlog.test: Import patch wl1012.patch mysql-test/extra/binlog_tests/ctype_ucs_binlog.test: Import patch wl1012.patch mysql-test/extra/binlog_tests/drop_temp_table.test: Import patch wl1012.patch mysql-test/extra/binlog_tests/insert_select-binlog.test: Import patch wl1012.patch mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_ddl.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_deadlock.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_err_ignoredtable.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_flsh_tbls.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_loaddata_m.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_log.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_max_relay_size.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_multi_query.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_reset_slave.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_stm_000001.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_stm_EE_err.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_stm_charset.test: Import patch wl1012.patch mysql-test/extra/rpl_tests/rpl_user_variables.test: Import patch wl1012.patch mysql-test/r/binlog_stm_binlog.result: Import patch wl1012.patch mysql-test/r/binlog_stm_blackhole.result: Import patch wl1012.patch mysql-test/r/binlog_stm_ctype_cp932.result: Import patch wl1012.patch mysql-test/r/binlog_stm_ctype_ucs.result: Import patch wl1012.patch mysql-test/r/binlog_stm_drop_tmp_tbl.result: Import patch wl1012.patch mysql-test/r/binlog_stm_insert_select.result: Import patch wl1012.patch mysql-test/r/binlog_stm_mix_innodb_myisam.result: Import patch wl1012.patch mysql-test/r/rpl_000012.result: Import patch wl1012.patch mysql-test/r/rpl_000015.result: Import patch wl1012.patch mysql-test/r/rpl_deadlock_innodb.result: Import patch wl1012.patch mysql-test/r/rpl_flushlog_loop.result: Import patch wl1012.patch mysql-test/r/rpl_loaddata_s.result: Import patch wl1012.patch mysql-test/r/rpl_stm_000001.result: Import patch wl1012.patch mysql-test/r/rpl_stm_EE_err.result: Import patch wl1012.patch mysql-test/r/rpl_stm_charset.result: Import patch wl1012.patch mysql-test/r/rpl_stm_ddl.result: Import patch wl1012.patch mysql-test/r/rpl_stm_err_ignoredtable.result: Import patch wl1012.patch mysql-test/r/rpl_stm_flsh_tbls.result: Import patch wl1012.patch mysql-test/r/rpl_stm_loaddata_m.result: Import patch wl1012.patch mysql-test/r/rpl_stm_log.result: Import patch wl1012.patch mysql-test/r/rpl_stm_max_relay_size.result: Import patch wl1012.patch mysql-test/r/rpl_stm_multi_query.result: Import patch wl1012.patch mysql-test/r/rpl_stm_mystery22.result: Import patch wl1012.patch mysql-test/r/rpl_stm_reset_slave.result: Import patch wl1012.patch mysql-test/r/rpl_stm_rewrt_db.result: Import patch wl1012.patch mysql-test/r/rpl_stm_sp.result: Import patch wl1012.patch mysql-test/r/rpl_stm_timezone.result: Import patch wl1012.patch mysql-test/r/rpl_stm_until.result: Import patch wl1012.patch mysql-test/r/rpl_stm_user_variables.result: Import patch wl1012.patch mysql-test/r/rpl_stm_view.result: Import patch wl1012.patch mysql-test/t/binlog_row_binlog-master.opt: Import patch wl1012.patch mysql-test/t/rpl_000012.test: Import patch wl1012.patch mysql-test/t/rpl_000015-slave.sh: Import patch wl1012.patch mysql-test/t/rpl_000015.slave-mi: Import patch wl1012.patch mysql-test/t/rpl_000015.test: Import patch wl1012.patch mysql-test/t/rpl_deadlock_innodb-slave.opt: Import patch wl1012.patch mysql-test/t/rpl_flushlog_loop-master.opt: Import patch wl1012.patch mysql-test/t/rpl_flushlog_loop-master.sh: Import patch wl1012.patch mysql-test/t/rpl_flushlog_loop-slave.opt: Import patch wl1012.patch mysql-test/t/rpl_flushlog_loop-slave.sh: Import patch wl1012.patch mysql-test/t/rpl_flushlog_loop.test: Import patch wl1012.patch mysql-test/t/rpl_loaddata_s-slave.opt: Import patch wl1012.patch mysql-test/t/rpl_loaddata_s.test: Import patch wl1012.patch mysql-test/t/rpl_stm_000001-slave.opt: Import patch wl1012.patch mysql-test/t/rpl_stm_err_ignoredtable-slave.opt: Import patch wl1012.patch mysql-test/t/rpl_stm_loaddata_m-master.opt: Import patch wl1012.patch mysql-test/t/rpl_stm_log-master.opt: Import patch wl1012.patch mysql-test/t/rpl_stm_log-slave.opt: Import patch wl1012.patch mysql-test/t/rpl_stm_mystery22.test: Import patch wl1012.patch mysql-test/t/rpl_stm_rewrt_db-slave.opt: Import patch wl1012.patch mysql-test/t/rpl_stm_rewrt_db.test: Import patch wl1012.patch mysql-test/t/rpl_stm_sp-master.opt: Import patch wl1012.patch mysql-test/t/rpl_stm_sp-slave.opt: Import patch wl1012.patch mysql-test/t/rpl_stm_sp.test: Import patch wl1012.patch mysql-test/t/rpl_stm_timezone-master.opt: Import patch wl1012.patch mysql-test/t/rpl_stm_timezone-slave.opt: Import patch wl1012.patch BUILD/SETUP.sh: Import patch wl1012.patch Makefile.am: Import patch wl1012.patch mysql-test/t/rpl_stm_timezone.test: Import patch wl1012.patch mysql-test/t/rpl_stm_until.test: Import patch wl1012.patch mysql-test/t/rpl_stm_view.test: Import patch wl1012.patch client/Makefile.am: Import patch wl1012.patch client/client_priv.h: Import patch wl1012.patch client/mysqlbinlog.cc: Import patch wl1012.patch configure.in: Import patch wl1012.patch include/Makefile.am: Import patch wl1012.patch include/base64.h: Import patch wl1012.patch include/config-win.h: Import patch wl1012.patch include/my_base.h: Import patch wl1012.patch include/my_global.h: Import patch wl1012.patch mysql-test/Makefile.am: Import patch wl1012.patch mysql-test/mysql-test-run.pl: Import patch wl1012.patch mysql-test/mysql-test-run.sh: Import patch wl1012.patch mysql-test/r/date_formats.result: Import patch wl1012.patch mysql-test/r/flush_block_commit.result: Import patch wl1012.patch mysql-test/r/innodb.result: Import patch wl1012.patch mysql-test/r/rpl000017.result: Import patch wl1012.patch mysql-test/r/rpl_change_master.result: Import patch wl1012.patch mysql-test/r/rpl_commit_after_flush.result: Import patch wl1012.patch mysql-test/r/rpl_create_database.result: Import patch wl1012.patch mysql-test/r/rpl_do_grant.result: Import patch wl1012.patch mysql-test/r/rpl_loaddata.result: Import patch wl1012.patch mysql-test/r/rpl_log_pos.result: Import patch wl1012.patch mysql-test/r/rpl_multi_delete.result: Import patch wl1012.patch mysql-test/r/rpl_multi_update.result: Import patch wl1012.patch mysql-test/r/rpl_openssl.result: Import patch wl1012.patch mysql-test/r/rpl_replicate_do.result: Import patch wl1012.patch mysql-test/r/rpl_rotate_logs.result: Import patch wl1012.patch mysql-test/r/rpl_server_id1.result: Import patch wl1012.patch mysql-test/r/rpl_server_id2.result: Import patch wl1012.patch mysql-test/r/rpl_temporary.result: Import patch wl1012.patch mysql-test/r/user_var-binlog.result: Import patch wl1012.patch mysql-test/t/create_select_tmp.test: Import patch wl1012.patch mysql-test/t/date_formats.test: Import patch wl1012.patch mysql-test/t/disabled.def: Import patch wl1012.patch mysql-test/t/innodb.test: Import patch wl1012.patch mysql-test/t/mysqlbinlog.test: Import patch wl1012.patch mysql-test/t/mysqlbinlog2.test: Import patch wl1012.patch mysql-test/t/rpl000002.test: Import patch wl1012.patch mysql-test/t/rpl000006.test: Import patch wl1012.patch mysql-test/t/rpl000013.test: Import patch wl1012.patch mysql-test/t/rpl000017.test: Import patch wl1012.patch mysql-test/t/rpl_auto_increment.test: Import patch wl1012.patch mysql-test/t/rpl_change_master.test: Import patch wl1012.patch mysql-test/t/rpl_commit_after_flush.test: Import patch wl1012.patch mysql-test/t/rpl_create_database.test: Import patch wl1012.patch mysql-test/t/rpl_do_grant.test: Import patch wl1012.patch mysql-test/t/rpl_drop.test: Import patch wl1012.patch mysql-test/t/rpl_empty_master_crash.test: Import patch wl1012.patch mysql-test/t/rpl_failed_optimize.test: Import patch wl1012.patch mysql-test/t/rpl_heap.test: Import patch wl1012.patch mysql-test/t/rpl_insert_id.test: Import patch wl1012.patch mysql-test/t/rpl_insert_ignore.test: Import patch wl1012.patch mysql-test/t/rpl_loaddata.test: Import patch wl1012.patch mysql-test/t/rpl_log_pos.test: Import patch wl1012.patch mysql-test/t/rpl_multi_delete.test: Import patch wl1012.patch mysql-test/t/rpl_multi_update.test: Import patch wl1012.patch mysql-test/t/rpl_multi_update2.test: Import patch wl1012.patch mysql-test/t/rpl_multi_update3.test: Import patch wl1012.patch mysql-test/t/rpl_openssl.test: Import patch wl1012.patch mysql-test/t/rpl_redirect.test: Import patch wl1012.patch mysql-test/t/rpl_relayrotate.test: Import patch wl1012.patch mysql-test/t/rpl_replicate_do.test: Import patch wl1012.patch mysql-test/t/rpl_rotate_logs.test: Import patch wl1012.patch mysql-test/t/rpl_server_id1.test: Import patch wl1012.patch mysql-test/t/rpl_sp_effects.test: Import patch wl1012.patch mysql-test/t/rpl_temporary.test: Import patch wl1012.patch mysql-test/t/rpl_trigger.test: Import patch wl1012.patch mysql-test/t/sp.test: Import patch wl1012.patch mysql-test/t/user_var-binlog.test: Import patch wl1012.patch mysys/Makefile.am: Import patch wl1012.patch mysys/base64.c: Import patch wl1012.patch sql/Makefile.am: Import patch wl1012.patch sql/ha_innodb.cc: Import patch wl1012.patch sql/ha_innodb.h: Import patch wl1012.patch sql/ha_partition.cc: Import patch wl1012.patch sql/handler.cc: Import patch wl1012.patch sql/handler.h: Import patch wl1012.patch sql/item_sum.cc: Import patch wl1012.patch sql/log.cc: Import patch wl1012.patch sql/log_event.cc: Import patch wl1012.patch sql/log_event.h: Import patch wl1012.patch sql/mysql_priv.h: Import patch wl1012.patch sql/mysqld.cc: Import patch wl1012.patch sql/rpl_filter.h: Import patch wl1012.patch sql/set_var.cc: Import patch wl1012.patch sql/share/errmsg.txt: Import patch wl1012.patch sql/slave.cc: Import patch wl1012.patch sql/slave.h: Import patch wl1012.patch sql/sp.cc: Import patch wl1012.patch sql/sp_head.cc: Import patch wl1012.patch sql/sql_acl.cc: Import patch wl1012.patch sql/sql_base.cc: Import patch wl1012.patch sql/sql_class.cc: Import patch wl1012.patch sql/sql_class.h: Import patch wl1012.patch sql/sql_delete.cc: Import patch wl1012.patch sql/sql_insert.cc: Import patch wl1012.patch sql/sql_lex.h: Import patch wl1012.patch sql/sql_list.h: Import patch wl1012.patch sql/sql_load.cc: Import patch wl1012.patch sql/sql_parse.cc: Import patch wl1012.patch sql/sql_plugin.cc: Import patch wl1012.patch sql/sql_rename.cc: Import patch wl1012.patch sql/sql_repl.h: Import patch wl1012.patch sql/sql_select.cc: Import patch wl1012.patch sql/sql_show.cc: Import patch wl1012.patch sql/sql_table.cc: Import patch wl1012.patch sql/sql_udf.cc: Import patch wl1012.patch sql/sql_union.cc: Import patch wl1012.patch sql/sql_update.cc: Import patch wl1012.patch sql/sql_yacc.yy: Import patch wl1012.patch sql/table.cc: Import patch wl1012.patch sql/table.h: Import patch wl1012.patch storage/innobase/include/lock0lock.h: Import patch wl1012.patch storage/innobase/include/row0mysql.h: Import patch wl1012.patch storage/innobase/include/row0vers.h: Import patch wl1012.patch storage/innobase/lock/lock0lock.c: Import patch wl1012.patch storage/innobase/row/row0mysql.c: Import patch wl1012.patch storage/innobase/row/row0sel.c: Import patch wl1012.patch storage/innobase/row/row0vers.c: Import patch wl1012.patch
-rwxr-xr-xBUILD/SETUP.sh2
-rw-r--r--ChangeLog49
-rw-r--r--Makefile.am50
-rw-r--r--client/Makefile.am7
-rw-r--r--client/client_priv.h2
-rw-r--r--client/mysqlbinlog.cc25
-rw-r--r--config/ac-macros/replication.m430
-rw-r--r--configure.in5
-rw-r--r--include/Makefile.am3
-rw-r--r--include/base64.h3
-rw-r--r--include/config-win.h12
-rw-r--r--include/my_base.h7
-rw-r--r--include/my_global.h32
-rw-r--r--include/my_vle.h42
-rw-r--r--mysql-test/Makefile.am23
-rw-r--r--mysql-test/extra/binlog_tests/binlog.test (renamed from mysql-test/t/binlog.test)11
-rw-r--r--mysql-test/extra/binlog_tests/blackhole.test (renamed from mysql-test/t/blackhole.test)0
-rw-r--r--mysql-test/extra/binlog_tests/ctype_cp932.test (renamed from mysql-test/t/ctype_cp932.test)2
-rw-r--r--mysql-test/extra/binlog_tests/ctype_cp932_binlog.test (renamed from mysql-test/t/ctype_cp932_binlog.test)3
-rw-r--r--mysql-test/extra/binlog_tests/ctype_ucs_binlog.test (renamed from mysql-test/t/ctype_ucs_binlog.test)2
-rw-r--r--mysql-test/extra/binlog_tests/drop_temp_table.test (renamed from mysql-test/t/drop_temp_table.test)0
-rw-r--r--mysql-test/extra/binlog_tests/innodb_stat.test47
-rw-r--r--mysql-test/extra/binlog_tests/insert_select-binlog.test (renamed from mysql-test/t/insert_select-binlog.test)0
-rw-r--r--mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test (renamed from mysql-test/t/mix_innodb_myisam_binlog.test)37
-rw-r--r--mysql-test/extra/rpl_tests/rpl000006.test47
-rw-r--r--mysql-test/extra/rpl_tests/rpl_auto_increment.test103
-rw-r--r--mysql-test/extra/rpl_tests/rpl_commit_after_flush.test22
-rw-r--r--mysql-test/extra/rpl_tests/rpl_ddl.test (renamed from mysql-test/t/rpl_ddl.test)48
-rw-r--r--mysql-test/extra/rpl_tests/rpl_deadlock.test (renamed from mysql-test/t/rpl_deadlock.test)21
-rw-r--r--mysql-test/extra/rpl_tests/rpl_delete_no_where.test19
-rw-r--r--mysql-test/extra/rpl_tests/rpl_err_ignoredtable.test (renamed from mysql-test/t/rpl_error_ignored_table.test)6
-rw-r--r--mysql-test/extra/rpl_tests/rpl_failed_optimize.test19
-rw-r--r--mysql-test/extra/rpl_tests/rpl_flsh_tbls.test (renamed from mysql-test/t/rpl_flush_tables.test)13
-rw-r--r--mysql-test/extra/rpl_tests/rpl_foreign_key.test32
-rw-r--r--mysql-test/extra/rpl_tests/rpl_insert_id.test78
-rw-r--r--mysql-test/extra/rpl_tests/rpl_insert_ignore.test71
-rw-r--r--mysql-test/extra/rpl_tests/rpl_loaddata.test156
-rw-r--r--mysql-test/extra/rpl_tests/rpl_loaddata_m.test (renamed from mysql-test/t/rpl_loaddata_rule_m.test)12
-rw-r--r--mysql-test/extra/rpl_tests/rpl_log.test (renamed from mysql-test/t/rpl_log.test)22
-rw-r--r--mysql-test/extra/rpl_tests/rpl_max_relay_size.test (renamed from mysql-test/t/rpl_max_relay_size.test)21
-rw-r--r--mysql-test/extra/rpl_tests/rpl_multi_query.test (renamed from mysql-test/t/rpl_multi_query.test)9
-rw-r--r--mysql-test/extra/rpl_tests/rpl_multi_update.test30
-rw-r--r--mysql-test/extra/rpl_tests/rpl_multi_update2.test62
-rw-r--r--mysql-test/extra/rpl_tests/rpl_multi_update3.test220
-rw-r--r--mysql-test/extra/rpl_tests/rpl_relayrotate.test75
-rw-r--r--mysql-test/extra/rpl_tests/rpl_reset_slave.test (renamed from mysql-test/t/rpl_reset_slave.test)16
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_001.test84
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_EE_err.test40
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_UUID.test80
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_charset.test182
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_delayed_ins.test22
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_func003.test96
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_multi_update3.test159
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_sp002.test239
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_sp003.test72
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_sp006.test90
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_sp007.test70
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_tabledefs.test129
-rw-r--r--mysql-test/extra/rpl_tests/rpl_stm_000001.test (renamed from mysql-test/t/rpl000001.test)5
-rw-r--r--mysql-test/extra/rpl_tests/rpl_stm_EE_err.test (renamed from mysql-test/t/rpl_EE_error.test)12
-rw-r--r--mysql-test/extra/rpl_tests/rpl_stm_charset.test (renamed from mysql-test/t/rpl_charset.test)9
-rw-r--r--mysql-test/extra/rpl_tests/rpl_trig004.test46
-rw-r--r--mysql-test/extra/rpl_tests/rpl_user_variables.test (renamed from mysql-test/t/rpl_user_variables.test)18
-rw-r--r--mysql-test/include/have_binlog_format_row.inc4
-rw-r--r--mysql-test/include/have_binlog_format_statement.inc4
-rw-r--r--mysql-test/include/have_row_based.inc4
-rw-r--r--mysql-test/include/not_row_based.inc4
-rw-r--r--mysql-test/include/rpl_multi_engine.inc16
-rw-r--r--mysql-test/include/rpl_row_basic.inc249
-rw-r--r--mysql-test/include/rpl_stmt_seq2.inc201
-rwxr-xr-xmysql-test/mysql-test-run.pl7
-rw-r--r--mysql-test/mysql-test-run.sh12
-rw-r--r--mysql-test/r/binlog_row_binlog.result237
-rw-r--r--mysql-test/r/binlog_row_blackhole.result146
-rw-r--r--mysql-test/r/binlog_row_ctype_cp932.result11368
-rw-r--r--mysql-test/r/binlog_row_ctype_ucs.result16
-rw-r--r--mysql-test/r/binlog_row_drop_tmp_tbl.result18
-rw-r--r--mysql-test/r/binlog_row_innodb_stat.result39
-rw-r--r--mysql-test/r/binlog_row_insert_select.result26
-rw-r--r--mysql-test/r/binlog_row_mix_innodb_myisam.result282
-rw-r--r--mysql-test/r/binlog_stm_binlog.result (renamed from mysql-test/r/binlog.result)10
-rw-r--r--mysql-test/r/binlog_stm_blackhole.result (renamed from mysql-test/r/blackhole.result)0
-rwxr-xr-xmysql-test/r/binlog_stm_ctype_cp932.result (renamed from mysql-test/r/ctype_cp932.result)8
-rw-r--r--mysql-test/r/binlog_stm_ctype_ucs.result (renamed from mysql-test/r/ctype_ucs_binlog.result)6
-rw-r--r--mysql-test/r/binlog_stm_drop_tmp_tbl.result (renamed from mysql-test/r/drop_temp_table.result)0
-rw-r--r--mysql-test/r/binlog_stm_innodb_stat.result39
-rw-r--r--mysql-test/r/binlog_stm_insert_select.result (renamed from mysql-test/r/insert_select-binlog.result)6
-rw-r--r--mysql-test/r/binlog_stm_mix_innodb_myisam.result258
-rw-r--r--mysql-test/r/ctype_cp932_binlog_row.result (renamed from mysql-test/r/ctype_cp932_binlog.result)8
-rw-r--r--mysql-test/r/ctype_cp932_binlog_stm.result17
-rw-r--r--mysql-test/r/date_formats.result3
-rw-r--r--mysql-test/r/flush_block_commit.result4
-rw-r--r--mysql-test/r/have_binlog_format_row.require2
-rw-r--r--mysql-test/r/have_binlog_format_statement.require2
-rw-r--r--mysql-test/r/have_row_based.require2
-rw-r--r--mysql-test/r/innodb.result38
-rw-r--r--mysql-test/r/innodb_concurrent.result621
-rw-r--r--mysql-test/r/mix_innodb_myisam_binlog.result258
-rw-r--r--mysql-test/r/mysqlbinlog_base64.result89
-rw-r--r--mysql-test/r/not_row_based.require2
-rw-r--r--mysql-test/r/rpl000017.result6
-rw-r--r--mysql-test/r/rpl_000012.result (renamed from mysql-test/r/rpl000012.result)29
-rw-r--r--mysql-test/r/rpl_000015.result (renamed from mysql-test/r/rpl000015.result)11
-rw-r--r--mysql-test/r/rpl_LD_INFILE.result121
-rw-r--r--mysql-test/r/rpl_bit.result138
-rw-r--r--mysql-test/r/rpl_bit_npk.result137
-rw-r--r--mysql-test/r/rpl_change_master.result4
-rw-r--r--mysql-test/r/rpl_commit_after_flush.result2
-rw-r--r--mysql-test/r/rpl_create_database.result15
-rw-r--r--mysql-test/r/rpl_deadlock_innodb.result (renamed from mysql-test/r/rpl_deadlock.result)18
-rw-r--r--mysql-test/r/rpl_delete_no_where.result15
-rw-r--r--mysql-test/r/rpl_do_grant.result52
-rw-r--r--mysql-test/r/rpl_flush_tables.result46
-rw-r--r--mysql-test/r/rpl_flushlog_loop.result (renamed from mysql-test/r/rpl_flush_log_loop.result)3
-rw-r--r--mysql-test/r/rpl_foreign_key_innodb.result42
-rw-r--r--mysql-test/r/rpl_loaddata.result8
-rw-r--r--mysql-test/r/rpl_loaddata2.result152
-rw-r--r--mysql-test/r/rpl_loaddata_s.result (renamed from mysql-test/r/rpl_loaddata_rule_s.result)6
-rw-r--r--mysql-test/r/rpl_loadfile.result234
-rw-r--r--mysql-test/r/rpl_log.result103
-rw-r--r--mysql-test/r/rpl_log_pos.result20
-rw-r--r--mysql-test/r/rpl_multi_delete.result9
-rw-r--r--mysql-test/r/rpl_multi_engine.result365
-rw-r--r--mysql-test/r/rpl_multi_update.result12
-rw-r--r--mysql-test/r/rpl_mystery22.result23
-rw-r--r--mysql-test/r/rpl_openssl.result4
-rw-r--r--mysql-test/r/rpl_replicate_do.result2
-rw-r--r--mysql-test/r/rpl_replicate_ignore_db.result23
-rw-r--r--mysql-test/r/rpl_rotate_logs.result30
-rw-r--r--mysql-test/r/rpl_row_001.result55
-rw-r--r--mysql-test/r/rpl_row_4_bytes.result27
-rw-r--r--mysql-test/r/rpl_row_EE_err.result19
-rw-r--r--mysql-test/r/rpl_row_NOW.result28
-rw-r--r--mysql-test/r/rpl_row_USER.result36
-rw-r--r--mysql-test/r/rpl_row_UUID.result38
-rw-r--r--mysql-test/r/rpl_row_basic_2myisam.result426
-rw-r--r--mysql-test/r/rpl_row_basic_3innodb.result426
-rw-r--r--mysql-test/r/rpl_row_charset.result201
-rw-r--r--mysql-test/r/rpl_row_create_table.result213
-rw-r--r--mysql-test/r/rpl_row_ddl.result1693
-rw-r--r--mysql-test/r/rpl_row_delayed_ins.result27
-rw-r--r--mysql-test/r/rpl_row_drop.result56
-rw-r--r--mysql-test/r/rpl_row_err_ignoredtable.result44
-rw-r--r--mysql-test/r/rpl_row_flsh_tbls.result32
-rw-r--r--mysql-test/r/rpl_row_func001.result30
-rw-r--r--mysql-test/r/rpl_row_func002.result25
-rw-r--r--mysql-test/r/rpl_row_func003.result29
-rw-r--r--mysql-test/r/rpl_row_inexist_tbl.result45
-rw-r--r--mysql-test/r/rpl_row_loaddata_m.result20
-rw-r--r--mysql-test/r/rpl_row_log.result105
-rw-r--r--mysql-test/r/rpl_row_max_relay_size.result (renamed from mysql-test/r/rpl_max_relay_size.result)14
-rw-r--r--mysql-test/r/rpl_row_multi_query.result37
-rw-r--r--mysql-test/r/rpl_row_multi_update3.result124
-rw-r--r--mysql-test/r/rpl_row_mystery22.result30
-rw-r--r--mysql-test/r/rpl_row_reset_slave.result32
-rw-r--r--mysql-test/r/rpl_row_rewrt_db.result (renamed from mysql-test/r/rpl_rewrite_db.result)0
-rw-r--r--mysql-test/r/rpl_row_sp000.result362
-rw-r--r--mysql-test/r/rpl_row_sp001.result85
-rw-r--r--mysql-test/r/rpl_row_sp002_innodb.result239
-rw-r--r--mysql-test/r/rpl_row_sp003.result49
-rw-r--r--mysql-test/r/rpl_row_sp005.result100
-rw-r--r--mysql-test/r/rpl_row_sp006_InnoDB.result45
-rw-r--r--mysql-test/r/rpl_row_sp007_innodb.result50
-rw-r--r--mysql-test/r/rpl_row_sp008.result45
-rw-r--r--mysql-test/r/rpl_row_sp009.result77
-rw-r--r--mysql-test/r/rpl_row_sp010.result56
-rw-r--r--mysql-test/r/rpl_row_sp011.result69
-rw-r--r--mysql-test/r/rpl_row_sp012.result58
-rw-r--r--mysql-test/r/rpl_row_stop_middle.result26
-rw-r--r--mysql-test/r/rpl_row_stop_middle_update.result16
-rw-r--r--mysql-test/r/rpl_row_tabledefs.result248
-rw-r--r--mysql-test/r/rpl_row_timezone.result121
-rw-r--r--mysql-test/r/rpl_row_trig001.result29
-rw-r--r--mysql-test/r/rpl_row_trig002.result63
-rw-r--r--mysql-test/r/rpl_row_trig003.result83
-rw-r--r--mysql-test/r/rpl_row_trig004.result29
-rw-r--r--mysql-test/r/rpl_row_until.result62
-rw-r--r--mysql-test/r/rpl_row_user_variables.result82
-rw-r--r--mysql-test/r/rpl_row_view.result44
-rw-r--r--mysql-test/r/rpl_row_view01.result100
-rw-r--r--mysql-test/r/rpl_server_id1.result2
-rw-r--r--mysql-test/r/rpl_server_id2.result2
-rw-r--r--mysql-test/r/rpl_sp004.result93
-rw-r--r--mysql-test/r/rpl_stm_000001.result (renamed from mysql-test/r/rpl000001.result)0
-rw-r--r--mysql-test/r/rpl_stm_EE_err.result (renamed from mysql-test/r/rpl_EE_error.result)0
-rw-r--r--mysql-test/r/rpl_stm_charset.result (renamed from mysql-test/r/rpl_charset.result)2
-rw-r--r--mysql-test/r/rpl_stm_ddl.result (renamed from mysql-test/r/rpl_ddl.result)38
-rw-r--r--mysql-test/r/rpl_stm_err_ignoredtable.result (renamed from mysql-test/r/rpl_error_ignored_table.result)4
-rw-r--r--mysql-test/r/rpl_stm_flsh_tbls.result32
-rw-r--r--mysql-test/r/rpl_stm_loaddata_m.result (renamed from mysql-test/r/rpl_loaddata_rule_m.result)9
-rw-r--r--mysql-test/r/rpl_stm_log.result103
-rw-r--r--mysql-test/r/rpl_stm_max_relay_size.result61
-rw-r--r--mysql-test/r/rpl_stm_multi_query.result (renamed from mysql-test/r/rpl_multi_query.result)2
-rw-r--r--mysql-test/r/rpl_stm_mystery22.result31
-rw-r--r--mysql-test/r/rpl_stm_no_op.result (renamed from mysql-test/r/rpl_delete_all.result)37
-rw-r--r--mysql-test/r/rpl_stm_reset_slave.result (renamed from mysql-test/r/rpl_reset_slave.result)8
-rw-r--r--mysql-test/r/rpl_stm_rewrt_db.result93
-rw-r--r--mysql-test/r/rpl_stm_sp.result (renamed from mysql-test/r/rpl_sp.result)2
-rw-r--r--mysql-test/r/rpl_stm_timezone.result (renamed from mysql-test/r/rpl_timezone.result)0
-rw-r--r--mysql-test/r/rpl_stm_until.result (renamed from mysql-test/r/rpl_until.result)20
-rw-r--r--mysql-test/r/rpl_stm_user_variables.result82
-rw-r--r--mysql-test/r/rpl_stm_view.result (renamed from mysql-test/r/rpl_view.result)0
-rw-r--r--mysql-test/r/rpl_temporary.result15
-rw-r--r--mysql-test/r/rpl_user_variables.result110
-rw-r--r--mysql-test/r/user_var-binlog.result12
-rw-r--r--mysql-test/std_data/rpl_timezone2.dat2
-rw-r--r--mysql-test/std_data/words2.dat50
-rw-r--r--mysql-test/t/binlog_row_binlog-master.opt (renamed from mysql-test/t/binlog-master.opt)0
-rw-r--r--mysql-test/t/binlog_row_binlog.test5
-rw-r--r--mysql-test/t/binlog_row_blackhole.test5
-rw-r--r--mysql-test/t/binlog_row_ctype_cp932.test5
-rw-r--r--mysql-test/t/binlog_row_ctype_ucs.test6
-rw-r--r--mysql-test/t/binlog_row_drop_tmp_tbl.test5
-rw-r--r--mysql-test/t/binlog_row_innodb_stat.test5
-rw-r--r--mysql-test/t/binlog_row_insert_select.test5
-rw-r--r--mysql-test/t/binlog_row_mix_innodb_myisam.test5
-rw-r--r--mysql-test/t/binlog_stm_binlog-master.opt1
-rw-r--r--mysql-test/t/binlog_stm_binlog.test5
-rw-r--r--mysql-test/t/binlog_stm_blackhole.test5
-rw-r--r--mysql-test/t/binlog_stm_ctype_cp932.test5
-rw-r--r--mysql-test/t/binlog_stm_ctype_ucs.test6
-rw-r--r--mysql-test/t/binlog_stm_drop_tmp_tbl.test5
-rw-r--r--mysql-test/t/binlog_stm_innodb_stat-master.opt1
-rw-r--r--mysql-test/t/binlog_stm_innodb_stat.test5
-rw-r--r--mysql-test/t/binlog_stm_insert_select.test5
-rw-r--r--mysql-test/t/binlog_stm_mix_innodb_myisam.test5
-rw-r--r--mysql-test/t/create_select_tmp.test3
-rw-r--r--mysql-test/t/ctype_cp932_binlog_row.test5
-rw-r--r--mysql-test/t/ctype_cp932_binlog_stm.test5
-rw-r--r--mysql-test/t/date_formats.test3
-rw-r--r--mysql-test/t/disabled.def18
-rw-r--r--mysql-test/t/innodb.test43
-rw-r--r--mysql-test/t/innodb_concurrent-master.opt1
-rw-r--r--mysql-test/t/innodb_concurrent.test346
-rw-r--r--mysql-test/t/mysqlbinlog.test6
-rw-r--r--mysql-test/t/mysqlbinlog2.test19
-rw-r--r--mysql-test/t/mysqlbinlog_base64.test38
-rw-r--r--mysql-test/t/rpl000002.test5
-rw-r--r--mysql-test/t/rpl000006.test49
-rw-r--r--mysql-test/t/rpl000013-slave.opt1
-rw-r--r--mysql-test/t/rpl000013.test10
-rw-r--r--mysql-test/t/rpl000017.test6
-rw-r--r--mysql-test/t/rpl_000012.test (renamed from mysql-test/t/rpl000012.test)36
-rwxr-xr-xmysql-test/t/rpl_000015-slave.sh (renamed from mysql-test/t/rpl000015-slave.sh)0
-rw-r--r--mysql-test/t/rpl_000015.slave-mi (renamed from mysql-test/t/rpl000015.slave-mi)0
-rw-r--r--mysql-test/t/rpl_000015.test (renamed from mysql-test/t/rpl000015.test)6
-rw-r--r--mysql-test/t/rpl_LD_INFILE.test41
-rw-r--r--mysql-test/t/rpl_auto_increment.test111
-rw-r--r--mysql-test/t/rpl_bit.test90
-rw-r--r--mysql-test/t/rpl_bit_npk.test112
-rw-r--r--mysql-test/t/rpl_change_master.test4
-rw-r--r--mysql-test/t/rpl_commit_after_flush.test25
-rw-r--r--mysql-test/t/rpl_create_database.test3
-rw-r--r--mysql-test/t/rpl_deadlock_innodb-slave.opt (renamed from mysql-test/t/rpl_deadlock-slave.opt)0
-rw-r--r--mysql-test/t/rpl_deadlock_innodb.test6
-rw-r--r--mysql-test/t/rpl_delete_all.test43
-rw-r--r--mysql-test/t/rpl_delete_no_where.test2
-rw-r--r--mysql-test/t/rpl_do_grant.test54
-rw-r--r--mysql-test/t/rpl_drop.test2
-rw-r--r--mysql-test/t/rpl_empty_master_crash.test2
-rw-r--r--mysql-test/t/rpl_failed_optimize.test26
-rw-r--r--mysql-test/t/rpl_flushlog_loop-master.opt (renamed from mysql-test/t/rpl_flush_log_loop-master.opt)0
-rwxr-xr-xmysql-test/t/rpl_flushlog_loop-master.sh (renamed from mysql-test/t/rpl_flush_log_loop-master.sh)0
-rw-r--r--mysql-test/t/rpl_flushlog_loop-slave.opt (renamed from mysql-test/t/rpl_flush_log_loop-slave.opt)0
-rwxr-xr-xmysql-test/t/rpl_flushlog_loop-slave.sh (renamed from mysql-test/t/rpl_flush_log_loop-slave.sh)0
-rw-r--r--mysql-test/t/rpl_flushlog_loop.test (renamed from mysql-test/t/rpl_flush_log_loop.test)14
-rw-r--r--mysql-test/t/rpl_foreign_key_innodb.test6
-rw-r--r--mysql-test/t/rpl_heap.test5
-rw-r--r--mysql-test/t/rpl_insert_id.test83
-rw-r--r--mysql-test/t/rpl_insert_ignore.test78
-rw-r--r--mysql-test/t/rpl_loaddata.test155
-rw-r--r--mysql-test/t/rpl_loaddata2.test8
-rw-r--r--mysql-test/t/rpl_loaddata_s-slave.opt (renamed from mysql-test/t/rpl_loaddata_rule_m-master.opt)0
-rw-r--r--mysql-test/t/rpl_loaddata_s.test (renamed from mysql-test/t/rpl_loaddata_rule_s.test)14
-rw-r--r--mysql-test/t/rpl_loadfile.test47
-rw-r--r--mysql-test/t/rpl_log_pos.test13
-rw-r--r--mysql-test/t/rpl_multi_delete.test26
-rw-r--r--mysql-test/t/rpl_multi_engine-slave.opt (renamed from mysql-test/t/rpl000001-slave.opt)0
-rw-r--r--mysql-test/t/rpl_multi_engine.test99
-rw-r--r--mysql-test/t/rpl_multi_update.test51
-rw-r--r--mysql-test/t/rpl_multi_update2.test64
-rw-r--r--mysql-test/t/rpl_multi_update3.test222
-rw-r--r--mysql-test/t/rpl_openssl.test4
-rw-r--r--mysql-test/t/rpl_redirect.test2
-rw-r--r--mysql-test/t/rpl_relayrotate.test78
-rw-r--r--mysql-test/t/rpl_replicate_do.test3
-rw-r--r--mysql-test/t/rpl_replicate_ignore_db-slave.opt1
-rw-r--r--mysql-test/t/rpl_replicate_ignore_db.test30
-rw-r--r--mysql-test/t/rpl_rotate_logs.test9
-rw-r--r--mysql-test/t/rpl_row_001.test2
-rw-r--r--mysql-test/t/rpl_row_4_bytes-master.opt1
-rw-r--r--mysql-test/t/rpl_row_4_bytes.test33
-rw-r--r--mysql-test/t/rpl_row_EE_err.test2
-rw-r--r--mysql-test/t/rpl_row_NOW.test73
-rw-r--r--mysql-test/t/rpl_row_USER.test54
-rw-r--r--mysql-test/t/rpl_row_UUID.test2
-rw-r--r--mysql-test/t/rpl_row_basic_2myisam.test3
-rw-r--r--mysql-test/t/rpl_row_basic_3innodb-slave.opt1
-rw-r--r--mysql-test/t/rpl_row_basic_3innodb.test6
-rw-r--r--mysql-test/t/rpl_row_charset.test2
-rw-r--r--mysql-test/t/rpl_row_create_table.test108
-rw-r--r--mysql-test/t/rpl_row_ddl.test35
-rw-r--r--mysql-test/t/rpl_row_delayed_ins.test2
-rw-r--r--mysql-test/t/rpl_row_drop.test47
-rw-r--r--mysql-test/t/rpl_row_err_daisychain-master.opt1
-rw-r--r--mysql-test/t/rpl_row_err_daisychain-slave.opt1
-rw-r--r--mysql-test/t/rpl_row_flsh_tbls.test6
-rw-r--r--mysql-test/t/rpl_row_func001.test56
-rw-r--r--mysql-test/t/rpl_row_func002.test104
-rw-r--r--mysql-test/t/rpl_row_func003.test6
-rw-r--r--mysql-test/t/rpl_row_inexist_tbl.test27
-rw-r--r--mysql-test/t/rpl_row_log-master.opt (renamed from mysql-test/t/rpl_log-master.opt)0
-rw-r--r--mysql-test/t/rpl_row_log-slave.opt (renamed from mysql-test/t/rpl_log-slave.opt)0
-rw-r--r--mysql-test/t/rpl_row_log.test4
-rw-r--r--mysql-test/t/rpl_row_max_relay_size.test9
-rw-r--r--mysql-test/t/rpl_row_multi_update3.test2
-rw-r--r--mysql-test/t/rpl_row_mystery22.test45
-rw-r--r--mysql-test/t/rpl_row_reset_slave.test5
-rw-r--r--mysql-test/t/rpl_row_rewrt_db-slave.opt (renamed from mysql-test/t/rpl_rewrite_db-slave.opt)0
-rw-r--r--mysql-test/t/rpl_row_rewrt_db.test (renamed from mysql-test/t/rpl_rewrite_db.test)6
-rw-r--r--mysql-test/t/rpl_row_sp000-master.opt (renamed from mysql-test/t/rpl_sp-master.opt)0
-rw-r--r--mysql-test/t/rpl_row_sp000-slave.opt1
-rw-r--r--mysql-test/t/rpl_row_sp000.test323
-rw-r--r--mysql-test/t/rpl_row_sp001.test144
-rw-r--r--mysql-test/t/rpl_row_sp002_innodb-master.opt1
-rw-r--r--mysql-test/t/rpl_row_sp002_innodb-slave.opt1
-rw-r--r--mysql-test/t/rpl_row_sp002_innodb.test6
-rw-r--r--mysql-test/t/rpl_row_sp003-master.opt1
-rw-r--r--mysql-test/t/rpl_row_sp003-slave.opt1
-rw-r--r--mysql-test/t/rpl_row_sp003.test6
-rw-r--r--mysql-test/t/rpl_row_sp005.test105
-rw-r--r--mysql-test/t/rpl_row_sp006_InnoDB-slave.opt1
-rw-r--r--mysql-test/t/rpl_row_sp006_InnoDB.test6
-rw-r--r--mysql-test/t/rpl_row_sp007_innodb.test6
-rw-r--r--mysql-test/t/rpl_row_sp008.test58
-rw-r--r--mysql-test/t/rpl_row_sp009.test105
-rw-r--r--mysql-test/t/rpl_row_sp010.test81
-rw-r--r--mysql-test/t/rpl_row_sp011.test115
-rw-r--r--mysql-test/t/rpl_row_sp012.test74
-rw-r--r--mysql-test/t/rpl_row_stop_middle.test44
-rw-r--r--mysql-test/t/rpl_row_stop_middle_update-master.opt1
-rw-r--r--mysql-test/t/rpl_row_stop_middle_update-slave.opt1
-rw-r--r--mysql-test/t/rpl_row_stop_middle_update.test31
-rw-r--r--mysql-test/t/rpl_row_timezone-master.opt (renamed from mysql-test/t/rpl_timezone-master.opt)0
-rw-r--r--mysql-test/t/rpl_row_timezone-slave.opt2
-rw-r--r--mysql-test/t/rpl_row_timezone.test129
-rw-r--r--mysql-test/t/rpl_row_trig001.test98
-rw-r--r--mysql-test/t/rpl_row_trig002.test79
-rw-r--r--mysql-test/t/rpl_row_trig003.test152
-rw-r--r--mysql-test/t/rpl_row_trig004.test14
-rw-r--r--mysql-test/t/rpl_row_until.test86
-rw-r--r--mysql-test/t/rpl_row_user_variables.test4
-rw-r--r--mysql-test/t/rpl_row_view.test (renamed from mysql-test/t/rpl_view.test)6
-rw-r--r--mysql-test/t/rpl_row_view01.test82
-rw-r--r--mysql-test/t/rpl_server_id1.test2
-rw-r--r--mysql-test/t/rpl_sp004.test97
-rw-r--r--mysql-test/t/rpl_sp_effects.test7
-rw-r--r--mysql-test/t/rpl_stm_000001-slave.opt1
-rw-r--r--mysql-test/t/rpl_stm_000001.test2
-rw-r--r--mysql-test/t/rpl_stm_EE_err.test2
-rw-r--r--mysql-test/t/rpl_stm_charset.test2
-rw-r--r--mysql-test/t/rpl_stm_ddl.test35
-rw-r--r--mysql-test/t/rpl_stm_err_ignoredtable-slave.opt (renamed from mysql-test/t/rpl_error_ignored_table-slave.opt)0
-rw-r--r--mysql-test/t/rpl_stm_err_ignoredtable.test8
-rw-r--r--mysql-test/t/rpl_stm_flsh_tbls.test8
-rw-r--r--mysql-test/t/rpl_stm_loaddata_m-master.opt (renamed from mysql-test/t/rpl_loaddata_rule_s-slave.opt)0
-rw-r--r--mysql-test/t/rpl_stm_loaddata_m.test10
-rw-r--r--mysql-test/t/rpl_stm_log-master.opt1
-rw-r--r--mysql-test/t/rpl_stm_log-slave.opt1
-rw-r--r--mysql-test/t/rpl_stm_log.test7
-rw-r--r--mysql-test/t/rpl_stm_max_relay_size.test11
-rw-r--r--mysql-test/t/rpl_stm_multi_query.test12
-rw-r--r--mysql-test/t/rpl_stm_mystery22.test (renamed from mysql-test/t/rpl_mystery22.test)30
-rw-r--r--mysql-test/t/rpl_stm_no_op.test93
-rw-r--r--mysql-test/t/rpl_stm_reset_slave.test6
-rw-r--r--mysql-test/t/rpl_stm_rewrt_db-slave.opt1
-rw-r--r--mysql-test/t/rpl_stm_rewrt_db.test84
-rw-r--r--mysql-test/t/rpl_stm_sp-master.opt1
-rw-r--r--mysql-test/t/rpl_stm_sp-slave.opt (renamed from mysql-test/t/rpl_sp-slave.opt)0
-rw-r--r--mysql-test/t/rpl_stm_sp.test (renamed from mysql-test/t/rpl_sp.test)5
-rw-r--r--mysql-test/t/rpl_stm_timezone-master.opt1
-rw-r--r--mysql-test/t/rpl_stm_timezone-slave.opt (renamed from mysql-test/t/rpl_timezone-slave.opt)0
-rw-r--r--mysql-test/t/rpl_stm_timezone.test (renamed from mysql-test/t/rpl_timezone.test)3
-rw-r--r--mysql-test/t/rpl_stm_until.test (renamed from mysql-test/t/rpl_until.test)11
-rw-r--r--mysql-test/t/rpl_stm_user_variables.test5
-rw-r--r--mysql-test/t/rpl_stm_view.test50
-rw-r--r--mysql-test/t/rpl_temporary.test11
-rw-r--r--mysql-test/t/rpl_trigger.test5
-rw-r--r--mysql-test/t/sp.test4
-rw-r--r--mysql-test/t/user_var-binlog.test6
-rw-r--r--mysys/Makefile.am1
-rw-r--r--mysys/base64.c2
-rw-r--r--mysys/my_vle.c113
-rw-r--r--sql/Makefile.am6
-rw-r--r--sql/ha_innodb.cc65
-rw-r--r--sql/ha_innodb.h2
-rw-r--r--sql/ha_partition.cc4
-rw-r--r--sql/handler.cc110
-rw-r--r--sql/handler.h60
-rw-r--r--sql/item_sum.cc2
-rw-r--r--sql/log.cc427
-rw-r--r--sql/log.h332
-rw-r--r--sql/log_event.cc1914
-rw-r--r--sql/log_event.h596
-rw-r--r--sql/mysql_priv.h73
-rw-r--r--sql/mysqld.cc147
-rw-r--r--sql/rpl_filter.h1
-rw-r--r--sql/rpl_rli.h312
-rw-r--r--sql/rpl_tblmap.cc151
-rw-r--r--sql/rpl_tblmap.h109
-rw-r--r--sql/set_var.cc3
-rw-r--r--sql/share/errmsg.txt6
-rw-r--r--sql/slave.cc274
-rw-r--r--sql/slave.h291
-rw-r--r--sql/sp.cc12
-rw-r--r--sql/sp_head.cc89
-rw-r--r--sql/sql_acl.cc56
-rw-r--r--sql/sql_base.cc81
-rw-r--r--sql/sql_binlog.cc135
-rw-r--r--sql/sql_class.cc451
-rw-r--r--sql/sql_class.h414
-rw-r--r--sql/sql_delete.cc50
-rw-r--r--sql/sql_insert.cc228
-rw-r--r--sql/sql_lex.h3
-rw-r--r--sql/sql_list.h22
-rw-r--r--sql/sql_load.cc109
-rw-r--r--sql/sql_parse.cc54
-rw-r--r--sql/sql_plugin.cc4
-rw-r--r--sql/sql_rename.cc4
-rw-r--r--sql/sql_repl.h2
-rw-r--r--sql/sql_select.cc30
-rw-r--r--sql/sql_show.cc77
-rw-r--r--sql/sql_show.h17
-rw-r--r--sql/sql_table.cc180
-rw-r--r--sql/sql_udf.cc4
-rw-r--r--sql/sql_union.cc2
-rw-r--r--sql/sql_update.cc45
-rw-r--r--sql/sql_yacc.yy8
-rw-r--r--sql/table.cc20
-rw-r--r--sql/table.h5
-rw-r--r--storage/innobase/include/lock0lock.h20
-rw-r--r--storage/innobase/include/row0mysql.h30
-rw-r--r--storage/innobase/include/row0vers.h26
-rw-r--r--storage/innobase/lock/lock0lock.c68
-rw-r--r--storage/innobase/row/row0mysql.c14
-rw-r--r--storage/innobase/row/row0sel.c172
-rw-r--r--storage/innobase/row/row0vers.c138
447 files changed, 34744 insertions, 3218 deletions
diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index eece41d72e6..ae5c8332bcd 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -55,7 +55,7 @@ SSL_LIBRARY=--with-openssl
global_warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wchar-subscripts -Wformat -Wparentheses -Wsign-compare -Wwrite-strings"
#debug_extra_warnings="-Wuninitialized"
c_warnings="$global_warnings -Wunused"
-cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor"
+cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder"
base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine --with-partition $SSL_LIBRARY"
base_max_no_ndb_configs="--with-innodb --with-berkeley-db --without-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine --with-partition $SSL_LIBRARY"
max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-csv-storage-engine --with-embedded-server --with-big-tables --with-partition $SSL_LIBRARY"
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 00000000000..7ca0b28a723
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,49 @@
+2005-09-25 Mats Kindahl <mats@mysql.com>
+
+ * sql/log_event.cc (find_and_fetch_row): Added the optimization
+ that if a record is found using a key with HA_NOSAME flag set, we
+ do not need to compare records to see if it is the correct one.
+
+2005-09-23 Mats Kindahl <mats@mysql.com>
+
+ * sql/log_event.cc (replace_record): Added function to overwrite
+ existing row if there were a duplicate key.
+
+2005-09-17 Mats Kindahl <mats@mysql.com>
+
+ * mysql-test/t/rpl_row_multi_query.test: This test is explicitly
+ for testing that multi-queries are logged as one Query_log_event
+ per sub-query instead of one Query_log_event for the entire
+ multi-query.
+
+ The test was removed
+
+ * mysql-test/t/rpl_stm_flsh_tbls.test: Added rename_event_pos
+ parameter.
+
+ * mysql-test/t/rpl_row_flsh_tbls.test: Added rename_event_pos
+ parameter.
+
+ * mysql-test/extra/rpl_tests/rpl_flsh_tbls.test: Takes one
+ additional parameter with the position of the RENAME TABLE
+ event. The SHOW BINLOG EVENTS is only used to check the presence
+ of the RENAME TABLE event and the FLUSH TABLES event.
+
+2005-09-16 Mats Kindahl <mats@mysql.com>
+
+ * mysql-test/t/rpl_row_err_ignoredtable.test: This test is
+ statement-oriented since it tests that errorneous statements are
+ sent through the binlog. This does not happen with RBR, since
+ statements are not replicated through the binlog.
+
+ Test was removed.
+
+ * mysql-test/t/rpl_row_loaddata_m.test: This test is purely
+ statement-based, so it was removed as a test for row-based
+ logging. The LOAD DATA is not replicated as two statements, but
+ is rather replicated using row-based events, and this is a test
+ that the correct events are put into the binary log on execution
+ of LOAD DATA INFILE.
+
+ Test was removed.
+
diff --git a/Makefile.am b/Makefile.am
index 5d7de33cc42..68183a6b246 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -110,24 +110,52 @@ tags:
test:
cd mysql-test ; \
- ./mysql-test-run && \
- ./mysql-test-run --ps-protocol
+ ./mysql-test-run --mysqld=--binlog-format=statement && \
+ ./mysql-test-run --ps-protocol --mysqld=--binlog-format=row
+
+test-full:
+ cd mysql-test ; \
+ ./mysql-test-run --mysqld=--binlog-format=statement && \
+ ./mysql-test-run --ps-protocol --mysqld=--binlog-format=statement && \
+ ./mysql-test-run --mysqld=--binlog-format=row && \
+ ./mysql-test-run --ps-protocol --mysqld=--binlog-format=row
test-force:
- cd mysql-test; \
- ./mysql-test-run --force && \
- ./mysql-test-run --ps-protocol --force
+ cd mysql-test ; \
+ ./mysql-test-run --force --mysqld=--binlog-format=statement && \
+ ./mysql-test-run --ps-protocol --force --mysqld=--binlog-format=row
+
+test-force-full:
+ cd mysql-test ; \
+ ./mysql-test-run --force --mysqld=--binlog-format=statement && \
+ ./mysql-test-run --force --ps-protocol --mysqld=--binlog-format=statement && \
+ ./mysql-test-run --force --mysqld=--binlog-format=row && \
+ ./mysql-test-run --force --ps-protocol --mysqld=--binlog-format=row
# We are testing a new Perl version of the test script
test-pl:
- cd mysql-test; \
- ./mysql-test-run.pl && \
- ./mysql-test-run.pl --ps-protocol
+ cd mysql-test ; \
+ ./mysql-test-run.pl --mysqld=--binlog-format=statement && \
+ ./mysql-test-run.pl --ps-protocol --mysqld=--binlog-format=row
+
+test-full-pl:
+ cd mysql-test ; \
+ ./mysql-test-run.pl --mysqld=--binlog-format=statement && \
+ ./mysql-test-run.pl --ps-protocol --mysqld=--binlog-format=statement && \
+ ./mysql-test-run.pl --mysqld=--binlog-format=row && \
+ ./mysql-test-run.pl --ps-protocol --mysqld=--binlog-format=row
test-force-pl:
- cd mysql-test; \
- ./mysql-test-run.pl --force && \
- ./mysql-test-run.pl --ps-protocol --force
+ cd mysql-test ; \
+ ./mysql-test-run.pl --force --mysqld=--binlog-format=statement && \
+ ./mysql-test-run.pl --ps-protocol --force --mysqld=--binlog-format=row
+
+test-force-full-pl:
+ cd mysql-test ; \
+ ./mysql-test-run.pl --force --mysqld=--binlog-format=statement && \
+ ./mysql-test-run.pl --force --ps-protocol --mysqld=--binlog-format=statement && \
+ ./mysql-test-run.pl --force --mysqld=--binlog-format=row && \
+ ./mysql-test-run.pl --force --ps-protocol --mysqld=--binlog-format=row
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/client/Makefile.am b/client/Makefile.am
index 4d4bb55cc17..fe3620bbad7 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -41,7 +41,12 @@ mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS)
mysqltest_SOURCES= mysqltest.c $(top_srcdir)/mysys/my_getsystime.c \
$(yassl_dummy_link_fix)
mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD)
-mysqlbinlog_SOURCES = mysqlbinlog.cc $(top_srcdir)/mysys/mf_tempdir.c $(top_srcdir)/mysys/my_new.cc
+mysqlbinlog_SOURCES = mysqlbinlog.cc $(top_srcdir)/mysys/mf_tempdir.c \
+ $(top_srcdir)/mysys/my_new.cc \
+ $(top_srcdir)/mysys/my_bit.c \
+ $(top_srcdir)/mysys/my_bitmap.c \
+ $(top_srcdir)/mysys/my_vle.c \
+ $(top_srcdir)/mysys/base64.c
mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS)
mysqltestmanager_pwgen_SOURCES = mysqlmanager-pwgen.c
mysqltestmanagerc_SOURCES= mysqlmanagerc.c $(yassl_dummy_link_fix)
diff --git a/client/client_priv.h b/client/client_priv.h
index a9c5f517d19..024a92daf7b 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -52,5 +52,5 @@ enum options_client
OPT_TRIGGERS,
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_CREATE_SLAP_SCHEMA,
- OPT_MYSQL_REPLACE_INTO, OPT_SERVER_ID
+ OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT, OPT_SERVER_ID
};
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index da8a23f8447..6ecbb6802c7 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -63,6 +63,7 @@ void sql_print_error(const char *format, ...);
static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0;
static bool opt_hexdump= 0;
+static bool opt_base64_output= 0;
static const char* database= 0;
static my_bool force_opt= 0, short_form= 0, remote_opt= 0;
static ulonglong offset = 0;
@@ -533,11 +534,19 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
else
print_event_info->hexdump_from= pos;
+ print_event_info->base64_output= opt_base64_output;
+
switch (ev_type) {
case QUERY_EVENT:
if (check_database(((Query_log_event*)ev)->db))
goto end;
- ev->print(result_file, print_event_info);
+ if (opt_base64_output)
+ {
+ ev->print_header(result_file, print_event_info);
+ ev->print_base64(result_file, print_event_info);
+ }
+ else
+ ev->print(result_file, print_event_info);
break;
case CREATE_FILE_EVENT:
{
@@ -557,7 +566,13 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
filename and use LOCAL), prepared in the 'case EXEC_LOAD_EVENT'
below.
*/
- ce->print(result_file, print_event_info, TRUE);
+ if (opt_base64_output)
+ {
+ ce->print_header(result_file, print_event_info);
+ ce->print_base64(result_file, print_event_info);
+ }
+ else
+ ce->print(result_file, print_event_info, TRUE);
// If this binlog is not 3.23 ; why this test??
if (description_event->binlog_version >= 3)
@@ -653,6 +668,12 @@ static struct my_option my_long_options[] =
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
+ {"base64-output", OPT_BASE64_OUTPUT,
+ "Print all binlog entries using base64 encoding. "
+ "This is for debugging only. Logs produced using this option "
+ "should not be applied on production systems.",
+ (gptr*) &opt_base64_output, (gptr*) &opt_base64_output, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
/*
mysqlbinlog needs charsets knowledge, to be able to convert a charset
number found in binlog to a charset name (to be able to print things
diff --git a/config/ac-macros/replication.m4 b/config/ac-macros/replication.m4
new file mode 100644
index 00000000000..f73b9319b86
--- /dev/null
+++ b/config/ac-macros/replication.m4
@@ -0,0 +1,30 @@
+dnl This file contains configuration parameters for replication.
+
+dnl ---------------------------------------------------------------------------
+dnl Macro: MYSQL_CHECK_REPLICATION
+dnl Sets HAVE_ROW_BASED_REPLICATION if --with-row-based-replication is used
+dnl ---------------------------------------------------------------------------
+
+AC_DEFUN([MYSQL_CHECK_REPLICATION], [
+ AC_ARG_WITH([row-based-replication],
+ AC_HELP_STRING([--with-row-based-replication],
+ [Include row-based replication]),
+ [row_based="$withval"],
+ [row_based=yes])
+ AC_MSG_CHECKING([for row-based replication])
+
+ case "$row_based" in
+ yes )
+ AC_DEFINE([HAVE_ROW_BASED_REPLICATION], [1], [Define to have row-based replication])
+ AC_MSG_RESULT([-- including row-based replication])
+ [have_row_based=yes]
+ ;;
+ * )
+ AC_MSG_RESULT([-- not including row-based replication])
+ [have_row_based=no]
+ ;;
+ esac
+])
+dnl ---------------------------------------------------------------------------
+dnl END OF MYSQL_CHECK_REPLICATION
+dnl ---------------------------------------------------------------------------
diff --git a/configure.in b/configure.in
index 848b41269ea..3b619e108ac 100644
--- a/configure.in
+++ b/configure.in
@@ -42,6 +42,7 @@ sinclude(config/ac-macros/large_file.m4)
sinclude(config/ac-macros/misc.m4)
sinclude(config/ac-macros/openssl.m4)
sinclude(config/ac-macros/readline.m4)
+sinclude(config/ac-macros/replication.m4)
sinclude(config/ac-macros/yassl.m4)
sinclude(config/ac-macros/zlib.m4)
@@ -1834,7 +1835,8 @@ MYSQL_TYPE_QSORT
AC_FUNC_UTIME_NULL
AC_FUNC_VPRINTF
-AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \
+AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \
+ chsize cuserid fchmod fcntl \
fconvert fdatasync finite fpresetsticky fpsetmask fsync ftruncate \
getcwd gethostbyaddr_r gethostbyname_r getpass getpassphrase getpwnam \
getpwuid getrlimit getrusage getwd gmtime_r index initgroups isnan \
@@ -2386,6 +2388,7 @@ AC_SUBST(readline_h_ln_cmd)
MYSQL_CHECK_BIG_TABLES
MYSQL_CHECK_MAX_INDEXES
+MYSQL_CHECK_REPLICATION
MYSQL_STORAGE_ENGINE(innobase,,innodb,,,,storage/innobase,ha_innodb.o,[ dnl
\$(top_builddir)/storage/innobase/usr/libusr.a dnl
diff --git a/include/Makefile.am b/include/Makefile.am
index d2605628a7d..44efe0b7211 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -30,7 +30,8 @@ noinst_HEADERS = config-win.h config-os2.h config-netware.h \
my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \
my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \
thr_lock.h t_ctype.h violite.h md5.h base64.h \
- mysql_version.h.in my_handler.h my_time.h decimal.h
+ mysql_version.h.in my_handler.h my_time.h decimal.h \
+ my_vle.h
# mysql_version.h are generated
CLEANFILES = mysql_version.h my_config.h readline
diff --git a/include/base64.h b/include/base64.h
index fcc2f8b40dc..a2b0fc0352b 100644
--- a/include/base64.h
+++ b/include/base64.h
@@ -21,8 +21,7 @@
extern "C" {
#endif
-
-#include <mysys_priv.h>
+#include <my_global.h>
/*
Calculate how much memory needed for dst of base64_encode()
diff --git a/include/config-win.h b/include/config-win.h
index b825d34f1ee..6c0937391fb 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -269,6 +269,12 @@ inline double ulonglong2double(ulonglong value)
(((uint32) ((uchar) (A)[2])) << 16) +\
(((uint32) ((uchar) (A)[3])) << 24)) +\
(((ulonglong) ((uchar) (A)[4])) << 32))
+#define uint6korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) + \
+ (((uint32) ((uchar) (A)[1])) << 8) + \
+ (((uint32) ((uchar) (A)[2])) << 16) + \
+ (((uint32) ((uchar) (A)[3])) << 24)) + \
+ (((ulonglong) ((uchar) (A)[4])) << 32) + \
+ (((ulonglong) ((uchar) (A)[5])) << 40))
#define uint8korr(A) (*((ulonglong *) (A)))
#define sint8korr(A) (*((longlong *) (A)))
#define int2store(T,A) *((uint16*) (T))= (uint16) (A)
@@ -281,6 +287,12 @@ inline double ulonglong2double(ulonglong value)
*((T)+2)=(uchar) (((A) >> 16));\
*((T)+3)=(uchar) (((A) >> 24)); \
*((T)+4)=(uchar) (((A) >> 32)); }
+#define int6store(T,A) { *(T) =(uchar)((A)); \
+ *((T)+1)=(uchar) (((A) >> 8)); \
+ *((T)+2)=(uchar) (((A) >> 16)); \
+ *((T)+3)=(uchar) (((A) >> 24)); \
+ *((T)+4)=(uchar) (((A) >> 32)); \
+ *((T)+5)=(uchar) (((A) >> 40)); }
#define int8store(T,A) *((ulonglong *) (T))= (ulonglong) (A)
#define doubleget(V,M) do { *((long *) &V) = *((long*) M); \
diff --git a/include/my_base.h b/include/my_base.h
index 5ea3795f715..4e1a573217b 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -343,9 +343,12 @@ enum ha_base_keytype {
#define HA_ERR_NO_CONNECTION 157 /* Could not connect to storage engine */
#define HA_ERR_NULL_IN_SPATIAL 158 /* NULLs are not supported in spatial index */
#define HA_ERR_TABLE_DEF_CHANGED 159 /* The table changed in storage engine */
-#define HA_ERR_NO_PARTITION_FOUND 160 /* There's no partition in table for given value */
+#define HA_ERR_NO_PARTITION_FOUND 160 /* There's no partition in table for
+ given value */
+#define HA_ERR_RBR_LOGGING_FAILED 161 /* Row-based binlogging of row failed */
+
+#define HA_ERR_LAST 161 /* Copy last error no */
-#define HA_ERR_LAST 160 /*Copy last error nr.*/
/* Add error numbers before HA_ERR_LAST and change it accordingly. */
#define HA_ERR_ERRORS (HA_ERR_LAST - HA_ERR_FIRST + 1)
diff --git a/include/my_global.h b/include/my_global.h
index 6be59e41512..8d7ad9e0ad5 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -844,6 +844,14 @@ typedef long my_ptrdiff_t;
typedef long long my_ptrdiff_t;
#endif
+#if HAVE_SIZE_T
+typedef size_t my_size_t;
+#elif SIZEOF_CHARP <= SIZEOF_LONG
+typedef unsigned long my_size_t;
+#else
+typedef unsigned long long my_size_t;
+#endif
+
#define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1))
#define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double))
/* Size to make adressable obj. */
@@ -1122,6 +1130,12 @@ typedef char bool; /* Ordinary boolean values 0 1 */
(((uint32) ((uchar) (A)[2])) << 16) +\
(((uint32) ((uchar) (A)[3])) << 24)) +\
(((ulonglong) ((uchar) (A)[4])) << 32))
+#define uint6korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) + \
+ (((uint32) ((uchar) (A)[1])) << 8) + \
+ (((uint32) ((uchar) (A)[2])) << 16) + \
+ (((uint32) ((uchar) (A)[3])) << 24)) + \
+ (((ulonglong) ((uchar) (A)[4])) << 32) + \
+ (((ulonglong) ((uchar) (A)[5])) << 40))
#define uint8korr(A) (*((ulonglong *) (A)))
#define sint8korr(A) (*((longlong *) (A)))
#define int2store(T,A) *((uint16*) (T))= (uint16) (A)
@@ -1134,6 +1148,12 @@ typedef char bool; /* Ordinary boolean values 0 1 */
*((T)+2)=(uchar) (((A) >> 16));\
*((T)+3)=(uchar) (((A) >> 24)); \
*((T)+4)=(uchar) (((A) >> 32)); } while(0)
+#define int6store(T,A) do { *(T)= (uchar)((A)); \
+ *((T)+1)=(uchar) (((A) >> 8)); \
+ *((T)+2)=(uchar) (((A) >> 16)); \
+ *((T)+3)=(uchar) (((A) >> 24)); \
+ *((T)+4)=(uchar) (((A) >> 32)); \
+ *((T)+5)=(uchar) (((A) >> 40)); } while(0)
#define int8store(T,A) *((ulonglong *) (T))= (ulonglong) (A)
typedef union {
@@ -1190,6 +1210,12 @@ do { doubleget_union _tmp; \
(((uint32) ((uchar) (A)[2])) << 16) +\
(((uint32) ((uchar) (A)[3])) << 24)) +\
(((ulonglong) ((uchar) (A)[4])) << 32))
+#define uint6korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) + \
+ (((uint32) ((uchar) (A)[1])) << 8) + \
+ (((uint32) ((uchar) (A)[2])) << 16) + \
+ (((uint32) ((uchar) (A)[3])) << 24)) + \
+ (((ulonglong) ((uchar) (A)[4])) << 32) + \
+ (((ulonglong) ((uchar) (A)[5])) << 40))
#define uint8korr(A) ((ulonglong)(((uint32) ((uchar) (A)[0])) +\
(((uint32) ((uchar) (A)[1])) << 8) +\
(((uint32) ((uchar) (A)[2])) << 16) +\
@@ -1217,6 +1243,12 @@ do { doubleget_union _tmp; \
*(((char *)(T))+2)=(((A) >> 16));\
*(((char *)(T))+3)=(((A) >> 24)); \
*(((char *)(T))+4)=(((A) >> 32)); } while(0)
+#define int6store(T,A) do { *((char *)(T))=((A));\
+ *(((char *)(T))+1)=(((A) >> 8)); \
+ *(((char *)(T))+2)=(((A) >> 16)); \
+ *(((char *)(T))+3)=(((A) >> 24)); \
+ *(((char *)(T))+4)=(((A) >> 32)); \
+ *(((char *)(T))+5)=(((A) >> 40)); } while(0)
#define int8store(T,A) do { uint def_temp= (uint) (A), def_temp2= (uint) ((A) >> 32); \
int4store((T),def_temp); \
int4store((T+4),def_temp2); } while(0)
diff --git a/include/my_vle.h b/include/my_vle.h
new file mode 100644
index 00000000000..94d293487f4
--- /dev/null
+++ b/include/my_vle.h
@@ -0,0 +1,42 @@
+/*
+ Copyright (C) 2005 MySQL AB
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+*/
+
+#ifndef VLE_H
+#define VLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "my_global.h"
+
+/*
+ The size (in bytes) required to store the object ITEM, which can be
+ either an expression or a type (since sizeof() is used on the item).
+*/
+#define my_vle_sizeof(ITEM) (((sizeof(ITEM) * CHAR_BIT) + 6) / 7)
+
+byte *my_vle_encode(byte *vle, my_size_t max, ulong value);
+byte const *my_vle_decode(ulong *value_ptr, byte const *vle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am
index a63b4cbf178..c1db94e9d71 100644
--- a/mysql-test/Makefile.am
+++ b/mysql-test/Makefile.am
@@ -36,15 +36,24 @@ mysql_test_run_new_SOURCES= mysql_test_run_new.c my_manage.c my_create_tables.c
dist-hook:
- mkdir -p $(distdir)/t $(distdir)/r $(distdir)/include \
- $(distdir)/std_data $(distdir)/lib
+ mkdir -p \
+ $(distdir)/t \
+ $(distdir)/extra/binlog_tests \
+ $(distdir)/extra/rpl_tests \
+ $(distdir)/r \
+ $(distdir)/include \
+ $(distdir)/std_data \
+ $(distdir)/lib
-$(INSTALL_DATA) $(srcdir)/t/*.def $(distdir)/t
$(INSTALL_DATA) $(srcdir)/t/*.test $(distdir)/t
-$(INSTALL_DATA) $(srcdir)/t/*.imtest $(distdir)/t
$(INSTALL_DATA) $(srcdir)/t/*.sql $(distdir)/t
-$(INSTALL_DATA) $(srcdir)/t/*.disabled $(distdir)/t
- $(INSTALL_DATA) $(srcdir)/t/*.opt $(srcdir)/t/*.slave-mi $(distdir)/t
- $(INSTALL_SCRIPT) $(srcdir)/t/*.sh $(distdir)/t
+ $(INSTALL_DATA) $(srcdir)/t/*.opt $(srcdir)/t/*.sh $(srcdir)/t/*.slave-mi $(distdir)/t
+ $(INSTALL_DATA) $(srcdir)/extra/binlog_tests/*.test $(distdir)/extra/binlog_tests
+ $(INSTALL_DATA) $(srcdir)/extra/rpl_tests/*.test $(distdir)/extra/rpl_tests
+ -$(INSTALL_DATA) $(srcdir)/extra/binlog_tests/*.opt $(distdir)/extra/binlog_tests
+ -$(INSTALL_DATA) $(srcdir)/extra/rpl_tests/*.opt $(distdir)/extra/rpl_tests
$(INSTALL_DATA) $(srcdir)/include/*.inc $(distdir)/include
$(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.require $(distdir)/r
$(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(distdir)/std_data
@@ -59,6 +68,8 @@ dist-hook:
install-data-local:
$(mkinstalldirs) \
$(DESTDIR)$(testdir)/t \
+ $(DESTDIR)$(testdir)/extra/binlog_tests \
+ $(DESTDIR)$(testdir)/extra/rpl_tests \
$(DESTDIR)$(testdir)/r \
$(DESTDIR)$(testdir)/include \
$(DESTDIR)$(testdir)/std_data \
@@ -74,6 +85,10 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/t/*.slave-mi $(DESTDIR)$(testdir)/t
$(INSTALL_DATA) $(srcdir)/r/*.result $(DESTDIR)$(testdir)/r
$(INSTALL_DATA) $(srcdir)/r/*.require $(DESTDIR)$(testdir)/r
+ $(INSTALL_DATA) $(srcdir)/extra/binlog_tests/*.test $(DESTDIR)$(testdir)/extra/binlog_tests
+ $(INSTALL_DATA) $(srcdir)/extra/rpl_tests/*.test $(DESTDIR)$(testdir)/extra/rpl_tests
+ -$(INSTALL_DATA) $(srcdir)/extra/binlog_tests/*.opt $(DESTDIR)$(testdir)/extra/binlog_tests
+ -$(INSTALL_DATA) $(srcdir)/extra/rpl_tests/*.opt $(DESTDIR)$(testdir)/extra/rpl_tests
$(INSTALL_DATA) $(srcdir)/include/*.inc $(DESTDIR)$(testdir)/include
$(INSTALL_DATA) $(srcdir)/std_data/*.dat $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.*001 $(DESTDIR)$(testdir)/std_data
diff --git a/mysql-test/t/binlog.test b/mysql-test/extra/binlog_tests/binlog.test
index 2310e800df7..8eb1dcb7dc3 100644
--- a/mysql-test/t/binlog.test
+++ b/mysql-test/extra/binlog_tests/binlog.test
@@ -1,8 +1,10 @@
#
# misc binlogging tests that do not require a slave running
#
+
-- source include/have_bdb.inc
-- source include/have_innodb.inc
+-- source include/have_debug.inc
--disable_warnings
drop table if exists t1, t2;
@@ -18,9 +20,8 @@ begin;
insert t2 values (5);
commit;
# first COMMIT must be Query_log_event, second - Xid_log_event
---replace_result "xid=18" "xid=11"
--replace_column 2 # 5 #
-show binlog events from 98;
+show binlog events from 102;
drop table t1,t2;
#
@@ -40,9 +41,7 @@ while ($1)
--enable_query_log
commit;
drop table t1;
---replace_result "xid=29" "xid=18"
--replace_column 2 # 5 #
-show binlog events in 'master-bin.000001' from 98;
+show binlog events in 'master-bin.000001' from 102;
--replace_column 2 # 5 #
-show binlog events in 'master-bin.000002' from 98;
-
+show binlog events in 'master-bin.000002' from 102;
diff --git a/mysql-test/t/blackhole.test b/mysql-test/extra/binlog_tests/blackhole.test
index 1b5a9beb887..1b5a9beb887 100644
--- a/mysql-test/t/blackhole.test
+++ b/mysql-test/extra/binlog_tests/blackhole.test
diff --git a/mysql-test/t/ctype_cp932.test b/mysql-test/extra/binlog_tests/ctype_cp932.test
index 082786e38af..ab1dd6d0108 100644
--- a/mysql-test/t/ctype_cp932.test
+++ b/mysql-test/extra/binlog_tests/ctype_cp932.test
@@ -415,7 +415,7 @@ SET @var1= x'8300';
# code (and I have used it to test the fix) until there is some way to
# exercise this code from mysql-test-run.
EXECUTE stmt1 USING @var1;
-SHOW BINLOG EVENTS FROM 98;
+SHOW BINLOG EVENTS FROM 102;
SELECT HEX(f1) FROM t1;
DROP table t1;
# end test for bug#11338
diff --git a/mysql-test/t/ctype_cp932_binlog.test b/mysql-test/extra/binlog_tests/ctype_cp932_binlog.test
index 270e27cf27f..a17f8f827a6 100644
--- a/mysql-test/t/ctype_cp932_binlog.test
+++ b/mysql-test/extra/binlog_tests/ctype_cp932_binlog.test
@@ -26,7 +26,8 @@ SET @var1= x'8300';
# code (and I have used it to test the fix) until there is some way to
# exercise this code from mysql-test-run.
EXECUTE stmt1 USING @var1;
-SHOW BINLOG EVENTS FROM 98;
+--replace_column 2 # 5 #
+SHOW BINLOG EVENTS FROM 102;
SELECT HEX(f1) FROM t1;
DROP table t1;
# end test for bug#11338
diff --git a/mysql-test/t/ctype_ucs_binlog.test b/mysql-test/extra/binlog_tests/ctype_ucs_binlog.test
index 1ce55edd469..f7f46388033 100644
--- a/mysql-test/t/ctype_ucs_binlog.test
+++ b/mysql-test/extra/binlog_tests/ctype_ucs_binlog.test
@@ -9,7 +9,7 @@ create table t2 (c char(30)) charset=ucs2;
set @v=convert('abc' using ucs2);
reset master;
insert into t2 values (@v);
-show binlog events from 98;
+show binlog events from 102;
# more important than SHOW BINLOG EVENTS, mysqlbinlog (where we
# absolutely need variables names to be quoted and strings to be
# escaped).
diff --git a/mysql-test/t/drop_temp_table.test b/mysql-test/extra/binlog_tests/drop_temp_table.test
index bc06de4096c..bc06de4096c 100644
--- a/mysql-test/t/drop_temp_table.test
+++ b/mysql-test/extra/binlog_tests/drop_temp_table.test
diff --git a/mysql-test/extra/binlog_tests/innodb_stat.test b/mysql-test/extra/binlog_tests/innodb_stat.test
new file mode 100644
index 00000000000..131c244d8fd
--- /dev/null
+++ b/mysql-test/extra/binlog_tests/innodb_stat.test
@@ -0,0 +1,47 @@
+-- source include/have_innodb.inc
+
+#
+# Let us test binlog_cache_use and binlog_cache_disk_use status vars.
+# Actually this test has nothing to do with innodb per se, it just requires
+# transactional table.
+#
+show status like "binlog_cache_use";
+show status like "binlog_cache_disk_use";
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table t1 (a int) engine=innodb;
+
+# Now we are going to create transaction which is long enough so its
+# transaction binlog will be flushed to disk...
+let $1=2000;
+disable_query_log;
+begin;
+while ($1)
+{
+ eval insert into t1 values( $1 );
+ dec $1;
+}
+commit;
+enable_query_log;
+show status like "binlog_cache_use";
+show status like "binlog_cache_disk_use";
+
+# Transaction which should not be flushed to disk and so should not
+# increase binlog_cache_disk_use.
+begin;
+delete from t1;
+commit;
+show status like "binlog_cache_use";
+show status like "binlog_cache_disk_use";
+drop table t1;
+
+# Test for testable InnoDB status variables. This test
+# uses previous ones(pages_created, rows_deleted, ...).
+show status like "Innodb_buffer_pool_pages_total";
+show status like "Innodb_page_size";
+show status like "Innodb_rows_deleted";
+show status like "Innodb_rows_inserted";
+show status like "Innodb_rows_updated";
+
diff --git a/mysql-test/t/insert_select-binlog.test b/mysql-test/extra/binlog_tests/insert_select-binlog.test
index d4041f86ab5..d4041f86ab5 100644
--- a/mysql-test/t/insert_select-binlog.test
+++ b/mysql-test/extra/binlog_tests/insert_select-binlog.test
diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test
index 658584b625e..a9612b831f1 100644
--- a/mysql-test/t/mix_innodb_myisam_binlog.test
+++ b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test
@@ -9,6 +9,7 @@
-- source include/not_embedded.inc
-- source include/have_innodb.inc
+-- source include/have_debug.inc
--disable_warnings
drop table if exists t1, t2;
@@ -29,8 +30,7 @@ insert into t2 select * from t1;
commit;
--replace_column 5 #
---replace_result "xid=15" "xid=8"
-show binlog events from 98;
+show binlog events from 102;
delete from t1;
delete from t2;
@@ -43,7 +43,7 @@ insert into t2 select * from t1;
rollback;
--replace_column 5 #
-show binlog events from 98;
+show binlog events from 102;
delete from t1;
delete from t2;
@@ -58,8 +58,7 @@ rollback to savepoint my_savepoint;
commit;
--replace_column 5 #
---replace_result "xid=48" "xid=25"
-show binlog events from 98;
+show binlog events from 102;
delete from t1;
delete from t2;
@@ -76,8 +75,7 @@ commit;
select a from t1 order by a; # check that savepoints work :)
--replace_column 5 #
---replace_result "xid=70" "xid=37"
-show binlog events from 98;
+show binlog events from 102;
# and when ROLLBACK is not explicit?
delete from t1;
@@ -98,7 +96,7 @@ connection con2;
# logging has been done, we use a user lock.
select get_lock("a",10);
--replace_column 5 #
-show binlog events from 98;
+show binlog events from 102;
# and when not in a transact1on?
delete from t1;
@@ -109,8 +107,7 @@ insert into t1 values(9);
insert into t2 select * from t1;
--replace_column 5 #
---replace_result "xid=119" "xid=60"
-show binlog events from 98;
+show binlog events from 102;
# Check that when the query updat1ng the MyISAM table is the first in the
# transaction, we log it immediately.
@@ -122,14 +119,12 @@ insert into t1 values(10); # first make t1 non-empty
begin;
insert into t2 select * from t1;
--replace_column 5 #
---replace_result "xid=133" "xid=66"
-show binlog events from 98;
+show binlog events from 102;
insert into t1 values(11);
commit;
--replace_column 5 #
---replace_result "xid=133" "xid=66" "xid=136" "xid=68"
-show binlog events from 98;
+show binlog events from 102;
# Check that things work like before this BEGIN/ROLLBACK code was added,
@@ -147,8 +142,7 @@ insert into t2 select * from t1;
commit;
--replace_column 5 #
---replace_result "xid=155" "xid=78"
-show binlog events from 98;
+show binlog events from 102;
delete from t1;
delete from t2;
@@ -160,7 +154,7 @@ insert into t2 select * from t1;
rollback;
--replace_column 5 #
-show binlog events from 98;
+show binlog events from 102;
delete from t1;
delete from t2;
@@ -175,8 +169,7 @@ rollback to savepoint my_savepoint;
commit;
--replace_column 5 #
---replace_result "xid=187" "xid=94"
-show binlog events from 98;
+show binlog events from 102;
delete from t1;
delete from t2;
@@ -193,8 +186,7 @@ commit;
select a from t1 order by a; # check that savepoints work :)
--replace_column 5 #
---replace_result "xid=208" "xid=105"
-show binlog events from 98;
+show binlog events from 102;
# Test for BUG#5714, where a MyISAM update in the transaction used to
# release row-level locks in InnoDB
@@ -254,8 +246,7 @@ disconnect con2;
connection con3;
select get_lock("lock1",60);
--replace_column 5 #
---replace_result "xid=208" "xid=105" "xid=227" "xid=114" "xid=230" "xid=115" "xid=234" "xid=117" "xid=261" "xid=132"
-show binlog events from 98;
+show binlog events from 102;
do release_lock("lock1");
drop table t0,t2;
diff --git a/mysql-test/extra/rpl_tests/rpl000006.test b/mysql-test/extra/rpl_tests/rpl000006.test
new file mode 100644
index 00000000000..272e5744d9c
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl000006.test
@@ -0,0 +1,47 @@
+#
+# Test forced timestamp
+#
+-- source include/master-slave.inc
+
+# Don't log table creating to the slave as we want to test LOAD TABLE
+set SQL_LOG_BIN=0,timestamp=200006;
+create table t1(t timestamp not null,a char(1));
+insert into t1 ( a) values ('F');
+select unix_timestamp(t) from t1;
+connection slave;
+load table t1 from master;
+select unix_timestamp(t) from t1;
+
+# Delete the created table on master and slave
+connection master;
+set SQL_LOG_BIN=1,timestamp=default;
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
+connection master;
+
+#
+# Test copying table with checksum
+#
+
+# Don't log table creating to the slave as we want to test LOAD TABLE
+set SQL_LOG_BIN=0;
+
+eval CREATE TABLE t1 (
+ a int not null
+) ENGINE=$engine_type MAX_ROWS=4000 CHECKSUM=1;
+INSERT INTO t1 VALUES (1);
+save_master_pos;
+connection slave;
+sync_with_master;
+load table t1 from master;
+check table t1;
+drop table t1;
+connection master;
+drop table t1;
+save_master_pos;
+connection slave;
+sync_with_master;
+
+# End of 4.1 tests
diff --git a/mysql-test/extra/rpl_tests/rpl_auto_increment.test b/mysql-test/extra/rpl_tests/rpl_auto_increment.test
new file mode 100644
index 00000000000..e7ea85f9f71
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_auto_increment.test
@@ -0,0 +1,103 @@
+#
+# Test of auto_increment with offset
+#
+-- source include/master-slave.inc
+
+eval create table t1 (a int not null auto_increment,b int, primary key (a)) engine=$engine_type2 auto_increment=3;
+insert into t1 values (NULL,1),(NULL,2),(NULL,3);
+select * from t1;
+
+sync_slave_with_master;
+select * from t1;
+connection master;
+drop table t1;
+
+eval create table t1 (a int not null auto_increment,b int, primary key (a)) engine=$engine_type2;
+insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4);
+delete from t1 where b=4;
+insert into t1 values (NULL,5),(NULL,6);
+select * from t1;
+
+sync_slave_with_master;
+select * from t1;
+connection master;
+
+drop table t1;
+
+set @@session.auto_increment_increment=100, @@session.auto_increment_offset=10;
+show variables like "%auto_inc%";
+
+eval create table t1 (a int not null auto_increment, primary key (a)) engine=$engine_type2;
+# Insert with 2 insert statements to get better testing of logging
+insert into t1 values (NULL),(5),(NULL);
+insert into t1 values (250),(NULL);
+select * from t1;
+insert into t1 values (1000);
+set @@insert_id=400;
+insert into t1 values(NULL),(NULL);
+select * from t1;
+
+sync_slave_with_master;
+select * from t1;
+connection master;
+drop table t1;
+
+#
+# Same test with innodb (as the innodb code is a bit different)
+#
+eval create table t1 (a int not null auto_increment, primary key (a)) engine=$engine_type;
+# Insert with 2 insert statements to get better testing of logging
+insert into t1 values (NULL),(5),(NULL);
+insert into t1 values (250),(NULL);
+select * from t1;
+insert into t1 values (1000);
+set @@insert_id=400;
+insert into t1 values(NULL),(NULL);
+select * from t1;
+
+sync_slave_with_master;
+select * from t1;
+connection master;
+drop table t1;
+
+set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1;
+eval create table t1 (a int not null auto_increment, primary key (a)) engine=$engine_type2;
+# Insert with 2 insert statements to get better testing of logging
+insert into t1 values (NULL),(5),(NULL),(NULL);
+insert into t1 values (500),(NULL),(502),(NULL),(NULL);
+select * from t1;
+set @@insert_id=600;
+--error 1062
+insert into t1 values(600),(NULL),(NULL);
+set @@insert_id=600;
+insert ignore into t1 values(600),(NULL),(NULL),(610),(NULL);
+select * from t1;
+
+sync_slave_with_master;
+select * from t1;
+connection master;
+drop table t1;
+
+#
+# Test that auto-increment works when slave has rows in the table
+#
+set @@session.auto_increment_increment=10, @@session.auto_increment_offset=1;
+
+eval create table t1 (a int not null auto_increment, primary key (a)) engine=$engine_type2;
+
+sync_slave_with_master;
+insert into t1 values(2),(12),(22),(32),(42);
+connection master;
+
+insert into t1 values (NULL),(NULL);
+insert into t1 values (3),(NULL),(NULL);
+select * from t1;
+
+sync_slave_with_master;
+select * from t1;
+connection master;
+
+drop table t1;
+
+# End cleanup
+sync_slave_with_master;
diff --git a/mysql-test/extra/rpl_tests/rpl_commit_after_flush.test b/mysql-test/extra/rpl_tests/rpl_commit_after_flush.test
new file mode 100644
index 00000000000..d63d7e4b07d
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_commit_after_flush.test
@@ -0,0 +1,22 @@
+#################################
+# Test updated to use a wrapper #
+#################################
+
+-- source include/master-slave.inc
+
+eval CREATE TABLE t1 (a INT) ENGINE=$engine_type;
+
+begin;
+insert into t1 values(1);
+flush tables with read lock;
+commit;
+save_master_pos;
+connection slave;
+sync_with_master;
+# cleanup
+connection master;
+unlock tables;
+drop table t1;
+sync_slave_with_master;
+
+# End of 4.1 tests
diff --git a/mysql-test/t/rpl_ddl.test b/mysql-test/extra/rpl_tests/rpl_ddl.test
index d2a41a305b6..0d9f390531f 100644
--- a/mysql-test/t/rpl_ddl.test
+++ b/mysql-test/extra/rpl_tests/rpl_ddl.test
@@ -28,9 +28,6 @@
# eval SELECT CONCAT('######## ','$my_stmt',' ########') as "";
#
---source include/have_innodb.inc
---source include/master-slave.inc
-
###############################################################
# Some preparations
###############################################################
@@ -54,28 +51,28 @@ DROP DATABASE IF EXISTS mysqltest3;
#
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
-CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE= "InnoDB";
+eval CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE=$engine_type;
INSERT INTO mysqltest1.t1 SET f1= 0;
-CREATE TABLE mysqltest1.t2 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t3 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t4 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t5 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t6 (f1 BIGINT) ENGINE= "InnoDB";
+eval CREATE TABLE mysqltest1.t2 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t3 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t4 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t5 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t6 (f1 BIGINT) ENGINE=$engine_type;
CREATE INDEX my_idx6 ON mysqltest1.t6(f1);
-CREATE TABLE mysqltest1.t7 (f1 BIGINT) ENGINE= "InnoDB";
+eval CREATE TABLE mysqltest1.t7 (f1 BIGINT) ENGINE=$engine_type;
INSERT INTO mysqltest1.t7 SET f1= 0;
-CREATE TABLE mysqltest1.t8 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t9 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t10 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t11 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t12 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t13 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t14 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t15 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t16 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t17 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t18 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t19 (f1 BIGINT) ENGINE= "InnoDB";
+eval CREATE TABLE mysqltest1.t8 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t9 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t10 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t11 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t12 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t13 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t14 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t15 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t16 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t17 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t18 (f1 BIGINT) ENGINE=$engine_type;
+eval CREATE TABLE mysqltest1.t19 (f1 BIGINT) ENGINE=$engine_type;
CREATE TEMPORARY TABLE mysqltest1.t23 (f1 BIGINT);
#
@@ -207,10 +204,10 @@ connection master;
SELECT '-------- switch to master -------' as "";
--enable_query_log
-let $my_stmt= CREATE TABLE mysqltest1.t21 (f1 BIGINT) ENGINE= "InnoDB";
+let $my_stmt= CREATE TABLE mysqltest1.t21 (f1 BIGINT) ENGINE=;
let $my_master_commit= true;
let $my_slave_commit= true;
---source include/rpl_stmt_seq.inc
+--source include/rpl_stmt_seq2.inc
# Note: Since this test is executed with a skip-innodb slave, the
# slave incorrectly commits the insert. One can *not* have InnoDB on
@@ -218,6 +215,9 @@ let $my_slave_commit= true;
# after a CREATE TEMPORARY TABLE should work correctly on the slave.
# For this to work properly the handler on the slave must be able to
# handle transactions (e.g. InnoDB or NDB).
+let $engine='';
+let $eng_type='';
+
let $my_stmt= CREATE TEMPORARY TABLE mysqltest1.t22 (f1 BIGINT);
let $my_master_commit= false;
let $my_slave_commit= true;
diff --git a/mysql-test/t/rpl_deadlock.test b/mysql-test/extra/rpl_tests/rpl_deadlock.test
index c74ed989ece..2582a901b3b 100644
--- a/mysql-test/t/rpl_deadlock.test
+++ b/mysql-test/extra/rpl_tests/rpl_deadlock.test
@@ -10,14 +10,13 @@
# We don't 'show status like 'slave_retried_transactions'' because this
# is not repeatable (depends on sleeps).
-source include/have_innodb.inc;
-source include/master-slave.inc;
+-- source include/master-slave.inc
connection master;
-create table t1 (a int not null, key(a)) engine=innodb;
-create table t2 (a int not null, key(a)) engine=innodb;
-create table t3 (a int) engine=innodb;
-create table t4 (a int) engine=innodb;
+eval CREATE TABLE t1 (a INT NOT NULL, KEY(a)) ENGINE=$engine_type;
+eval CREATE TABLE t2 (a INT NOT NULL, KEY(a)) ENGINE=$engine_type;
+eval CREATE TABLE t3 (a INT) ENGINE=$engine_type;
+eval CREATE TABLE t4 (a INT) ENGINE=$engine_type;
show variables like 'slave_transaction_retries';
sync_slave_with_master;
@@ -65,14 +64,14 @@ sync_with_master;
select * from t1; # check that slave succeeded finally
select * from t2;
# check that no error is reported
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 7 # 8 # 9 # 16 # 22 # 23 # 33 #
--replace_result $MASTER_MYPORT MASTER_MYPORT
show slave status;
# 2) Test lock wait timeout
stop slave;
-change master to master_log_pos=532; # the BEGIN log event
+change master to master_log_pos=536; # the BEGIN log event
begin;
select * from t2 for update; # hold lock
start slave;
@@ -82,7 +81,7 @@ sync_with_master;
select * from t1; # check that slave succeeded finally
select * from t2;
# check that no error is reported
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 7 # 8 # 9 # 16 # 22 # 23 # 33 #
--replace_result $MASTER_MYPORT MASTER_MYPORT
show slave status;
@@ -93,7 +92,7 @@ set global max_relay_log_size=0;
# This is really copy-paste of 2) of above
stop slave;
-change master to master_log_pos=532;
+change master to master_log_pos=536;
begin;
select * from t2 for update;
start slave;
@@ -102,7 +101,7 @@ commit;
sync_with_master;
select * from t1;
select * from t2;
---replace_column 1 # 8 # 9 # 11 # 23 # 33 #
+--replace_column 1 # 7 # 8 # 9 # 11 # 16 # 22 # 23 # 33 #
--replace_result $MASTER_MYPORT MASTER_MYPORT
show slave status;
diff --git a/mysql-test/extra/rpl_tests/rpl_delete_no_where.test b/mysql-test/extra/rpl_tests/rpl_delete_no_where.test
new file mode 100644
index 00000000000..4db9e0fb63f
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_delete_no_where.test
@@ -0,0 +1,19 @@
+# Test to see if a DELETE which triggers a fast deletion of all rows
+# (not internally row-per-row but more like a TRUNCATE, MyISAM
+# supports that), is replicated (BUG#13576).
+
+-- source include/master-slave.inc
+
+eval create table t1 (a int, b int) engine=$engine_type;
+insert into t1 values(1,1);
+sync_slave_with_master;
+select * from t1;
+connection master;
+delete from t1;
+sync_slave_with_master;
+select * from t1;
+
+# cleanup
+connection master;
+drop table t1;
+sync_slave_with_master;
diff --git a/mysql-test/t/rpl_error_ignored_table.test b/mysql-test/extra/rpl_tests/rpl_err_ignoredtable.test
index 339d966dbb3..e439dbdc388 100644
--- a/mysql-test/t/rpl_error_ignored_table.test
+++ b/mysql-test/extra/rpl_tests/rpl_err_ignoredtable.test
@@ -2,7 +2,9 @@
# Bug #797: If a query is ignored on slave (replicate-ignore-table) the slave
# still checks that it has the same error as on the master.
-source include/master-slave.inc;
+# Requires statement logging
+-- source include/master-slave.inc
+
connection master;
create table t1 (a int primary key);
# generate an error that goes to the binlog
@@ -49,7 +51,7 @@ connection master;
reap;
connection master1;
--replace_column 2 # 5 #
-show binlog events from 98;
+show binlog events from 102;
save_master_pos;
connection slave;
# SQL slave thread should not have stopped (because table of the killed
diff --git a/mysql-test/extra/rpl_tests/rpl_failed_optimize.test b/mysql-test/extra/rpl_tests/rpl_failed_optimize.test
new file mode 100644
index 00000000000..598f9746fab
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_failed_optimize.test
@@ -0,0 +1,19 @@
+-- source include/master-slave.inc
+
+#
+# BUG#5551 "Failed OPTIMIZE TABLE is logged to binary log"
+# Replication should work when OPTIMIZE TABLE timeouts, and
+# when OPTIMIZE TABLE is executed on a non-existing table
+#
+
+eval CREATE TABLE t1 ( a int ) ENGINE=$engine_type;
+BEGIN;
+INSERT INTO t1 VALUES (1);
+
+connection master1;
+OPTIMIZE TABLE t1;
+
+OPTIMIZE TABLE non_existing;
+sync_slave_with_master;
+
+# End of 4.1 tests
diff --git a/mysql-test/t/rpl_flush_tables.test b/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test
index 92aef9c85d0..c046487729e 100644
--- a/mysql-test/t/rpl_flush_tables.test
+++ b/mysql-test/extra/rpl_tests/rpl_flsh_tbls.test
@@ -1,12 +1,9 @@
-#
+# depends on the binlog output
# Test of replicating FLUSH TABLES to make
# RENAME TABLE work with MERGE tables on the slave.
# Test of FLUSH NO_WRITE_TO_BINLOG by the way.
#
---source include/master-slave.inc
-# Skipped on Windows because it can't handle a table underlying an open
-# merge table getting renamed.
---source include/not_windows.inc
+-- source include/master-slave.inc
create table t1 (a int);
insert into t1 values (10);
@@ -22,7 +19,7 @@ flush no_write_to_binlog tables;
# Check that it's not in the binlog.
--replace_result $SERVER_VERSION SERVER_VERSION
--replace_column 2 # 5 #
-show binlog events;
+eval SHOW BINLOG EVENTS FROM $rename_event_pos ;
# Check that the master is not confused.
select * from t3;
# This FLUSH should go into the binlog to not confuse the slave.
@@ -30,7 +27,7 @@ flush tables;
# Check that it's in the binlog.
--replace_result $SERVER_VERSION SERVER_VERSION
--replace_column 2 # 5 #
-show binlog events;
+eval SHOW BINLOG EVENTS FROM $rename_event_pos ;
save_master_pos;
connection slave;
sync_with_master;
@@ -50,4 +47,4 @@ sleep 1;
stop slave;
# End of 4.1 tests
-# Adding comment for force manual merge 5.0 -> wl1012. Delete me if needed.
+
diff --git a/mysql-test/extra/rpl_tests/rpl_foreign_key.test b/mysql-test/extra/rpl_tests/rpl_foreign_key.test
new file mode 100644
index 00000000000..20ec0e4179e
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_foreign_key.test
@@ -0,0 +1,32 @@
+# Check the replication of the FOREIGN_KEY_CHECKS variable.
+
+-- source include/master-slave.inc
+
+eval CREATE TABLE t1 (a INT AUTO_INCREMENT KEY) ENGINE=$engine_type;
+eval CREATE TABLE t2 (b INT AUTO_INCREMENT KEY, c INT, FOREIGN KEY(b) REFERENCES t1(a)) ENGINE=$engine_type;
+
+SET FOREIGN_KEY_CHECKS=0;
+INSERT INTO t1 VALUES (10);
+INSERT INTO t1 VALUES (NULL),(NULL),(NULL);
+INSERT INTO t2 VALUES (5,0);
+INSERT INTO t2 VALUES (NULL,LAST_INSERT_ID());
+SET FOREIGN_KEY_CHECKS=1;
+SELECT * FROM t1;
+SELECT * FROM t2;
+sync_slave_with_master;
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+connection master;
+SET TIMESTAMP=1000000000;
+CREATE TABLE t3 ( a INT UNIQUE );
+SET FOREIGN_KEY_CHECKS=0;
+--error 1062
+INSERT INTO t3 VALUES (1),(1);
+sync_slave_with_master;
+
+connection master;
+SET FOREIGN_KEY_CHECKS=0;
+DROP TABLE IF EXISTS t1,t2,t3;
+SET FOREIGN_KEY_CHECKS=1;
+
diff --git a/mysql-test/extra/rpl_tests/rpl_insert_id.test b/mysql-test/extra/rpl_tests/rpl_insert_id.test
new file mode 100644
index 00000000000..adf8631bea2
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_insert_id.test
@@ -0,0 +1,78 @@
+# See if queries that use both auto_increment and LAST_INSERT_ID()
+# are replicated well
+
+# We also check how the foreign_key_check variable is replicated
+
+-- source include/master-slave.inc
+#should work for both SBR and RBR
+
+connection master;
+create table t1(a int auto_increment, key(a));
+create table t2(b int auto_increment, c int, key(b));
+insert into t1 values (1),(2),(3);
+insert into t1 values (null);
+insert into t2 values (null,last_insert_id());
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from t1;
+select * from t2;
+connection master;
+#check if multi-line inserts,
+#which set last_insert_id to the first id inserted,
+#are replicated the same way
+drop table t1;
+drop table t2;
+--disable_warnings
+eval create table t1(a int auto_increment, key(a)) engine=$engine_type;
+eval create table t2(b int auto_increment, c int, key(b), foreign key(b) references t1(a)) engine=$engine_type;
+--enable_warnings
+SET FOREIGN_KEY_CHECKS=0;
+insert into t1 values (10);
+insert into t1 values (null),(null),(null);
+insert into t2 values (5,0);
+insert into t2 values (null,last_insert_id());
+SET FOREIGN_KEY_CHECKS=1;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from t1;
+select * from t2;
+connection master;
+
+# check if INSERT SELECT in auto_increment is well replicated (bug #490)
+
+drop table t2;
+drop table t1;
+create table t1(a int auto_increment, key(a));
+create table t2(b int auto_increment, c int, key(b));
+insert into t1 values (10);
+insert into t1 values (null),(null),(null);
+insert into t2 values (5,0);
+insert into t2 (c) select * from t1;
+select * from t2;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from t1;
+select * from t2;
+connection master;
+drop table t1;
+drop table t2;
+save_master_pos;
+connection slave;
+sync_with_master;
+
+#
+# Bug#8412: Error codes reported in binary log for CHARACTER SET,
+# FOREIGN_KEY_CHECKS
+#
+connection master;
+SET TIMESTAMP=1000000000;
+CREATE TABLE t1 ( a INT UNIQUE );
+SET FOREIGN_KEY_CHECKS=0;
+--error 1062
+INSERT INTO t1 VALUES (1),(1);
+sync_slave_with_master;
+
+# End of 4.1 tests
diff --git a/mysql-test/extra/rpl_tests/rpl_insert_ignore.test b/mysql-test/extra/rpl_tests/rpl_insert_ignore.test
new file mode 100644
index 00000000000..207b53b6fb4
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_insert_ignore.test
@@ -0,0 +1,71 @@
+# Testcase for BUG#6287 "Slave skips auto_increment values in Replication with InnoDB"
+# The bug was that if on master, INSERT IGNORE ignored some
+# rows, and the table was InnoDB with auto_inc column, then on slave
+# some rows received an auto_inc bigger than on master.
+# Slave needs to be started with --innodb to store table in InnoDB.
+# Same test for MyISAM (which had no bug).
+
+-- source include/master-slave.inc
+
+eval CREATE TABLE t1 (
+ a int unsigned not null auto_increment primary key,
+ b int unsigned,
+ unique (b)
+) ENGINE=$engine_type;
+
+eval CREATE TABLE t2 (
+ a int unsigned, # to force INSERT SELECT to have a certain order
+ b int unsigned
+) ENGINE=$engine_type;
+
+
+INSERT INTO t1 VALUES (NULL, 1);
+INSERT INTO t1 VALUES (NULL, 2);
+INSERT INTO t1 VALUES (NULL, 3);
+INSERT INTO t1 VALUES (NULL, 4);
+
+# An alternation of values which will conflict in t1 and will not.
+
+INSERT INTO t2 VALUES (1, 1);
+INSERT INTO t2 VALUES (2, 2);
+INSERT INTO t2 VALUES (3, 5);
+INSERT INTO t2 VALUES (4, 3);
+INSERT INTO t2 VALUES (5, 4);
+INSERT INTO t2 VALUES (6, 6);
+
+INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a;
+
+# Compare results
+
+SELECT * FROM t1 ORDER BY a;
+
+sync_slave_with_master;
+SELECT * FROM t1 ORDER BY a;
+
+# Now do the same for MyISAM
+
+connection master;
+drop table t1;
+eval CREATE TABLE t1 (
+ a int unsigned not null auto_increment primary key,
+ b int unsigned,
+ unique (b)
+) ENGINE=$engine_type2;
+
+INSERT INTO t1 VALUES (1, 1);
+INSERT INTO t1 VALUES (2, 2);
+INSERT INTO t1 VALUES (3, 3);
+INSERT INTO t1 VALUES (4, 4);
+
+INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a;
+
+SELECT * FROM t1 ORDER BY a;
+
+sync_slave_with_master;
+SELECT * FROM t1 ORDER BY a;
+
+connection master;
+drop table t1, t2;
+sync_slave_with_master;
+
+# End of 4.1 tests
diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test
new file mode 100644
index 00000000000..0da3a8b8011
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test
@@ -0,0 +1,156 @@
+# Requires statement logging
+-- source include/have_binlog_format_statement.inc
+
+# See if replication of a "LOAD DATA in an autoincrement column"
+# Honours autoincrement values
+# i.e. if the master and slave have the same sequence
+#
+# check replication of load data for temporary tables with additional
+# parameters
+#
+# check if duplicate entries trigger an error (they should unless IGNORE or
+# REPLACE was used on the master) (bug 571).
+#
+# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and
+# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986)
+
+-- source include/master-slave.inc
+
+connection slave;
+reset master;
+connection master;
+
+create table t1(a int not null auto_increment, b int, primary key(a) );
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+
+create temporary table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60));
+load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines;
+
+create table t3 (day date,id int(9),category enum('a','b','c'),name varchar(60));
+insert into t3 select * from t2;
+
+save_master_pos;
+connection slave;
+sync_with_master;
+
+select * from t1;
+select * from t3;
+# We want to be sure that LOAD DATA is in the slave's binlog.
+# But we can't simply read this binlog, because as the slave has not been
+# restarted for this test, the file_id is uncertain (would cause test
+# failures). So instead, we test if the binlog looks long enough to
+# contain LOAD DATA. Since 5.0.3 we assume that binlog of 1292 is ok.
+# If LOAD DATA was not logged, the binlog would be shorter.
+show master status;
+
+connection master;
+
+drop table t1;
+drop table t2;
+drop table t3;
+create table t1(a int, b int, unique(b));
+
+save_master_pos;
+connection slave;
+sync_with_master;
+
+# See if slave stops when there's a duplicate entry for key error in LOAD DATA
+
+insert into t1 values(1,10);
+
+connection master;
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+
+save_master_pos;
+connection slave;
+# The SQL slave thread should be stopped now.
+wait_for_slave_to_stop;
+
+# Skip the bad event and see if error is cleared in SHOW SLAVE STATUS by START
+# SLAVE, even though we are not executing any event (as sql_slave_skip_counter
+# takes us directly to the end of the relay log).
+
+set global sql_slave_skip_counter=1;
+start slave;
+sync_with_master;
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
+show slave status;
+
+# Trigger error again to test CHANGE MASTER
+
+connection master;
+set sql_log_bin=0;
+delete from t1;
+set sql_log_bin=1;
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+save_master_pos;
+connection slave;
+# The SQL slave thread should be stopped now.
+# Exec_Master_Log_Pos should point to the start of Execute event
+# for last load data.
+wait_for_slave_to_stop;
+
+# CHANGE MASTER and see if error is cleared in SHOW SLAVE STATUS.
+stop slave;
+change master to master_user='test';
+change master to master_user='root';
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
+show slave status;
+
+# Trigger error again to test RESET SLAVE
+
+set global sql_slave_skip_counter=1;
+start slave;
+sync_with_master;
+connection master;
+set sql_log_bin=0;
+delete from t1;
+set sql_log_bin=1;
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+save_master_pos;
+connection slave;
+# The SQL slave thread should be stopped now.
+wait_for_slave_to_stop;
+
+# RESET SLAVE and see if error is cleared in SHOW SLAVE STATUS.
+stop slave;
+reset slave;
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
+show slave status;
+
+# Finally, see if logging is done ok on master for a failing LOAD DATA INFILE
+
+connection master;
+reset master;
+eval create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60),
+unique(day)) engine=$engine_type; # no transactions
+--error 1062
+load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
+terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
+'\n##\n' starting by '>' ignore 1 lines;
+select * from t2;
+save_master_pos;
+connection slave;
+start slave;
+sync_with_master;
+select * from t2;
+
+# verify that if no error on slave, this is an error
+
+alter table t2 drop key day;
+connection master;
+delete from t2;
+--error 1062
+load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
+terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
+'\n##\n' starting by '>' ignore 1 lines;
+connection slave;
+wait_for_slave_to_stop;
+drop table t2;
+connection master;
+drop table t2;
+
+# End of 4.1 tests
diff --git a/mysql-test/t/rpl_loaddata_rule_m.test b/mysql-test/extra/rpl_tests/rpl_loaddata_m.test
index c956f2c7720..ef90283f80e 100644
--- a/mysql-test/t/rpl_loaddata_rule_m.test
+++ b/mysql-test/extra/rpl_tests/rpl_loaddata_m.test
@@ -2,7 +2,8 @@
# exist.
# This is for BUG#1100 (LOAD DATA INFILE was half-logged).
-source include/master-slave.inc;
+
+-- source include/master-slave.inc
--disable_warnings
drop database if exists mysqltest;
@@ -16,15 +17,12 @@ stop slave; # don't need slave for this test
connection master;
# 'test' is the current database
create database mysqltest;
-create table t1(a int, b int, unique(b));
use mysqltest;
-load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
+create table t1(a int, b int, unique(b));
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
# Starting from 5.0.3 LOAD DATA is replicated much in the same way as ordinary
# query so "show binlog ..." should show two events (before 5.0.3 no events
# were returned).
--replace_column 2 # 5 #
-show binlog events from 98;
+show binlog events from 102;
drop database mysqltest;
-
-# End of 4.1 tests
-# Adding comment for force manual merge 5.0 -> wl1012: Delete me
diff --git a/mysql-test/t/rpl_log.test b/mysql-test/extra/rpl_tests/rpl_log.test
index 1f71d2981c5..252c1fcca41 100644
--- a/mysql-test/t/rpl_log.test
+++ b/mysql-test/extra/rpl_tests/rpl_log.test
@@ -1,4 +1,5 @@
-source include/master-slave.inc;
+# Requires statement logging
+-- source include/master-slave.inc
# Clean up old slave's binlogs.
# The slave is started with --log-slave-updates
@@ -37,10 +38,14 @@ load data infile '../../std_data/words.dat' into table t1 ignore 1 lines;
select count(*) from t1;
drop table t1;
--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
show binlog events;
-show binlog events from 98 limit 1;
-show binlog events from 98 limit 2;
-show binlog events from 98 limit 2,1;
+--replace_column 2 # 5 #
+show binlog events from 102 limit 1;
+--replace_column 2 # 5 #
+show binlog events from 102 limit 2;
+--replace_column 2 # 5 #
+show binlog events from 102 limit 2,1;
flush logs;
# We need an extra update before doing save_master_pos.
@@ -81,8 +86,10 @@ create table t1 (n int);
insert into t1 values (1);
drop table t1;
--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
show binlog events;
--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
show binlog events in 'master-bin.000002';
show binary logs;
save_master_pos;
@@ -91,11 +98,13 @@ start slave;
sync_with_master;
show binary logs;
--replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION
+--replace_column 2 # 5 #
show binlog events in 'slave-bin.000001' from 4;
--replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION
+--replace_column 2 # 5 #
show binlog events in 'slave-bin.000002' from 4;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
# Need to recode the following
@@ -108,6 +117,3 @@ show slave status;
--error 1220
show binlog events in 'slave-bin.000005' from 4;
-
-# End of 4.1 tests
-# Adding comment for force manual merge 5.0 -> wl1012: Delete me
diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/extra/rpl_tests/rpl_max_relay_size.test
index 9b6b06e0b14..14223392224 100644
--- a/mysql-test/t/rpl_max_relay_size.test
+++ b/mysql-test/extra/rpl_tests/rpl_max_relay_size.test
@@ -3,11 +3,14 @@
# for relay logs too).
# Test of manual relay log rotation with FLUSH LOGS.
-source include/master-slave.inc;
+# Requires statement logging
+-- source include/master-slave.inc
+
connection slave;
stop slave;
connection master;
# Generate a big enough master's binlog to cause relay log rotations
+
create table t1 (a int);
let $1=800;
disable_query_log;
@@ -29,7 +32,7 @@ select @@global.max_relay_log_size;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
stop slave;
reset slave;
@@ -38,7 +41,7 @@ select @@global.max_relay_log_size;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
stop slave;
reset slave;
@@ -47,7 +50,7 @@ select @@global.max_relay_log_size;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
# Tests below are mainly to ensure that we have not coded with wrong assumptions
@@ -58,7 +61,7 @@ reset slave;
# (to make sure it does not crash).
flush logs;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
reset slave;
@@ -74,7 +77,7 @@ save_master_pos;
connection slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
# one more rotation, to be sure Relay_Log_Space is correctly updated
flush logs;
@@ -84,13 +87,11 @@ save_master_pos;
connection slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
connection master;
# test that the absence of relay logs does not make a master crash
flush logs;
+-- replace_column 3 <Binlog_Ignore_DB>
show master status;
-
-# End of 4.1 tests
-#
diff --git a/mysql-test/t/rpl_multi_query.test b/mysql-test/extra/rpl_tests/rpl_multi_query.test
index b4cd88f756e..a0062bd04bf 100644
--- a/mysql-test/t/rpl_multi_query.test
+++ b/mysql-test/extra/rpl_tests/rpl_multi_query.test
@@ -3,10 +3,10 @@
# CLIENT_MULTI_STATEMENTS) will be binlogged ONE-query-per-event (not
# one binlog event containing all queries)
+
# PS doesn't support multi-statements
--disable_ps_protocol
-
-source include/master-slave.inc;
+-- source include/master-slave.inc
--disable_warnings
drop database if exists mysqltest;
--enable_warnings
@@ -24,9 +24,6 @@ sync_slave_with_master;
select * from mysqltest.t1;
connection master;
--replace_column 2 # 5 #
-show binlog events from 98;
+show binlog events from 102;
drop database mysqltest;
sync_slave_with_master;
-
-# End of 4.1 tests
-#
diff --git a/mysql-test/extra/rpl_tests/rpl_multi_update.test b/mysql-test/extra/rpl_tests/rpl_multi_update.test
new file mode 100644
index 00000000000..121ae18daa8
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_multi_update.test
@@ -0,0 +1,30 @@
+source include/master-slave.inc;
+
+eval CREATE TABLE t1 (
+ a int unsigned not null auto_increment primary key,
+ b int unsigned
+) ENGINE=$engine_type;
+
+eval CREATE TABLE t2 (
+ a int unsigned not null auto_increment primary key,
+ b int unsigned
+) ENGINE=$engine_type;
+
+INSERT INTO t1 VALUES (NULL, 0);
+INSERT INTO t1 SELECT NULL, 0 FROM t1;
+
+INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
+
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+UPDATE t1, t2 SET t1.b = t2.b WHERE t1.a = t2.a;
+save_master_pos;
+connection slave;
+sync_with_master;
+
+# End of 4.1 tests
+
+connection master;
+drop table t1, t2;
+sync_slave_with_master;
diff --git a/mysql-test/extra/rpl_tests/rpl_multi_update2.test b/mysql-test/extra/rpl_tests/rpl_multi_update2.test
new file mode 100644
index 00000000000..0adf0053425
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_multi_update2.test
@@ -0,0 +1,62 @@
+# Let's verify that multi-update is not always skipped by slave if
+# some replicate-* rules exist.
+# (BUG#7011)
+
+source include/master-slave.inc;
+
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+
+eval CREATE TABLE t1 (
+ a int unsigned not null auto_increment primary key,
+ b int unsigned
+) ENGINE=$engine_type;
+
+eval CREATE TABLE t2 (
+ a int unsigned not null auto_increment primary key,
+ b int unsigned
+) ENGINE=$engine_type;
+
+INSERT INTO t1 VALUES (NULL, 0);
+INSERT INTO t1 SELECT NULL, 0 FROM t1;
+
+INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
+
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+UPDATE t1, t2 SET t1.b = (t2.b+4) WHERE t1.a = t2.a;
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+connection master;
+drop table t1,t2;
+sync_slave_with_master;
+
+#
+# BUG#13236 multi-update with subquery & --replicate-ignore-table
+#
+reset master;
+
+connection master;
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES (0);
+UPDATE t1, (SELECT 3 as b) AS x SET t1.a = x.b;
+select * from t1;
+sync_slave_with_master;
+
+connection slave;
+select * from t1;
+
+connection master;
+drop table t1;
+sync_slave_with_master;
+
+# End of 4.1 tests
diff --git a/mysql-test/extra/rpl_tests/rpl_multi_update3.test b/mysql-test/extra/rpl_tests/rpl_multi_update3.test
new file mode 100644
index 00000000000..90cc81cfd58
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_multi_update3.test
@@ -0,0 +1,220 @@
+-- source include/master-slave.inc
+
+##############################################################################
+#
+# Let's verify that multi-update with a subselect does not cause the slave to crash
+# (BUG#10442)
+#
+--disable_query_log
+SELECT '-------- Test for BUG#9361 --------' as "";
+--enable_query_log
+
+eval CREATE TABLE t1 (
+ a int unsigned not null auto_increment primary key,
+ b int unsigned
+) ENGINE=$engine_type;
+
+eval CREATE TABLE t2 (
+ a int unsigned not null auto_increment primary key,
+ b int unsigned
+) ENGINE=$engine_type;
+
+INSERT INTO t1 VALUES (NULL, 0);
+INSERT INTO t1 SELECT NULL, 0 FROM t1;
+
+INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
+
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+UPDATE t2, (SELECT a FROM t1) AS t SET t2.b = t.a+5 ;
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+sync_slave_with_master;
+connection slave;
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+connection master;
+drop table t1,t2;
+
+##############################################################################
+#
+# Test for BUG#9361:
+# Subselects should work inside multi-updates
+#
+--disable_query_log
+SELECT '-------- Test 1 for BUG#9361 --------' as "";
+--enable_query_log
+
+connection master;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+CREATE TABLE t1 (
+ a1 char(30),
+ a2 int,
+ a3 int,
+ a4 char(30),
+ a5 char(30)
+);
+
+CREATE TABLE t2 (
+ b1 int,
+ b2 char(30)
+);
+
+# Insert one row per table
+INSERT INTO t1 VALUES ('Yes', 1, NULL, 'foo', 'bar');
+INSERT INTO t2 VALUES (1, 'baz');
+
+# This should update the row in t1
+UPDATE t1 a, t2
+ SET a.a1 = 'No'
+ WHERE a.a2 =
+ (SELECT b1
+ FROM t2
+ WHERE b2 = 'baz')
+ AND a.a3 IS NULL
+ AND a.a4 = 'foo'
+ AND a.a5 = 'bar';
+
+sync_slave_with_master;
+connection slave;
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+connection master;
+DROP TABLE t1, t2;
+
+##############################################################################
+#
+# Second test for BUG#9361
+#
+
+--disable_query_log
+SELECT '-------- Test 2 for BUG#9361 --------' as "";
+--enable_query_log
+
+connection master;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+--enable_warnings
+
+CREATE TABLE t1 (
+ i INT,
+ j INT,
+ x INT,
+ y INT,
+ z INT
+);
+
+CREATE TABLE t2 (
+ i INT,
+ k INT,
+ x INT,
+ y INT,
+ z INT
+);
+
+CREATE TABLE t3 (
+ j INT,
+ k INT,
+ x INT,
+ y INT,
+ z INT
+);
+
+INSERT INTO t1 VALUES ( 1, 2,13,14,15);
+INSERT INTO t2 VALUES ( 1, 3,23,24,25);
+INSERT INTO t3 VALUES ( 2, 3, 1,34,35), ( 2, 3, 1,34,36);
+
+UPDATE t1 AS a
+INNER JOIN t2 AS b
+ ON a.i = b.i
+INNER JOIN t3 AS c
+ ON a.j = c.j AND b.k = c.k
+SET a.x = b.x,
+ a.y = b.y,
+ a.z = (
+ SELECT sum(z)
+ FROM t3
+ WHERE y = 34
+ )
+WHERE b.x = 23;
+
+sync_slave_with_master;
+connection slave;
+
+SELECT * FROM t1;
+
+connection master;
+DROP TABLE t1, t2, t3;
+
+##############################################################################
+#
+# BUG#12618
+#
+# TEST: Replication of a statement containing a join in a multi-update.
+
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+
+CREATE TABLE t1 (
+ idp int(11) NOT NULL default '0',
+ idpro int(11) default NULL,
+ price decimal(19,4) default NULL,
+ PRIMARY KEY (idp)
+);
+
+CREATE TABLE t2 (
+ idpro int(11) NOT NULL default '0',
+ price decimal(19,4) default NULL,
+ nbprice int(11) default NULL,
+ PRIMARY KEY (idpro)
+);
+
+INSERT INTO t1 VALUES
+ (1,1,'3.0000'),
+ (2,2,'1.0000'),
+ (3,1,'1.0000'),
+ (4,1,'4.0000'),
+ (5,3,'2.0000'),
+ (6,2,'4.0000');
+
+INSERT INTO t2 VALUES
+ (1,'0.0000',0),
+ (2,'0.0000',0),
+ (3,'0.0000',0);
+
+# This update sets t2 to the minimal prices for each product
+update
+ t2
+ join
+ ( select idpro, min(price) as min_price, count(*) as nbr_price
+ from t1
+ where idpro>0 and price>0
+ group by idpro
+ ) as table_price
+on t2.idpro = table_price.idpro
+set t2.price = table_price.min_price,
+ t2.nbprice = table_price.nbr_price;
+
+select "-- MASTER AFTER JOIN --" as "";
+select * from t1;
+select * from t2;
+
+sync_slave_with_master;
+
+select "-- SLAVE AFTER JOIN --" as "";
+select * from t1;
+select * from t2;
+
+# End of 4.1 tests
diff --git a/mysql-test/extra/rpl_tests/rpl_relayrotate.test b/mysql-test/extra/rpl_tests/rpl_relayrotate.test
new file mode 100644
index 00000000000..dc91f9e7fff
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_relayrotate.test
@@ -0,0 +1,75 @@
+# When the relay log gets rotated while the I/O thread
+# is reading a transaction, the transaction spans on two or more
+# relay logs. If STOP SLAVE occurs while the SQL thread is
+# executing a part of the transaction in the non-first relay logs,
+# we test if START SLAVE will resume in the beginning of the
+# transaction (i.e., step back to the first relay log)
+
+# The slave is started with max_binlog_size=16384 bytes,
+# to force many rotations (approximately 30 rotations)
+
+-- source include/master-slave.inc
+
+connection slave;
+stop slave;
+connection master;
+--disable_warnings
+eval create table t1 (a int) engine=$engine_type;
+--enable_warnings
+let $1=8000;
+disable_query_log;
+begin;
+while ($1)
+{
+# eval means expand $ expressions
+ eval insert into t1 values( $1 );
+ dec $1;
+}
+commit;
+# This will generate a 500kB master's binlog,
+# which corresponds to 30 slave's relay logs.
+enable_query_log;
+save_master_pos;
+connection slave;
+reset slave;
+start slave;
+# We wait 1 sec for the SQL thread to be somewhere in
+# the middle of the transaction, hopefully not in
+# the first relay log, and hopefully before the COMMIT.
+# Usually it stops when the SQL thread is around the 15th relay log.
+# We cannot use MASTER_POS_WAIT() as master's position
+# increases only when the slave executes the COMMIT.
+# Note that except when using Valgrind, 1 second is enough for the I/O slave
+# thread to fetch the whole master's binlog.
+sleep 1;
+stop slave;
+# We suppose the SQL thread stopped before COMMIT.
+# If so the transaction was rolled back
+# and the table is now empty.
+# Now restart
+start slave;
+# And see if the table contains '8000'
+# which proves that the transaction restarted at
+# the right place.
+# We must wait for the transaction to commit before
+# reading, with a sync_with_master.
+sync_with_master;
+select max(a) from t1;
+connection master;
+
+# The following DROP is a very important cleaning task:
+# imagine the next test is run with --skip-innodb: it will do
+# DROP TABLE IF EXISTS t1; but this will delete the frm and leave
+# some data in the InnoDB datafile (because at that time mysqld
+# does not know about InnoDB : --skip-innodb). So if later in the
+# test suite a test wants to create an InnoDB table called t1, it
+# will fail with
+# InnoDB: Error: table t1 already exists in InnoDB internal
+# InnoDB: data dictionary. Have you deleted the .frm file etc
+drop table t1;
+# wait until this drop is executed on slave
+save_master_pos;
+connection slave;
+sync_with_master;
+
+# End of 4.1 tests
diff --git a/mysql-test/t/rpl_reset_slave.test b/mysql-test/extra/rpl_tests/rpl_reset_slave.test
index 00b1cf68294..374b2620a34 100644
--- a/mysql-test/t/rpl_reset_slave.test
+++ b/mysql-test/extra/rpl_tests/rpl_reset_slave.test
@@ -1,3 +1,6 @@
+# TBF - difference in row level logging
+# Temp tables are not replicated in rbr, but it is still good to hit rbr with everthing
+
# See SHOW SLAVE STATUS displays well after RESET SLAVE (it should display the
# --master-* options from mysqld, as this is what is going to be used next time
# slave threads will be started). In bug 985, it displayed old values (of before
@@ -5,30 +8,30 @@
# See if slave crashes when doing a CREATE TEMPORARY TABLE twice, separated by
# RESET SLAVE.
-source include/master-slave.inc;
+-- source include/master-slave.inc
connection master;
save_master_pos;
connection slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
stop slave;
change master to master_user='test';
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
reset slave;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
start slave;
sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
# test of crash with temp tables & RESET SLAVE
@@ -46,6 +49,3 @@ reset slave;
start slave;
sync_with_master;
show status like 'slave_open_temp_tables';
-
-# End of 4.1 tests
-#
diff --git a/mysql-test/extra/rpl_tests/rpl_row_001.test b/mysql-test/extra/rpl_tests/rpl_row_001.test
new file mode 100644
index 00000000000..2efefb3cd63
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_001.test
@@ -0,0 +1,84 @@
+-- source include/master-slave.inc
+-- source include/have_binlog_format_row.inc
+
+CREATE TABLE t1 (word CHAR(20) NOT NULL);
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+eval LOAD DATA LOCAL INFILE '$MYSQL_TEST_DIR/std_data/words.dat' INTO TABLE t1;
+SELECT * FROM t1 LIMIT 10;
+
+#
+# Test slave with wrong password
+#
+save_master_pos;
+connection slave;
+sync_with_master;
+STOP SLAVE;
+connection master;
+SET PASSWORD FOR root@"localhost" = PASSWORD('foo');
+connection slave;
+START SLAVE;
+connection master;
+#
+# Give slave time to do at last one failed connect retry
+# This one must be short so that the slave will not stop retrying
+real_sleep 2;
+SET PASSWORD FOR root@"localhost" = PASSWORD('');
+# Give slave time to connect (will retry every second)
+sleep 2;
+
+CREATE TABLE t3(n INT);
+INSERT INTO t3 VALUES(1),(2);
+sync_slave_with_master;
+SELECT * FROM t3;
+SELECT SUM(LENGTH(word)) FROM t1;
+connection master;
+DROP TABLE t1,t3;
+save_master_pos;
+connection slave;
+sync_with_master;
+
+# Test if the slave SQL thread can be more than 16K behind the slave
+# I/O thread (> IO_SIZE)
+
+connection master;
+# we'll use table-level locking to delay slave SQL thread
+eval CREATE TABLE t1 (n INT) ENGINE=$engine_type;
+sync_slave_with_master;
+connection master;
+RESET MASTER;
+connection slave;
+STOP SLAVE;
+RESET SLAVE;
+
+connection master;
+let $1=5000;
+# Generate 16K of relay log
+disable_query_log;
+while ($1)
+{
+ eval INSERT INTO t1 VALUES($1);
+ dec $1;
+}
+enable_query_log;
+SELECT COUNT(*) FROM t1;
+save_master_pos;
+
+# Try to cause a large relay log lag on the slave by locking t1
+connection slave;
+LOCK TABLES t1 READ;
+START SLAVE;
+UNLOCK TABLES;
+sync_with_master;
+SELECT COUNT(*) FROM t1;
+
+connection master;
+DROP TABLE t1;
+CREATE TABLE t1 (n INT);
+INSERT INTO t1 VALUES(3456);
+sync_slave_with_master;
+SELECT n FROM t1;
+
+connection master;
+DROP TABLE t1;
+sync_slave_with_master;
diff --git a/mysql-test/extra/rpl_tests/rpl_row_EE_err.test b/mysql-test/extra/rpl_tests/rpl_row_EE_err.test
new file mode 100644
index 00000000000..7312e4e0fb5
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_EE_err.test
@@ -0,0 +1,40 @@
+# The test is not relevant when testing replication of error codes for
+# statements that are not replicated. The test below could be changed
+# to rely on the replication of error codes for statements that are not
+# replicated row-based.
+
+# This test does not work the same for row based as the insert in the second part is not replicated as a call but rather as a table map and row right. Have added a slave stop so the test will complete, other wise it just continues to loop waiting for a slave stop that never comes. 8/22/2005 JBM
+
+-- source include/have_binlog_format_row.inc
+
+# See if an EE_ error in one event of the master's binlog stops replication
+# (it should not: in this configuration the EE_ error is probably not
+# critical). Example: you do a DROP TABLE on a table which has no MYI file
+# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and
+# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986).
+
+-- source include/master-slave.inc
+
+eval create table t1 (a int) engine=$engine_type;
+flush tables;
+system rm ./var/master-data/test/t1.MYI ;
+drop table if exists t1;
+save_master_pos;
+connection slave;
+sync_with_master;
+
+# Now a real error.
+
+connection master;
+eval create table t1 (a int, unique(a)) engine=$engine_type;
+set sql_log_bin=0;
+insert into t1 values(2);
+set sql_log_bin=1;
+save_master_pos;
+--error 1062
+insert into t1 values(1),(2);
+drop table t1;
+save_master_pos;
+connection slave;
+stop slave;
+wait_for_slave_to_stop;
diff --git a/mysql-test/extra/rpl_tests/rpl_row_UUID.test b/mysql-test/extra/rpl_tests/rpl_row_UUID.test
new file mode 100644
index 00000000000..6bad362057a
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_UUID.test
@@ -0,0 +1,80 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/18/2005 #
+#############################################################################
+# TEST: To test the UUID() in rbr #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+# Begin clean up test section
+connection master;
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
+--enable_warnings
+
+# Section 1 test
+
+eval CREATE TABLE test.t1 (a INT, blob_column LONGBLOB, vchar_column VARCHAR(100), PRIMARY KEY(a)) engine=$engine_type;
+INSERT INTO test.t1 VALUES(1,UUID(),UUID());
+delimiter |;
+create procedure test.p1()
+begin
+ INSERT INTO test.t1 VALUES(2,UUID(),UUID());
+ INSERT INTO test.t1 VALUES(3,UUID(),UUID());
+end|
+delimiter ;|
+
+CALL test.p1();
+
+# Now the same thing with a function
+
+delimiter |;
+create function test.fn1(x int)
+ returns int
+begin
+ insert into t1 values (4+x,UUID(),UUID());
+ insert into t1 values (5+x,UUID(),UUID());
+ return 0;
+end|
+
+delimiter ;|
+# test both in SELECT and in INSERT
+select fn1(0);
+create table t2 (a int);
+insert into t2 values(fn1(2));
+
+sync_slave_with_master;
+SHOW CREATE TABLE test.t1;
+
+# Dump the databases and so we can see if they match
+# Another method would be to use SELECT INTO OUTFILE on master,
+# then LOAD DATA INFILE in slave, and use a query to compare.
+# This would have the advantage that it would not assume
+# the system has a 'diff'
+--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/rpl_row_UUID_master.sql
+--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/rpl_row_UUID_slave.sql
+
+connection master;
+# Let's cleanup
+
+DROP PROCEDURE test.p1;
+DROP TABLE test.t1;
+
+# Let's compare. Note: If they match test will pass, if they do not match
+# the test will show that the diff statement failed and not reject file
+# will be created. You will need to go to the mysql-test dir and diff
+# the files your self to see what is not matching :-)
+
+--exec diff ./var/tmp/rpl_row_UUID_master.sql ./var/tmp/rpl_row_UUID_slave.sql;
+
+# Cleanup dump files.
+# Long-term "system rm" is not portable; we could live without
+# this cleanup as no other test will use these files and they'll
+# be removed at next testsuite run.
+
+# End of 5.0 test case
diff --git a/mysql-test/extra/rpl_tests/rpl_row_charset.test b/mysql-test/extra/rpl_tests/rpl_row_charset.test
new file mode 100644
index 00000000000..c2a7cda4333
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_charset.test
@@ -0,0 +1,182 @@
+# Replication of character sets.
+# This test will fail if the server/client does not support enough charsets.
+
+# Requires statement logging
+-- source include/have_binlog_format_row.inc
+
+-- source include/master-slave.inc
+--disable_warnings
+set timestamp=1000000000;
+drop database if exists mysqltest2;
+drop database if exists mysqltest3;
+--enable_warnings
+
+create database mysqltest2 character set latin2;
+set @@character_set_server=latin5;
+create database mysqltest3;
+--disable_query_log
+select "--- --master--" as "";
+--enable_query_log
+show create database mysqltest2;
+show create database mysqltest3;
+sync_slave_with_master;
+--disable_query_log
+select "--- --slave--" as "";
+--enable_query_log
+show create database mysqltest2;
+show create database mysqltest3;
+
+connection master;
+set @@collation_server=armscii8_bin;
+drop database mysqltest3;
+create database mysqltest3;
+--disable_query_log
+select "--- --master--" as "";
+--enable_query_log
+show create database mysqltest3;
+sync_slave_with_master;
+--disable_query_log
+select "--- --slave--" as "";
+--enable_query_log
+show create database mysqltest3;
+
+connection master;
+use mysqltest2;
+create table t1 (a int auto_increment primary key, b varchar(100));
+set character_set_client=cp850, collation_connection=latin2_croatian_ci;
+insert into t1 (b) values(@@character_set_server);
+insert into t1 (b) values(@@collation_server);
+# character_set_database and collation_database are not tested as they
+# needn't be replicated (Bar said in Jan 2005).
+insert into t1 (b) values(@@character_set_client);
+# collation_client does not exist
+insert into t1 (b) values(@@character_set_connection);
+insert into t1 (b) values(@@collation_connection);
+--disable_query_log
+select "--- --master--" as "";
+--enable_query_log
+select * from t1 order by a;
+sync_slave_with_master;
+--disable_query_log
+select "--- --slave--" as "";
+--enable_query_log
+select * from mysqltest2.t1 order by a;
+
+select "--- --muller--" as "";
+connection master;
+set character_set_client=latin1, collation_connection=latin1_german1_ci;
+truncate table t1;
+insert into t1 (b) values(@@collation_connection);
+insert into t1 (b) values(LEAST("Müller","Muffler"));
+set collation_connection=latin1_german2_ci;
+insert into t1 (b) values(@@collation_connection);
+insert into t1 (b) values(LEAST("Müller","Muffler"));
+--disable_query_log
+select "--- --master--" as "";
+--enable_query_log
+select * from t1 order by a;
+sync_slave_with_master;
+--disable_query_log
+select "--- --slave--" as "";
+--enable_query_log
+select * from mysqltest2.t1 order by a;
+
+# Presently charset info is not logged with LOAD DATA but it will
+# change in Jan 2005 when Dmitri pushes his new LOAD DATA,
+# before 5.0.3 goes out. When done, LOAD DATA INFILE should be tested
+# here.
+
+# See if user var is prefixed with collation in binlog and replicated well.
+# Note: replication of user variables is broken as far as derivation is
+# concerned. That's because when we store a user variable in the binlog,
+# we lose its derivation. So later on the slave, it's impossible to
+# know if the collation was explicit or not, so we use DERIVATION_NONE,
+# which provokes error messages (like 'Illegal mix of collation') when
+# we replay the master's INSERT/etc statements.
+
+
+select "--- --INSERT--" as "";
+connection master;
+set @a= _cp850 'Müller' collate cp850_general_ci;
+truncate table t1;
+insert into t1 (b) values(collation(@a));
+--disable_query_log
+select "--- --master--" as "";
+--enable_query_log
+select * from t1 order by a;
+sync_slave_with_master;
+--disable_query_log
+select "--- --slave--" as "";
+--enable_query_log
+select * from mysqltest2.t1 order by a;
+
+connection master;
+drop database mysqltest2;
+drop database mysqltest3;
+--replace_column 2 # 5 #
+show binlog events from 102;
+sync_slave_with_master;
+
+# Check that we can change global.collation_server (since 5.0.3)
+
+select "--- --global--" as "";
+set global character_set_server=latin2;
+set global character_set_server=latin1; # back
+connection master;
+set global character_set_server=latin2;
+set global character_set_server=latin1; # back
+
+# Check that SET ONE_SHOT is really one shot
+
+select "--- --oneshot--" as "";
+set one_shot @@character_set_server=latin5;
+set @@max_join_size=1000;
+select @@character_set_server;
+select @@character_set_server;
+set @@character_set_server=latin5;
+select @@character_set_server;
+select @@character_set_server;
+
+# ONE_SHOT on not charset/collation stuff is not allowed
+-- error 1382
+set one_shot max_join_size=10;
+
+# Test of wrong character set numbers;
+error 1115;
+set character_set_client=9999999;
+error 1273;
+set collation_server=9999998;
+
+# This one was contributed by Sergey Petrunia (BUG#3943)
+
+select "--- --3943--" as "";
+use test;
+CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255));
+SET CHARACTER_SET_CLIENT=koi8r,
+ CHARACTER_SET_CONNECTION=cp1251,
+ CHARACTER_SET_RESULTS=koi8r;
+INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ');
+select hex(c1), hex(c2) from t1;
+sync_slave_with_master;
+select hex(c1), hex(c2) from t1;
+
+connection master;
+# Let's have a look at generated SETs.
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+#--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
+drop table t1;
+sync_slave_with_master;
+
+#
+# BUG#6676: Derivation of variables must be correct on slave
+#
+select "--- --6676--" as "";
+connection master;
+eval create table `t1` (
+ `pk` varchar(10) not null default '',
+ primary key (`pk`)
+) engine=$engine_type default charset=latin1;
+set @p=_latin1 'test';
+update t1 set pk='test' where pk=@p;
+drop table t1;
+sync_slave_with_master;
diff --git a/mysql-test/extra/rpl_tests/rpl_row_delayed_ins.test b/mysql-test/extra/rpl_tests/rpl_row_delayed_ins.test
new file mode 100644
index 00000000000..fc899f1fa5f
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_delayed_ins.test
@@ -0,0 +1,22 @@
+# See if INSERT DELAYED gets replicated
+# Only in row-based, as we do SHOW BINLOG EVENTS
+
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+connection master;
+let $VERSION=`select version()`;
+eval create table t1(a int not null primary key) engine=$engine_type;
+insert delayed into t1 values (1),(2),(3);
+flush tables;
+select * from t1;
+sync_slave_with_master;
+
+connection master;
+--replace_result $VERSION VERSION
+show binlog events;
+sync_slave_with_master;
+select * from t1;
+connection master;
+drop table t1;
+sync_slave_with_master;
diff --git a/mysql-test/extra/rpl_tests/rpl_row_func003.test b/mysql-test/extra/rpl_tests/rpl_row_func003.test
new file mode 100644
index 00000000000..f07c8a65265
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_func003.test
@@ -0,0 +1,96 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/15/2005 #
+# Update: 08/29/2005 Comment out sleep. Only needed for debugging #
+#############################################################################
+# Note: Many lines are commented out in this test case. These were used for #
+# creating the test case and debugging and are being left for #
+# debugging, but they can not be used for the regular testing as the #
+# Time changes and is not deteministic, so instead we dump both the #
+# master and slave and diff the dumps. If the dumps differ then the #
+# test case will fail. To run during diff failuers, comment out the #
+# diff. #
+# Test: Tests MySQL stored function using RAND() and a flow control. The #
+# test inserts rows into a givin table with the function used in #
+# the insert statement. Depending on the RAND() value returned #
+# inside the function one set of text is returned. In addition, #
+# it uses a transaction to see the effect a rollback has on master #
+# Vs slave. #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP FUNCTION IF EXISTS test.f1;
+DROP TABLE IF EXISTS test.t1;
+
+--enable_warnings
+
+
+eval CREATE TABLE test.t1 (a INT NOT NULL AUTO_INCREMENT, c CHAR(16),PRIMARY KEY(a))ENGINE=$engine_type;
+
+delimiter |;
+create function test.f1() RETURNS CHAR(16)
+BEGIN
+ DECLARE tmp CHAR(16);
+ DECLARE var_name FLOAT;
+ SET var_name = RAND();
+ IF var_name > .6
+ THEN SET tmp = 'Texas';
+ ELSE SET tmp = 'MySQL';
+ END IF;
+RETURN tmp;
+END|
+delimiter ;|
+
+INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1());
+sleep 6;
+INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1());
+sleep 6;
+
+#Select in this test are used for debugging
+#select * from test.t1;
+#connection slave;
+#select * from test.t1;
+
+connection master;
+SET AUTOCOMMIT=0;
+START TRANSACTION;
+INSERT INTO test.t1 VALUES (null,test.f1());
+ROLLBACK;
+SET AUTOCOMMIT=1;
+#select * from test.t1;
+#sleep 6;
+
+#connection slave;
+#select * from test.t1;
+
+#connection master;
+
+#used for debugging
+#show binlog events;
+
+# time to dump the databases and so we can see if they match
+
+--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/func003_master.sql
+--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/func003_slave.sql
+
+# First lets cleanupi
+DROP FUNCTION test.f1;
+DROP TABLE test.t1;
+
+
+# the test will show that the diff statement failed and no reject file
+# will be created. You will need to go to the mysql-test dir and diff
+# the files yourself to see what is not matching :-) File are located
+# in mysql-test/var/tmp
+
+exec diff ./var/tmp/func003_master.sql ./var/tmp/func003_slave.sql;
+
+
+# End of 5.0 test case
diff --git a/mysql-test/extra/rpl_tests/rpl_row_multi_update3.test b/mysql-test/extra/rpl_tests/rpl_row_multi_update3.test
new file mode 100644
index 00000000000..cd771d04229
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_multi_update3.test
@@ -0,0 +1,159 @@
+-- source include/master-slave.inc
+
+##############################################################################
+#
+# Let's verify that multi-update with a subselect does not cause the slave to crash
+# (BUG#10442)
+#
+--disable_query_log
+SELECT '-------- Test for BUG#9361 --------' as "";
+--enable_query_log
+
+eval CREATE TABLE t1 (
+ a int unsigned not null auto_increment primary key,
+ b int unsigned
+) ENGINE=$engine_type;
+
+eval CREATE TABLE t2 (
+ a int unsigned not null auto_increment primary key,
+ b int unsigned
+) ENGINE=$engine_type;
+
+INSERT INTO t1 VALUES (NULL, 0);
+INSERT INTO t1 SELECT NULL, 0 FROM t1;
+
+INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
+
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+UPDATE t2, (SELECT a FROM t1) AS t SET t2.b = t.a+5 ;
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+sync_slave_with_master;
+connection slave;
+SELECT * FROM t1 ORDER BY a;
+SELECT * FROM t2 ORDER BY a;
+
+connection master;
+drop table t1,t2;
+
+##############################################################################
+#
+# Test for BUG#9361:
+# Subselects should work inside multi-updates
+#
+--disable_query_log
+SELECT '-------- Test 1 for BUG#9361 --------' as "";
+--enable_query_log
+
+connection master;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+CREATE TABLE t1 (
+ a1 char(30),
+ a2 int,
+ a3 int,
+ a4 char(30),
+ a5 char(30)
+);
+
+CREATE TABLE t2 (
+ b1 int,
+ b2 char(30)
+);
+
+# Insert one row per table
+INSERT INTO t1 VALUES ('Yes', 1, NULL, 'foo', 'bar');
+INSERT INTO t2 VALUES (1, 'baz');
+
+# This should update the row in t1
+UPDATE t1 a, t2
+ SET a.a1 = 'No'
+ WHERE a.a2 =
+ (SELECT b1
+ FROM t2
+ WHERE b2 = 'baz')
+ AND a.a3 IS NULL
+ AND a.a4 = 'foo'
+ AND a.a5 = 'bar';
+
+sync_slave_with_master;
+connection slave;
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+connection master;
+DROP TABLE t1, t2;
+
+##############################################################################
+#
+# Second test for BUG#9361
+#
+
+--disable_query_log
+SELECT '-------- Test 2 for BUG#9361 --------' as "";
+--enable_query_log
+
+connection master;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+--enable_warnings
+
+CREATE TABLE t1 (
+ i INT,
+ j INT,
+ x INT,
+ y INT,
+ z INT
+);
+
+CREATE TABLE t2 (
+ i INT,
+ k INT,
+ x INT,
+ y INT,
+ z INT
+);
+
+CREATE TABLE t3 (
+ j INT,
+ k INT,
+ x INT,
+ y INT,
+ z INT
+);
+
+INSERT INTO t1 VALUES ( 1, 2,13,14,15);
+INSERT INTO t2 VALUES ( 1, 3,23,24,25);
+INSERT INTO t3 VALUES ( 2, 3, 1,34,35), ( 2, 3, 1,34,36);
+
+UPDATE t1 AS a
+INNER JOIN t2 AS b
+ ON a.i = b.i
+INNER JOIN t3 AS c
+ ON a.j = c.j AND b.k = c.k
+SET a.x = b.x,
+ a.y = b.y,
+ a.z = (
+ SELECT sum(z)
+ FROM t3
+ WHERE y = 34
+ )
+WHERE b.x = 23;
+
+sync_slave_with_master;
+connection slave;
+
+SELECT * FROM t1;
+
+connection master;
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/extra/rpl_tests/rpl_row_sp002.test b/mysql-test/extra/rpl_tests/rpl_row_sp002.test
new file mode 100644
index 00000000000..9d056626cf2
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_sp002.test
@@ -0,0 +1,239 @@
+#############################################################################
+# This test is being created to test out the non deterministic items with #
+# row based replication. #
+# Original Author: JBM #
+# Original Date: Aug/09/2005 #
+# Updated: Aug/29/2005 #
+#############################################################################
+# Test: Contains two stored procedures test one that insert data into tables#
+# and use the LAST_INSERTED_ID() on tables with FOREIGN KEY(a) #
+# REFERENCES ON DELETE CASCADE. This test also has a delete sp that #
+# should cause a delete cascade. #
+# The second test has a sp that will either insert rows or delete from#
+# the table depending on the CASE outcome. The test uses this SP in a#
+# transaction first rolling back and then commiting, #
+#############################################################################
+# Mod Date: 08/22/2005 #
+# TEST: Added test to include UPDATE CASCADE on table with FK per Trudy #
+#############################################################################
+
+
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP TABLE IF EXISTS test.t3;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+--enable_warnings
+# End of cleanup
+
+# Begin test section 1
+
+eval CREATE TABLE test.t1 (a INT AUTO_INCREMENT KEY, t CHAR(6)) ENGINE=$engine_type;
+eval CREATE TABLE test.t2 (a INT AUTO_INCREMENT KEY, f INT, FOREIGN KEY(a) REFERENCES test.t1(a) ON DELETE CASCADE) ENGINE=$engine_type;
+
+delimiter |;
+create procedure test.p1(IN i CHAR(6))
+begin
+ INSERT INTO test.t1 (t) VALUES (i);
+ INSERT INTO test.t2 VALUES (NULL,LAST_INSERT_ID());
+end|
+create procedure test.p2(IN i INT)
+begin
+ DELETE FROM test.t1 where a < i;
+end|
+delimiter ;|
+
+let $message=< -- test 1 call p1 -- >;
+--source include/show_msg.inc
+SET FOREIGN_KEY_CHECKS=1;
+call test.p1('texas');
+call test.p1('Live');
+call test.p1('next');
+call test.p1('to');
+call test.p1('OK');
+call test.p1('MySQL');
+
+let $message=< -- test 1 select master after p1 -- >;
+--source include/show_msg.inc
+
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+
+let $message=< -- test 1 select slave after p1 -- >;
+--source include/show_msg.inc
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+
+let $message=< -- test 1 call p2 & select master -- >;
+--source include/show_msg.inc
+connection master;
+call test.p2(4);
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+
+let $message=< -- test 1 select slave after p2 -- >;
+--source include/show_msg.inc
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+
+connection master;
+#show binlog events;
+let $message=< -- End test 1 Begin test 2 -- >;
+--source include/show_msg.inc
+# End test 1 Begin test 2
+
+--disable_warnings
+SET FOREIGN_KEY_CHECKS=0;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+--enable_warnings
+# End of cleanup
+
+eval CREATE TABLE test.t1 (a INT, t CHAR(6), PRIMARY KEY(a)) ENGINE=$engine_type;
+eval CREATE TABLE test.t2 (a INT, f INT, FOREIGN KEY(a) REFERENCES test.t1(a) ON UPDATE CASCADE, PRIMARY KEY(a)) ENGINE=$engine_type;
+
+delimiter |;
+CREATE PROCEDURE test.p1(IN nm INT, IN ch CHAR(6))
+BEGIN
+ INSERT INTO test.t1 (a,t) VALUES (nm, ch);
+ INSERT INTO test.t2 VALUES (nm, LAST_INSERT_ID());
+END|
+CREATE PROCEDURE test.p2(IN i INT)
+BEGIN
+ UPDATE test.t1 SET a = i*10 WHERE a = i;
+END|
+delimiter ;|
+SET FOREIGN_KEY_CHECKS=1;
+CALL test.p1(1,'texas');
+CALL test.p1(2,'Live');
+CALL test.p1(3,'next');
+CALL test.p1(4,'to');
+CALL test.p1(5,'OK');
+CALL test.p1(6,'MySQL');
+
+let $message=< -- test 2 select Master after p1 -- >;
+--source include/show_msg.inc
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+
+let $message=< -- test 2 select Slave after p1 -- >;
+--source include/show_msg.inc
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+
+let $message=< -- test 2 call p2 & select Master -- >;
+--source include/show_msg.inc
+connection master;
+CALL test.p2(2);
+CALL test.p2(4);
+CALL test.p2(6);
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+
+let $message=< -- test 1 select Slave after p2 -- >;
+--source include/show_msg.inc
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+
+connection master;
+#show binlog events;
+let $message=< -- End test 2 Begin test 3 -- >;
+--source include/show_msg.inc
+# End test 2 begin test 3
+
+eval CREATE TABLE test.t3 (a INT AUTO_INCREMENT KEY, t CHAR(6))ENGINE=$engine_type;
+
+delimiter |;
+CREATE PROCEDURE test.p3(IN n INT)
+begin
+CASE n
+WHEN 2 THEN
+ DELETE from test.t3;
+ELSE
+ INSERT INTO test.t3 VALUES (NULL,'NONE');
+END CASE;
+end|
+delimiter ;|
+
+SET AUTOCOMMIT=0;
+START TRANSACTION;
+
+-- disable_query_log
+-- disable_result_log
+let $n=50;
+while ($n)
+{
+ eval call test.p3($n);
+ dec $n;
+}
+-- enable_result_log
+-- enable_query_log
+
+ROLLBACK;
+select * from test.t3;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from test.t3;
+
+connection master;
+START TRANSACTION;
+
+-- disable_query_log
+-- disable_result_log
+let $n=50;
+while ($n>3)
+{
+ eval call test.p3($n);
+ dec $n;
+}
+-- enable_result_log
+-- enable_query_log
+
+COMMIT;
+select * from test.t3;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from test.t3;
+
+connection master;
+#show binlog events from 1626;
+
+
+# First lets cleanup
+SET AUTOCOMMIT=1;
+SET FOREIGN_KEY_CHECKS=0;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
+sync_slave_with_master;
+
+# End of 5.0 test case
diff --git a/mysql-test/extra/rpl_tests/rpl_row_sp003.test b/mysql-test/extra/rpl_tests/rpl_row_sp003.test
new file mode 100644
index 00000000000..2073fb41264
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_sp003.test
@@ -0,0 +1,72 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/13/2005 Created from Bug 12335 #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+--enable_warnings
+# End of cleanup
+
+# Begin test section 1
+
+eval CREATE TABLE test.t1(a INT,PRIMARY KEY(a))ENGINE=$engine_type;
+
+delimiter |;
+CREATE PROCEDURE test.p1()
+BEGIN
+ INSERT INTO test.t1 VALUES (4);
+ SELECT get_lock("test", 100);
+ UPDATE test.t1 set a=a+4 WHERE a=4;
+END|
+CREATE PROCEDURE test.p2()
+BEGIN
+ UPDATE test.t1 SET a=a+1;
+END|
+delimiter ;|
+
+SELECT get_lock("test", 200);
+
+connection master1;
+send CALL test.p1();
+
+connection master;
+# To make sure tha the call on master1 arrived at the get_lock
+sleep 1;
+CALL test.p2();
+SELECT release_lock("test");
+SELECT * FROM test.t1;
+#show binlog events;
+
+sync_slave_with_master;
+connection slave;
+SELECT * FROM test.t1;
+
+connection master;
+DROP TABLE IF EXISTS test.t1;
+eval CREATE TABLE test.t1(a INT,PRIMARY KEY(a))ENGINE=$engine_type;
+CALL test.p2();
+CALL test.p1();
+SELECT * FROM test.t1;
+
+sync_slave_with_master;
+connection slave;
+SELECT * FROM test.t1;
+connection master;
+#show binlog events from 719;
+
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+sync_slave_with_master;
+
+# End of 5.0 test case
diff --git a/mysql-test/extra/rpl_tests/rpl_row_sp006.test b/mysql-test/extra/rpl_tests/rpl_row_sp006.test
new file mode 100644
index 00000000000..272a7caf9ac
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_sp006.test
@@ -0,0 +1,90 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/15/2005 #
+# Updated: 08/29/2005 to remove sleeps #
+#############################################################################
+# Test: This test uses two SPs, one to populate a table, and another to use #
+# Cursors, CURRENT_DATE(), loop control, date math and logic control #
+# to populate a table with data from the first table. #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+create database if not exists mysqltest1;
+DROP PROCEDURE IF EXISTS mysqltest1.p1;
+DROP PROCEDURE IF EXISTS mysqltest1.p2;
+DROP TABLE IF EXISTS mysqltest1.t2;
+DROP TABLE IF EXISTS mysqltest1.t1;
+--enable_warnings
+# End of cleanup
+
+# Begin test section 1
+eval CREATE TABLE IF NOT EXISTS mysqltest1.t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=$engine_type;
+eval CREATE TABLE IF NOT EXISTS mysqltest1.t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=$engine_type;
+
+delimiter |;
+CREATE PROCEDURE mysqltest1.p1()
+BEGIN
+ DECLARE done INT DEFAULT 0;
+ DECLARE spa CHAR(16);
+ DECLARE spb INT;
+ DECLARE cur1 CURSOR FOR SELECT name,
+ (YEAR(CURDATE())-YEAR(birth))-(RIGHT(CURDATE(),5)<RIGHT(birth,5))
+ FROM mysqltest1.t1;
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
+
+ OPEN cur1;
+
+ SET AUTOCOMMIT=0;
+ REPEAT
+ FETCH cur1 INTO spa, spb;
+ IF NOT done THEN
+ START TRANSACTION;
+ INSERT INTO mysqltest1.t2 VALUES (spa,spb);
+ COMMIT;
+ END IF;
+ UNTIL done END REPEAT;
+
+ SET AUTOCOMMIT=1;
+ CLOSE cur1;
+END|
+CREATE PROCEDURE mysqltest1.p2()
+BEGIN
+ INSERT INTO mysqltest1.t1 VALUES ('MySQL','1993-02-04'),('ROCKS', '1990-08-27'),('Texas', '1999-03-30'),('kyle','2005-1-1');
+END|
+delimiter ;|
+
+CALL mysqltest1.p2();
+sync_slave_with_master;
+
+connection master;
+CALL mysqltest1.p1();
+sync_slave_with_master;
+
+connection master;
+
+--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > ./var/tmp/sp006_master.sql
+--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > ./var/tmp/sp006_slave.sql
+
+
+DROP PROCEDURE IF EXISTS mysqltest1.p1;
+DROP PROCEDURE IF EXISTS mysqltest1.p2;
+DROP TABLE IF EXISTS mysqltest1.t1;
+DROP TABLE IF EXISTS mysqltest1.t2;
+
+# Lets compare. Note: If they match test will pass, if they do not match
+# the test will show that the diff statement failed and not reject file
+# will be created. You will need to go to the mysql-test dir and diff
+# the files your self to see what is not matching :-) Failed test
+# Dump files will be located in mysql-test/var/tmp.
+
+exec diff ./var/tmp/sp006_master.sql ./var/tmp/sp006_slave.sql;
+
+sync_slave_with_master;
+
+# End of 5.1 test case
diff --git a/mysql-test/extra/rpl_tests/rpl_row_sp007.test b/mysql-test/extra/rpl_tests/rpl_row_sp007.test
new file mode 100644
index 00000000000..8f2b72e4d32
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_sp007.test
@@ -0,0 +1,70 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/15/2005 #
+# Updated: 08/29/2005 Remove sleeps #
+#############################################################################
+# TEST: SP that creates table, starts tranaction inserts. Save point, insert#
+# rollback to save point and then commits. #
+#############################################################################
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
+--enable_warnings
+# End of cleanup
+
+# Begin test section 1
+delimiter |;
+eval CREATE PROCEDURE test.p1(IN i INT)
+BEGIN
+ DECLARE CONTINUE HANDLER FOR sqlexception BEGIN END;
+ DROP TABLE IF EXISTS test.t1;
+ CREATE TABLE test.t1 (num INT,PRIMARY KEY(num))ENGINE=$engine_type;
+ START TRANSACTION;
+ INSERT INTO test.t1 VALUES(i);
+ savepoint t1_save;
+ INSERT INTO test.t1 VALUES (14);
+ ROLLBACK to savepoint t1_save;
+ COMMIT;
+END|
+delimiter ;|
+
+let $message=< ---- Master selects-- >;
+--source include/show_msg.inc
+CALL test.p1(12);
+SELECT * FROM test.t1;
+
+
+let $message=< ---- Slave selects-- >;
+--source include/show_msg.inc
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t1;
+
+let $message=< ---- Master selects-- >;
+--source include/show_msg.inc
+connection master;
+CALL test.p1(13);
+SELECT * FROM test.t1;
+
+let $message=< ---- Slave selects-- >;
+--source include/show_msg.inc
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t1;
+
+connection master;
+#show binlog events;
+
+
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
+
+# End of 5.0 test case
diff --git a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
new file mode 100644
index 00000000000..94a3af87ecd
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test
@@ -0,0 +1,129 @@
+# Test how replication of tables work when the definition on the
+# master and slave differs.
+
+# Consider making these part of the basic RBR tests.
+
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+connection master;
+eval CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=$engine_type;
+eval CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=$engine_type;
+eval CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=$engine_type;
+eval CREATE TABLE t4 (a INT) ENGINE=$engine_type;
+eval CREATE TABLE t5 (a INT, b INT, c INT) ENGINE=$engine_type;
+eval CREATE TABLE t6 (a INT, b INT, c INT) ENGINE=$engine_type;
+
+# Table used to detect that slave is running
+eval CREATE TABLE t9 (a INT PRIMARY KEY) ENGINE=$engine_type;
+
+sync_slave_with_master;
+# On the slave, we add one column last in table 't1',
+ALTER TABLE t1 ADD x INT DEFAULT 42;
+# ... add one column in the middle of table 't2', and
+ALTER TABLE t2 ADD x INT DEFAULT 42 AFTER a;
+# ... add one column first in table 't3'.
+ALTER TABLE t3 ADD x INT DEFAULT 42 FIRST;
+# ... change the type of the single column in table 't4'
+ALTER TABLE t4 MODIFY a FLOAT;
+# ... change the type of the middle column of table 't5'
+ALTER TABLE t5 MODIFY b FLOAT;
+# ... change the type of the last column of table 't6'
+ALTER TABLE t6 MODIFY c FLOAT;
+
+# Each of these should generate an error and stop the slave
+connection master;
+INSERT INTO t9 VALUES (1);
+sync_slave_with_master;
+# Now slave is guaranteed to be running
+connection master;
+INSERT INTO t1 VALUES (1,2);
+connection slave;
+wait_for_slave_to_stop;
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 8 # 9 # 23 # 33 #
+--vertical_results
+SHOW SLAVE STATUS;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+
+connection master;
+INSERT INTO t9 VALUES (2);
+sync_slave_with_master;
+# Now slave is guaranteed to be running
+connection master;
+INSERT INTO t2 VALUES (2,4);
+connection slave;
+wait_for_slave_to_stop;
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 8 # 9 # 23 # 33 #
+--vertical_results
+SHOW SLAVE STATUS;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+
+connection master;
+INSERT INTO t9 VALUES (3);
+sync_slave_with_master;
+# Now slave is guaranteed to be running
+connection master;
+INSERT INTO t3 VALUES (3,6);
+connection slave;
+wait_for_slave_to_stop;
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 8 # 9 # 23 # 33 #
+--vertical_results
+SHOW SLAVE STATUS;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+
+connection master;
+INSERT INTO t9 VALUES (4);
+sync_slave_with_master;
+# Now slave is guaranteed to be running
+connection master;
+INSERT INTO t4 VALUES (4);
+connection slave;
+wait_for_slave_to_stop;
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 8 # 9 # 23 # 33 #
+--vertical_results
+SHOW SLAVE STATUS;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+
+connection master;
+INSERT INTO t9 VALUES (5);
+sync_slave_with_master;
+# Now slave is guaranteed to be running
+connection master;
+INSERT INTO t5 VALUES (5,10,25);
+connection slave;
+wait_for_slave_to_stop;
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 8 # 9 # 23 # 33 #
+--vertical_results
+SHOW SLAVE STATUS;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+
+connection master;
+INSERT INTO t9 VALUES (6);
+sync_slave_with_master;
+# Now slave is guaranteed to be running
+connection master;
+INSERT INTO t6 VALUES (6,12,36);
+connection slave;
+wait_for_slave_to_stop;
+--replace_result $MASTER_MYPORT MASTER_PORT
+--replace_column 1 # 8 # 9 # 23 # 33 #
+--vertical_results
+SHOW SLAVE STATUS;
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+
+connection master;
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t9;
+--enable_warnings
+sync_slave_with_master;
diff --git a/mysql-test/t/rpl000001.test b/mysql-test/extra/rpl_tests/rpl_stm_000001.test
index 45d621b730f..fb2749a0764 100644
--- a/mysql-test/t/rpl000001.test
+++ b/mysql-test/extra/rpl_tests/rpl_stm_000001.test
@@ -1,4 +1,5 @@
-source include/master-slave.inc;
+-- source include/have_binlog_format_statement.inc
+-- source include/master-slave.inc
create table t1 (word char(20) not null);
load data infile '../../std_data/words.dat' into table t1;
@@ -44,7 +45,7 @@ sync_with_master;
connection master;
# we'll use table-level locking to delay slave SQL thread
-create table t1 (n int) engine=myisam;
+eval create table t1 (n int) engine=$engine_type;
sync_slave_with_master;
connection master;
reset master;
diff --git a/mysql-test/t/rpl_EE_error.test b/mysql-test/extra/rpl_tests/rpl_stm_EE_err.test
index 72df0c20ef8..9c7361093c3 100644
--- a/mysql-test/t/rpl_EE_error.test
+++ b/mysql-test/extra/rpl_tests/rpl_stm_EE_err.test
@@ -1,12 +1,18 @@
+# The test is not relevant when testing replication of error codes for
+# statements that are not replicated. The test below could be changed
+# to rely on the replication of error codes for statements that are not
+# replicated row-based.
+-- source include/have_binlog_format_statement.inc
+
# See if an EE_ error in one event of the master's binlog stops replication
# (it should not: in this configuration the EE_ error is probably not
# critical). Example: you do a DROP TABLE on a table which has no MYI file
# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and
# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986).
-source include/master-slave.inc;
+-- source include/master-slave.inc
-create table t1 (a int) engine=myisam;
+eval create table t1 (a int) engine=$engine_type;
flush tables;
system rm ./var/master-data/test/t1.MYI ;
drop table if exists t1;
@@ -17,7 +23,7 @@ sync_with_master;
# Now a real error.
connection master;
-create table t1 (a int, unique(a)) engine=myisam;
+eval create table t1 (a int, unique(a)) engine=$engine_type;
set sql_log_bin=0;
insert into t1 values(2);
set sql_log_bin=1;
diff --git a/mysql-test/t/rpl_charset.test b/mysql-test/extra/rpl_tests/rpl_stm_charset.test
index e5ddf084461..e05bbb49c4a 100644
--- a/mysql-test/t/rpl_charset.test
+++ b/mysql-test/extra/rpl_tests/rpl_stm_charset.test
@@ -1,6 +1,9 @@
# Replication of character sets.
# This test will fail if the server/client does not support enough charsets.
+# Requires statement logging
+-- source include/have_binlog_format_statement.inc
+
source include/master-slave.inc;
--disable_warnings
set timestamp=1000000000;
@@ -107,7 +110,7 @@ connection master;
drop database mysqltest2;
drop database mysqltest3;
--replace_column 2 # 5 #
-show binlog events from 98;
+show binlog events from 102;
sync_slave_with_master;
# Check that we can change global.collation_server (since 5.0.3)
@@ -161,10 +164,10 @@ sync_slave_with_master;
# BUG#6676: Derivation of variables must be correct on slave
#
connection master;
-create table `t1` (
+eval create table `t1` (
`pk` varchar(10) not null default '',
primary key (`pk`)
-) engine=myisam default charset=latin1;
+) engine=$engine_type default charset=latin1;
set @p=_latin1 'test';
update t1 set pk='test' where pk=@p;
drop table t1;
diff --git a/mysql-test/extra/rpl_tests/rpl_trig004.test b/mysql-test/extra/rpl_tests/rpl_trig004.test
new file mode 100644
index 00000000000..17031421bbe
--- /dev/null
+++ b/mysql-test/extra/rpl_tests/rpl_trig004.test
@@ -0,0 +1,46 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/09/2005 #
+#############################################################################
+# TEST: Use after insert and before inset triggers and stored procdures to #
+# Update and insert data #
+#############################################################################
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+--error 0,1360
+DROP TRIGGER test.t1_bi_t2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+
+
+eval CREATE TABLE test.t1 (n MEDIUMINT NOT NULL AUTO_INCREMENT, d FLOAT, PRIMARY KEY(n))ENGINE=$engine_type;
+eval CREATE TABLE test.t2 (n MEDIUMINT NOT NULL, f FLOAT, PRIMARY KEY(n))ENGINE=$engine_type;
+
+
+delimiter //;
+CREATE TRIGGER test.t1_bi_t2 BEFORE INSERT ON test.t2 FOR EACH ROW INSERT INTO test.t1 VALUES (NULL, 1.234)//
+delimiter ;//
+
+INSERT INTO test.t2 VALUES (1, 0.0);
+--error 0,1062
+INSERT INTO test.t2 VALUES (1, 0.0);
+
+#show binlog events;
+select * from test.t1;
+select * from test.t2;
+sync_slave_with_master;
+connection slave;
+select * from test.t1;
+select * from test.t2;
+
+connection master;
+
+DROP TRIGGER test.t1_bi_t2;
+DROP TABLE test.t1;
+DROP TABLE test.t2;
+
+sync_slave_with_master;
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_user_variables.test b/mysql-test/extra/rpl_tests/rpl_user_variables.test
index e8985397703..256c244d4eb 100644
--- a/mysql-test/t/rpl_user_variables.test
+++ b/mysql-test/extra/rpl_tests/rpl_user_variables.test
@@ -1,7 +1,8 @@
+# row-based and statement binlog difference in result files
#
# Test of replicating user variables
#
-source include/master-slave.inc;
+-- source include/master-slave.inc
# Disable PS as the log positions differs
--disable_ps_protocol
@@ -39,20 +40,15 @@ set @q:='abc';
insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
set @a:=5;
insert into t1 values (@a),(@a);
+# To flush the pending event, we add the following statement. RBR can
+# concatenate the result of several statements, which SBR cannot.
+select * from t1 where n = '<nonexistant>';
connection master1; # see if variable is reset in binlog when thread changes
insert into t1 values (@a),(@a),(@a*5);
select * from t1;
-save_master_pos;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
select * from t1;
---replace_column 2 # 5 #
-show binlog events from 98;
connection master;
drop table t1;
-save_master_pos;
-connection slave;
-sync_with_master;
+sync_slave_with_master;
stop slave;
-
-# End of 4.1 tests
diff --git a/mysql-test/include/have_binlog_format_row.inc b/mysql-test/include/have_binlog_format_row.inc
new file mode 100644
index 00000000000..2992b8e0f32
--- /dev/null
+++ b/mysql-test/include/have_binlog_format_row.inc
@@ -0,0 +1,4 @@
+-- require r/have_binlog_format_row.require
+disable_query_log;
+show variables like "binlog_format";
+enable_query_log;
diff --git a/mysql-test/include/have_binlog_format_statement.inc b/mysql-test/include/have_binlog_format_statement.inc
new file mode 100644
index 00000000000..c99297c10e5
--- /dev/null
+++ b/mysql-test/include/have_binlog_format_statement.inc
@@ -0,0 +1,4 @@
+-- require r/have_binlog_format_statement.require
+disable_query_log;
+show variables like "binlog_format";
+enable_query_log;
diff --git a/mysql-test/include/have_row_based.inc b/mysql-test/include/have_row_based.inc
new file mode 100644
index 00000000000..23771fde5cc
--- /dev/null
+++ b/mysql-test/include/have_row_based.inc
@@ -0,0 +1,4 @@
+-- require r/have_row_based.require
+disable_query_log;
+show variables like "have_row_based_replication";
+enable_query_log;
diff --git a/mysql-test/include/not_row_based.inc b/mysql-test/include/not_row_based.inc
new file mode 100644
index 00000000000..22f40bdceb0
--- /dev/null
+++ b/mysql-test/include/not_row_based.inc
@@ -0,0 +1,4 @@
+-- require r/not_row_based.require
+disable_query_log;
+show variables like "have_row_based_replication";
+enable_query_log;
diff --git a/mysql-test/include/rpl_multi_engine.inc b/mysql-test/include/rpl_multi_engine.inc
new file mode 100644
index 00000000000..f2c837ef90b
--- /dev/null
+++ b/mysql-test/include/rpl_multi_engine.inc
@@ -0,0 +1,16 @@
+connection master;
+INSERT INTO t1 VALUES(42,1,'Testing MySQL databases is a cool ', 'Must make it bug free for the customer',654321.4321,15.21,0,1965,"2005-11-14");
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+sync_slave_with_master;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+connection master;
+UPDATE t1 SET b1 = 0, t="2005-09-09" WHERE b1 = 1;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+sync_slave_with_master;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+connection master;
+DELETE FROM mysqltest1.t1 WHERE id = 42;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+sync_slave_with_master;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+connection master;
diff --git a/mysql-test/include/rpl_row_basic.inc b/mysql-test/include/rpl_row_basic.inc
new file mode 100644
index 00000000000..9f1cc186388
--- /dev/null
+++ b/mysql-test/include/rpl_row_basic.inc
@@ -0,0 +1,249 @@
+--source include/have_row_based.inc
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+
+#
+# Basic tests of row-level logging
+#
+
+#
+# First we test tables with only an index.
+#
+
+eval CREATE TABLE t1 (C1 CHAR(1), C2 CHAR(1), INDEX (C1)$extra_index_t1) ENGINE = $type ;
+SELECT * FROM t1;
+sync_slave_with_master;
+SELECT * FROM t1;
+
+# Testing insert
+connection master;
+INSERT INTO t1 VALUES ('A','B'), ('X','Y'), ('X','X');
+INSERT INTO t1 VALUES ('A','C'), ('X','Z'), ('A','A');
+SELECT * FROM t1 ORDER BY C1,C2;
+sync_slave_with_master;
+SELECT * FROM t1 ORDER BY C1,C2;
+
+# Testing delete
+# Observe that are several rows having the value for the index but only one
+# should be deleted.
+connection master;
+DELETE FROM t1 WHERE C1 = C2;
+SELECT * FROM t1 ORDER BY C1,C2;
+sync_slave_with_master;
+SELECT * FROM t1 ORDER BY C1,C2;
+
+#
+# Testing update.
+# Note that we have a condition on a column that is not part of the index for
+# the table. The right row should be updated nevertheless.
+#
+connection master;
+UPDATE t1 SET C2 = 'I' WHERE C1 = 'A' AND C2 = 'C';
+SELECT * FROM t1 ORDER BY C1,C2;
+sync_slave_with_master;
+SELECT * FROM t1 ORDER BY C1,C2;
+
+# Testing update with a condition that does not match any rows, but
+# which has a match for the index.
+connection master;
+UPDATE t1 SET c2 = 'Q' WHERE c1 = 'A' AND c2 = 'N';
+SELECT * FROM t1 ORDER BY c1,c2;
+sync_slave_with_master;
+SELECT * FROM t1 ORDER BY c1,c2;
+
+#
+# Testing table with primary key
+#
+connection master;
+eval CREATE TABLE t2 (c1 INT, c12 char(1), c2 INT, PRIMARY KEY (c1)) ENGINE = $type ;
+INSERT INTO t2
+ VALUES (1,'A',2), (2,'A',4), (3,'A',9), (4,'A',15), (5,'A',25),
+ (6,'A',35), (7,'A',50), (8,'A',64), (9,'A',81);
+SELECT * FROM t2 ORDER BY c1,c2;
+SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2;
+sync_slave_with_master;
+SELECT * FROM t2 ORDER BY c1,c2;
+SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2;
+
+connection master;
+UPDATE t2 SET c2 = c1*c1 WHERE c2 != c1*c1;
+SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2;
+sync_slave_with_master;
+SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2;
+
+# Testing update with a condition that does not match any rows, but
+# which has a match for the primary key.
+connection master;
+UPDATE t2 SET c12 = 'Q' WHERE c1 = 1 AND c2 = 999;
+SELECT * FROM t2 ORDER BY c1,c2;
+sync_slave_with_master;
+SELECT * FROM t2 ORDER BY c1,c2;
+
+connection master;
+DELETE FROM t2 WHERE c1 % 4 = 0;
+SELECT * FROM t2 ORDER BY c1,c2;
+sync_slave_with_master;
+SELECT * FROM t2 ORDER BY c1,c2;
+
+connection master;
+UPDATE t2 SET c12='X';
+
+#
+# Testing table with a multi-column primary key.
+#
+connection master;
+eval CREATE TABLE t3 (C1 CHAR(1), C2 CHAR(1), pk1 INT, C3 CHAR(1), pk2 INT, PRIMARY KEY (pk1,pk2)) ENGINE = $type ;
+
+INSERT INTO t3 VALUES ('A','B',1,'B',1), ('X','Y',2,'B',1), ('X','X',3,'B',1);
+INSERT INTO t3 VALUES ('A','C',1,'B',2), ('X','Z',2,'B',2), ('A','A',3,'B',2);
+SELECT * FROM t3 ORDER BY C1,C2;
+sync_slave_with_master;
+SELECT * FROM t3 ORDER BY C1,C2;
+
+connection master;
+DELETE FROM t3 WHERE C1 = C2;
+SELECT * FROM t3 ORDER BY C1,C2;
+sync_slave_with_master;
+SELECT * FROM t3 ORDER BY C1,C2;
+
+connection master;
+UPDATE t3 SET C2 = 'I' WHERE C1 = 'A' AND C2 = 'C';
+SELECT * FROM t3 ORDER BY C1,C2;
+sync_slave_with_master;
+SELECT * FROM t3 ORDER BY C1,C2;
+
+#
+# Testing table without index or primary key
+#
+connection master;
+eval CREATE TABLE t6 (C1 CHAR(1), C2 CHAR(1), C3 INT$extra_index_t6) ENGINE = $type;
+
+# Testing insert
+INSERT INTO t6 VALUES ('A','B',1), ('X','Y',2), ('X','X',3);
+INSERT INTO t6 VALUES ('A','C',4), ('X','Z',5), ('A','A',6);
+SELECT * FROM t6 ORDER BY C3;
+sync_slave_with_master;
+SELECT * FROM t6 ORDER BY C3;
+
+# Testing delete
+# Observe that are several rows having the value for the index but only one
+# should be deleted.
+connection master;
+DELETE FROM t6 WHERE C1 = C2;
+SELECT * FROM t6 ORDER BY C3;
+sync_slave_with_master;
+SELECT * FROM t6 ORDER BY C3;
+
+#
+# Testing update.
+# Note that we have a condition on a column that is not part of the index for
+# the table. The right row should be updated nevertheless.
+#
+connection master;
+UPDATE t6 SET C2 = 'I' WHERE C1 = 'A' AND C2 = 'C';
+SELECT * FROM t6 ORDER BY C3;
+sync_slave_with_master;
+SELECT * FROM t6 ORDER BY C3;
+
+# now mixing the 3 tables without begin/commit
+connection master;
+eval CREATE TABLE t5 (C1 CHAR(1), C2 CHAR(1), C3 INT PRIMARY KEY) ENGINE = $type ;
+INSERT INTO t5 VALUES ('A','B',1), ('X','Y',2), ('X','X',3);
+INSERT INTO t5 VALUES ('A','C',4), ('X','Z',5), ('A','A',6);
+
+UPDATE t5,t2,t3 SET t5.C2='Q', t2.c12='R', t3.C3 ='S' WHERE t5.C1 = t2.c12 AND t5.C1 = t3.C1;
+SELECT * FROM t5,t2,t3 WHERE t5.C2='Q' AND t2.c12='R' AND t3.C3 ='S' ORDER BY t5.C3,t2.c1,t3.pk1,t3.pk2;
+sync_slave_with_master;
+SELECT * FROM t5,t2,t3 WHERE t5.C2='Q' AND t2.c12='R' AND t3.C3 ='S' ORDER BY t5.C3,t2.c1,t3.pk1,t3.pk2;
+
+#
+# Testing special column types
+#
+
+connection master;
+eval CREATE TABLE t4 (C1 CHAR(1) PRIMARY KEY, B1 BIT(1), B2 BIT(1) NOT NULL DEFAULT 0, C2 CHAR(1) NOT NULL DEFAULT 'A') ENGINE = $type ;
+
+INSERT INTO t4 SET C1 = 1;
+SELECT C1,HEX(B1),HEX(B2) FROM t4 ORDER BY C1;
+sync_slave_with_master;
+SELECT C1,HEX(B1),HEX(B2) FROM t4 ORDER BY C1;
+
+#
+# Testing conflicting operations
+#
+connection master;
+eval CREATE TABLE t7 (C1 INT PRIMARY KEY, C2 INT) ENGINE = $type ;
+sync_slave_with_master;
+--disable_query_log
+SELECT "--- on slave: original values ---" AS "";
+--enable_query_log
+INSERT INTO t7 VALUES (1,3), (2,6), (3,9);
+SELECT * FROM t7 ORDER BY C1;
+
+connection master;
+--disable_query_log
+SELECT "--- on master: new values inserted ---" AS "";
+--enable_query_log
+INSERT INTO t7 VALUES (1,2), (2,4), (3,6);
+SELECT * FROM t7 ORDER BY C1;
+sync_slave_with_master;
+--disable_query_log
+SELECT "--- on slave: old values should be overwritten by replicated values ---" AS "";
+--enable_query_log
+SELECT * FROM t7 ORDER BY C1;
+
+#
+# A more complicated test where the table has several keys and we are
+# causing a conflict for a key that is not "last".
+#
+connection master;
+--disable_query_log
+SELECT "--- on master ---" AS "";
+--enable_query_log
+DROP TABLE t7;
+eval CREATE TABLE t7 (a INT PRIMARY KEY, b INT UNIQUE, c INT UNIQUE) ENGINE = $type ;
+
+# First we make sure that the constraints are correctly set.
+INSERT INTO t7 VALUES (99,99,99);
+--error 1062
+INSERT INTO t7 VALUES (99,22,33);
+--error 1062
+INSERT INTO t7 VALUES (11,99,33);
+--error 1062
+INSERT INTO t7 VALUES (11,22,99);
+SELECT * FROM t7 ORDER BY a;
+
+sync_slave_with_master;
+--disable_query_log
+SELECT "--- on slave ---" AS "";
+--enable_query_log
+SELECT * FROM t7 ORDER BY a;
+INSERT INTO t7 VALUES (1,2,3), (2,4,6), (3,6,9);
+SELECT * FROM t7 ORDER BY a;
+
+connection master;
+--disable_query_log
+SELECT "--- on master ---" AS "";
+--enable_query_log
+# We insert a row that will cause conflict on the primary key but not
+# on the other keys.
+INSERT INTO t7 VALUES (2,4,8);
+sync_slave_with_master;
+--disable_query_log
+SELECT "--- on slave ---" AS "";
+--enable_query_log
+SELECT * FROM t7 ORDER BY a;
+
+#
+# Test conflicting operations when changing in a table referenced by a
+# foreign key. We'll reuse the above table and just add a table that
+# references it.
+#
+
+#
+# cleanup
+#
+
+connection master;
+DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7;
+sync_slave_with_master;
diff --git a/mysql-test/include/rpl_stmt_seq2.inc b/mysql-test/include/rpl_stmt_seq2.inc
new file mode 100644
index 00000000000..7671a6a857c
--- /dev/null
+++ b/mysql-test/include/rpl_stmt_seq2.inc
@@ -0,0 +1,201 @@
+# include/rpl_stmt_seq.inc
+#
+# Please be very careful when editing this routine, because the handling of
+# the $variables is extreme sensitive.
+#
+
+###############################################################
+# Debug options : To debug this test script
+###############################################################
+let $show_binlog= 0;
+let $manipulate= 1;
+
+######## The typical test sequence
+# 1. INSERT without commit
+# check table content of master and slave
+# 2. EXECUTE the statement
+# check table content of master and slave
+# 3. ROLLBACK
+# check table content of master and slave
+# 4. flush the logs
+
+let $VERSION=`select version()`;
+
+--disable_query_log
+# SELECT '######## new test sequence ########' as "";
+eval SELECT CONCAT('######## ','$my_stmt',' $engine_type',' ########') as "";
+--enable_query_log
+
+
+###############################################################
+# Predict the number of the current log
+###############################################################
+# Disable the logging of the log number computation.
+--disable_query_log
+# $_log_num_n should contain the number of the current binlog in numeric style.
+# If this routine is called for the first time, $_log_num will not initialized
+# and contain the value '' instead of '1'. So we will correct it here.
+#
+eval set @aux= IF('$_log_num_n' = '', '1', '$_log_num_n');
+let $_log_num_n= `SELECT @aux`;
+eval set @aux= LPAD('$_log_num_n',6,'0');
+# SELECT @aux AS "@aux is";
+#
+# $_log_num_s should contain the number of the current binlog in string style.
+let $_log_num_s= `select @aux`;
+# eval SELECT '$log_num' ;
+--enable_query_log
+
+###############################################################
+# INSERT
+###############################################################
+connection master;
+--disable_query_log
+SELECT '-------- switch to master -------' as "";
+--enable_query_log
+# Maybe it would be smarter to use a table with autoincrement column.
+let $MAX= `SELECT MAX(f1) FROM t1` ;
+eval INSERT INTO t1 SET f1= $MAX + 1;
+# results before DDL(to be tested)
+SELECT MAX(f1) FROM t1;
+if ($show_binlog)
+{
+--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
+eval SHOW BINLOG EVENTS IN 'master-bin.$_log_num_s';
+}
+sync_slave_with_master;
+
+connection slave;
+--disable_query_log
+SELECT '-------- switch to slave --------' as "";
+--enable_query_log
+# results before DDL(to be tested)
+SELECT MAX(f1) FROM t1;
+if ($show_binlog)
+{
+--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
+eval SHOW BINLOG EVENTS IN 'slave-bin.$_log_num_s';
+}
+
+###############################################################
+# command to be tested
+###############################################################
+connection master;
+--disable_query_log
+SELECT '-------- switch to master -------' as "";
+--enable_query_log
+eval $my_stmt $engine_type;
+# Devaluate $my_stmt, to detect script bugs
+let $my_stmt= ERROR: YOU FORGOT TO FILL IN THE STATEMENT;
+# results after DDL(to be tested)
+SELECT MAX(f1) FROM t1;
+if ($show_binlog)
+{
+--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
+eval SHOW BINLOG EVENTS IN 'master-bin.$_log_num_s';
+}
+sync_slave_with_master;
+
+connection slave;
+--disable_query_log
+SELECT '-------- switch to slave --------' as "";
+--enable_query_log
+# results after DDL(to be tested)
+SELECT MAX(f1) FROM t1;
+if ($show_binlog)
+{
+--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
+eval SHOW BINLOG EVENTS IN 'slave-bin.$_log_num_s';
+}
+
+###############################################################
+# ROLLBACK
+###############################################################
+connection master;
+--disable_query_log
+SELECT '-------- switch to master -------' as "";
+--enable_query_log
+ROLLBACK;
+# results after final ROLLBACK
+SELECT MAX(f1) FROM t1;
+# Try to detect if the DDL command caused that the INSERT is committed
+# $MAX holds the highest/last value just before the insert of MAX + 1
+--disable_query_log
+eval SELECT CONCAT(CONCAT('TEST-INFO: MASTER: The INSERT is ',
+ IF(MAX(f1) = $MAX + 1, 'committed', 'not committed')),
+ IF((MAX(f1) = $MAX + 1) XOR NOT $my_master_commit,
+ ' (Succeeded)',
+ ' (Failed)')) AS ""
+ FROM mysqltest1.t1;
+--enable_query_log
+if ($show_binlog)
+{
+--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
+eval SHOW BINLOG EVENTS IN 'master-bin.$_log_num_s';
+}
+sync_slave_with_master;
+
+connection slave;
+--disable_query_log
+SELECT '-------- switch to slave --------' as "";
+--enable_query_log
+# results after final ROLLBACK
+SELECT MAX(f1) FROM t1;
+--disable_query_log
+eval SELECT CONCAT(CONCAT('TEST-INFO: SLAVE: The INSERT is ',
+ IF(MAX(f1) = $MAX + 1, 'committed', 'not committed')),
+ IF((MAX(f1) = $MAX + 1) XOR NOT $my_slave_commit,
+ ' (Succeeded)',
+ ' (Failed)')) AS ""
+ FROM mysqltest1.t1;
+--enable_query_log
+if ($show_binlog)
+{
+--replace_result $VERSION VERSION
+--replace_column 2 # 5 #
+eval SHOW BINLOG EVENTS IN 'slave-bin.$_log_num_s';
+}
+
+###############################################################
+# Manipulate binlog
+###############################################################
+if ($manipulate)
+{
+#### Manipulate the binary logs,
+# so that the output of SHOW BINLOG EVENTS IN <current log>
+# contains only commands of the current test sequence.
+# - flush the master and the slave log
+# ---> both start to write into new logs with incremented number
+# - increment $_log_num_n
+connection master;
+--disable_query_log
+SELECT '-------- switch to master -------' as "";
+--enable_query_log
+flush logs;
+# sleep 1;
+# eval SHOW BINLOG EVENTS IN 'master-bin.$_log_num_s';
+sync_slave_with_master;
+
+connection slave;
+--disable_query_log
+SELECT '-------- switch to slave --------' as "";
+--enable_query_log
+# the final content of the binary log
+flush logs;
+# The next sleep is urgent needed.
+# Without this sleep the slaves crashes often, when the SHOW BINLOG
+# is executed. :-(
+# sleep 1;
+# eval SHOW BINLOG EVENTS IN 'slave-bin.$_log_num_s';
+inc $_log_num_n;
+}
+
+connection master;
+--disable_query_log
+SELECT '-------- switch to master -------' as "";
+--enable_query_log
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 650c2b343f6..95968e1511e 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -2042,6 +2042,7 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir);
mtr_add_arg($args, "%s--core", $prefix);
mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
+ mtr_add_arg($args, "%s--loose-binlog-show-xid=0", $prefix);
mtr_add_arg($args, "%s--default-character-set=latin1", $prefix);
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
@@ -2165,6 +2166,7 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--sort_buffer=256K", $prefix);
mtr_add_arg($args, "%s--max_heap_table_size=1M", $prefix);
mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix);
+ mtr_add_arg($args, "%s--loose-binlog-show-xid=0", $prefix);
if ( $opt_ssl_supported )
{
@@ -2485,6 +2487,10 @@ sub run_mysqltest ($) {
my $cmdline_mysqldump= "$exe_mysqldump --no-defaults -uroot " .
"--port=$master->[0]->{'path_myport'} " .
"--socket=$master->[0]->{'path_mysock'} --password=";
+
+ my $cmdline_mysqldumpslave= "$exe_mysqldump --no-defaults -uroot " .
+ "--socket=$slave->[0]->{'path_mysock'} --password=";
+
if ( $opt_debug )
{
$cmdline_mysqldump .=
@@ -2568,6 +2574,7 @@ sub run_mysqltest ($) {
$ENV{'MYSQL_DUMP'}= $cmdline_mysqldump;
$ENV{'MYSQL_SLAP'}= $cmdline_mysqlslap unless $glob_win32;
$ENV{'MYSQL_IMPORT'}= $cmdline_mysqlimport;
+ $ENV{'MYSQL_DUMP_SLAVE'}= $cmdline_mysqldumpslave;
$ENV{'MYSQL_SHOW'}= $cmdline_mysqlshow;
$ENV{'MYSQL_BINLOG'}= $cmdline_mysqlbinlog;
$ENV{'MYSQL_FIX_SYSTEM_TABLES'}= $cmdline_mysql_fix_system_tables;
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index 5fc8f50dd47..3300e1a21a5 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -806,12 +806,13 @@ export MYSQL_DUMP_DIR
MYSQL_CHECK="$MYSQL_CHECK --no-defaults -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLCHECK_OPT"
MYSQL_DUMP="$MYSQL_DUMP --no-defaults -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLDUMP_OPT"
MYSQL_SLAP="$MYSQL_SLAP -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLSLAP_OPT"
+MYSQL_DUMP_SLAVE="$MYSQL_DUMP_DIR --no-defaults -uroot --socket=$SLAVE_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLDUMP_OPT"
MYSQL_SHOW="$MYSQL_SHOW -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLSHOW_OPT"
MYSQL_BINLOG="$MYSQL_BINLOG --no-defaults --local-load=$MYSQL_TMP_DIR --character-sets-dir=$CHARSETSDIR $EXTRA_MYSQLBINLOG_OPT"
MYSQL_IMPORT="$MYSQL_IMPORT -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLDUMP_OPT"
MYSQL_FIX_SYSTEM_TABLES="$MYSQL_FIX_SYSTEM_TABLES --no-defaults --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD --basedir=$BASEDIR --bindir=$CLIENT_BINDIR --verbose"
MYSQL="$MYSQL --no-defaults --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD"
-export MYSQL MYSQL_CHECK MYSQL_DUMP MYSQL_SHOW MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES MYSQL_IMPORT
+export MYSQL MYSQL_CHECK MYSQL_DUMP MYSQL_DUMP_SLAVE MYSQL_SHOW MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES MYSQL_IMPORT
export CLIENT_BINDIR MYSQL_CLIENT_TEST CHARSETSDIR MYSQL_MY_PRINT_DEFAULTS
export MYSQL_SLAP
export NDB_TOOLS_DIR
@@ -1287,9 +1288,10 @@ start_master()
--innodb_data_file_path=ibdata1:128M:autoextend \
--open-files-limit=1024 \
--log-bin-trust-function-creators \
+ --loose-binlog-show-xid=0 \
$MASTER_40_ARGS \
$SMALL_SERVER \
- $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
+ $EXTRA_MASTER_MYSQLD_OPT $EXTRA_MASTER_OPT \
$NOT_FIRST_MASTER_EXTRA_OPTS $CURR_MASTER_MYSQLD_TRACE"
else
master_args="--no-defaults --log-bin=$MYSQL_TEST_DIR/var/log/master-bin$1 \
@@ -1308,9 +1310,10 @@ start_master()
--language=$LANGUAGE \
--innodb_data_file_path=ibdata1:128M:autoextend \
--log-bin-trust-function-creators \
+ --loose-binlog-show-xid=0 \
$MASTER_40_ARGS \
$SMALL_SERVER \
- $EXTRA_MASTER_OPT $EXTRA_MASTER_MYSQLD_OPT \
+ $EXTRA_MASTER_MYSQLD_OPT $EXTRA_MASTER_OPT \
$NOT_FIRST_MASTER_EXTRA_OPTS"
fi
@@ -1441,8 +1444,9 @@ start_slave()
--master-retry-count=10 \
-O slave_net_timeout=10 \
--log-bin-trust-function-creators \
+ --loose-binlog-show-xid=0 \
$SMALL_SERVER \
- $EXTRA_SLAVE_OPT $EXTRA_SLAVE_MYSQLD_OPT"
+ $EXTRA_SLAVE_MYSQLD_OPT $EXTRA_SLAVE_OPT"
CUR_MYERR=$slave_err
CUR_MYSOCK=$slave_sock
diff --git a/mysql-test/r/binlog_row_binlog.result b/mysql-test/r/binlog_row_binlog.result
new file mode 100644
index 00000000000..df69ca29b2f
--- /dev/null
+++ b/mysql-test/r/binlog_row_binlog.result
@@ -0,0 +1,237 @@
+drop table if exists t1, t2;
+reset master;
+create table t1 (a int) engine=bdb;
+create table t2 (a int) engine=innodb;
+begin;
+insert t1 values (5);
+commit;
+begin;
+insert t2 values (5);
+commit;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; create table t1 (a int) engine=bdb
+master-bin.000001 # Query 1 # use `test`; create table t2 (a int) engine=innodb
+master-bin.000001 # Query 1 # use `test`; BEGIN
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `test`; COMMIT
+master-bin.000001 # Query 1 # use `test`; BEGIN
+master-bin.000001 # Table_map 1 # test.t2
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Xid 1 # COMMIT /* xid= */
+drop table t1,t2;
+reset master;
+create table t1 (n int) engine=innodb;
+begin;
+commit;
+drop table t1;
+show binlog events in 'master-bin.000001' from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; create table t1 (n int) engine=innodb
+master-bin.000001 # Query 1 # use `test`; BEGIN
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Xid 1 # COMMIT /* xid= */
+master-bin.000001 # Rotate 1 # master-bin.000002;pos=4
+show binlog events in 'master-bin.000002' from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000002 # Query 1 # use `test`; drop table t1
diff --git a/mysql-test/r/binlog_row_blackhole.result b/mysql-test/r/binlog_row_blackhole.result
new file mode 100644
index 00000000000..5c79f27bdf5
--- /dev/null
+++ b/mysql-test/r/binlog_row_blackhole.result
@@ -0,0 +1,146 @@
+drop table if exists t1,t2;
+CREATE TABLE t1 (
+Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL,
+Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL
+) ENGINE=blackhole;
+INSERT INTO t1 VALUES (9410,9412);
+select period from t1;
+period
+select * from t1;
+Period Varor_period
+select t1.* from t1;
+Period Varor_period
+CREATE TABLE t2 (
+auto int NOT NULL auto_increment,
+fld1 int(6) unsigned zerofill DEFAULT '000000' NOT NULL,
+companynr tinyint(2) unsigned zerofill DEFAULT '00' NOT NULL,
+fld3 char(30) DEFAULT '' NOT NULL,
+fld4 char(35) DEFAULT '' NOT NULL,
+fld5 char(35) DEFAULT '' NOT NULL,
+fld6 char(4) DEFAULT '' NOT NULL,
+primary key (auto)
+) ENGINE=blackhole;
+INSERT INTO t2 VALUES (1192,068305,00,'Colombo','hardware','colicky','');
+INSERT INTO t2 VALUES (1193,000000,00,'nondecreasing','implant','thrillingly','');
+select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%";
+fld3
+select fld3 from t2 where fld3 like "%cultivation" ;
+fld3
+select t2.fld3,companynr from t2 where companynr = 57+1 order by fld3;
+fld3 companynr
+select fld3,companynr from t2 where companynr = 58 order by fld3;
+fld3 companynr
+select fld3 from t2 order by fld3 desc limit 10;
+fld3
+select fld3 from t2 order by fld3 desc limit 5;
+fld3
+select fld3 from t2 order by fld3 desc limit 5,5;
+fld3
+select t2.fld3 from t2 where fld3 = 'honeysuckle';
+fld3
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_';
+fld3
+select t2.fld3 from t2 where fld3 LIKE 'hon_ysuckl_';
+fld3
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckle%';
+fld3
+select t2.fld3 from t2 where fld3 LIKE 'h%le';
+fld3
+select t2.fld3 from t2 where fld3 LIKE 'honeysuckle_';
+fld3
+select t2.fld3 from t2 where fld3 LIKE 'don_t_find_me_please%';
+fld3
+select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3;
+fld3
+select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3;
+fld1 fld3
+DROP TABLE t1;
+CREATE TABLE t1 (a VARCHAR(200), b TEXT, FULLTEXT (a,b));
+INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'),
+('Full-text indexes', 'are called collections'),
+('Only MyISAM tables','support collections'),
+('Function MATCH ... AGAINST()','is used to do a search'),
+('Full-text search in MySQL', 'implements vector space model');
+SHOW INDEX FROM t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 a 1 a NULL NULL NULL NULL YES FULLTEXT
+t1 1 a 2 b NULL NULL NULL NULL YES FULLTEXT
+select * from t1 where MATCH(a,b) AGAINST ("collections");
+a b
+Only MyISAM tables support collections
+Full-text indexes are called collections
+explain extended select * from t1 where MATCH(a,b) AGAINST ("collections");
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 fulltext a a 0 1 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where (match `test`.`t1`.`a`,`test`.`t1`.`b` against (_latin1'collections'))
+select * from t1 where MATCH(a,b) AGAINST ("indexes");
+a b
+Full-text indexes are called collections
+select * from t1 where MATCH(a,b) AGAINST ("indexes collections");
+a b
+Full-text indexes are called collections
+Only MyISAM tables support collections
+select * from t1 where MATCH(a,b) AGAINST ("only");
+a b
+reset master;
+drop table t1,t2;
+create table t1 (a int) engine=blackhole;
+delete from t1 where a=10;
+update t1 set a=11 where a=15;
+insert into t1 values(1);
+insert ignore into t1 values(1);
+replace into t1 values(100);
+create table t2 (a varchar(200)) engine=blackhole;
+load data infile '../../std_data/words.dat' into table t2;
+alter table t1 add b int;
+alter table t1 drop b;
+create table t3 like t1;
+insert into t1 select * from t3;
+replace into t1 select * from t3;
+select * from t1;
+a
+select * from t2;
+a
+select * from t3;
+a
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
+master-bin.000001 # Query 1 # use `test`; drop table t1,t2
+master-bin.000001 # Query 1 # use `test`; create table t1 (a int) engine=blackhole
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `test`; COMMIT
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `test`; COMMIT
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `test`; COMMIT
+master-bin.000001 # Query 1 # use `test`; create table t2 (a varchar(200)) engine=blackhole
+master-bin.000001 # Table_map 1 # test.t2
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `test`; COMMIT
+master-bin.000001 # Query 1 # use `test`; alter table t1 add b int
+master-bin.000001 # Query 1 # use `test`; alter table t1 drop b
+master-bin.000001 # Query 1 # use `test`; create table t3 like t1
+drop table t1,t2,t3;
+reset master;
+create table t1 (a int) engine=blackhole;
+set autocommit=0;
+start transaction;
+insert into t1 values(1);
+commit;
+start transaction;
+insert into t1 values(2);
+rollback;
+set autocommit=1;
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
+master-bin.000001 # Query 1 # use `test`; create table t1 (a int) engine=blackhole
+master-bin.000001 # Query 1 # use `test`; BEGIN
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `test`; COMMIT
diff --git a/mysql-test/r/binlog_row_ctype_cp932.result b/mysql-test/r/binlog_row_ctype_cp932.result
new file mode 100644
index 00000000000..179b6e52d86
--- /dev/null
+++ b/mysql-test/r/binlog_row_ctype_cp932.result
@@ -0,0 +1,11368 @@
+drop table if exists t1;
+drop table if exists t2;
+drop table if exists t3;
+drop table if exists t4;
+set names cp932;
+set character_set_database = cp932;
+CREATE TABLE t1(c1 CHAR(1)) DEFAULT CHARACTER SET = cp932;
+INSERT INTO t1 VALUES
+(0x05),(0x7E),(0x815C),(0x815F),(0x8160),(0x8161),(0x817C),(0x8191),(0x8192),(0x81CA);
+INSERT INTO t1 VALUES
+(0x8740),(0x8741),(0x8742),(0x8743),(0x8744),(0x8745),(0x8746),(0x8747),
+(0x8748),(0x8749),(0x874A),(0x874B),(0x874C),(0x874D),(0x874E),(0x874F),
+(0x8750),(0x8751),(0x8752),(0x8753),(0x8754),(0x8755),(0x8756),(0x8757),
+(0x8758),(0x8759),(0x875A),(0x875B),(0x875C),(0x875D),(0x875F),
+(0x8760),(0x8761),(0x8762),(0x8763),(0x8764),(0x8765),(0x8766),(0x8767),
+(0x8768),(0x8769),(0x876A),(0x876B),(0x876C),(0x876D),(0x876E),(0x876F),
+(0x8770),(0x8771),(0x8772),(0x8773),(0x8774),(0x8775),(0x877E),
+(0x8780),(0x8781),(0x8782),(0x8783),(0x8784),(0x8785),(0x8786),(0x8787),
+(0x8788),(0x8789),(0x878A),(0x878B),(0x878C),(0x878D),(0x878E),(0x878F),
+(0x8790),(0x8791),(0x8792),(0x8793),(0x8794),(0x8795),(0x8796),(0x8797),
+(0x8798),(0x8799),(0x879A),(0x879B),(0x879C);
+INSERT INTO t1 VALUES
+(0xED40),(0xED41),(0xED42),(0xED43),(0xED44),(0xED45),(0xED46),(0xED47),
+(0xED48),(0xED49),(0xED4A),(0xED4B),(0xED4C),(0xED4D),(0xED4E),(0xED4F),
+(0xED50),(0xED51),(0xED52),(0xED53),(0xED54),(0xED55),(0xED56),(0xED57),
+(0xED58),(0xED59),(0xED5A),(0xED5B),(0xED5C),(0xED5D),(0xED5E),(0xED5F),
+(0xED60),(0xED61),(0xED62),(0xED63),(0xED64),(0xED65),(0xED66),(0xED67),
+(0xED68),(0xED69),(0xED6A),(0xED6B),(0xED6C),(0xED6D),(0xED6E),(0xED6F),
+(0xED70),(0xED71),(0xED72),(0xED73),(0xED74),(0xED75),(0xED76),(0xED77),
+(0xED78),(0xED79),(0xED7A),(0xED7B),(0xED7C),(0xED7D),(0xED7E),
+(0xED80),(0xED81),(0xED82),(0xED83),(0xED84),(0xED85),(0xED86),(0xED87),
+(0xED88),(0xED89),(0xED8A),(0xED8B),(0xED8C),(0xED8D),(0xED8E),(0xED8F),
+(0xED90),(0xED91),(0xED92),(0xED93),(0xED94),(0xED95),(0xED96),(0xED97),
+(0xED98),(0xED99),(0xED9A),(0xED9B),(0xED9C),(0xED9D),(0xED9E),(0xED9F),
+(0xEDA0),(0xEDA1),(0xEDA2),(0xEDA3),(0xEDA4),(0xEDA5),(0xEDA6),(0xEDA7),
+(0xEDA8),(0xEDA9),(0xEDAA),(0xEDAB),(0xEDAC),(0xEDAD),(0xEDAE),(0xEDAF),
+(0xEDB0),(0xEDB1),(0xEDB2),(0xEDB3),(0xEDB4),(0xEDB5),(0xEDB6),(0xEDB7),
+(0xEDB8),(0xEDB9),(0xEDBA),(0xEDBB),(0xEDBC),(0xEDBD),(0xEDBE),(0xEDBF),
+(0xEDC0),(0xEDC1),(0xEDC2),(0xEDC3),(0xEDC4),(0xEDC5),(0xEDC6),(0xEDC7),
+(0xEDC8),(0xEDC9),(0xEDCA),(0xEDCB),(0xEDCC),(0xEDCD),(0xEDCE),(0xEDCF),
+(0xEDD0),(0xEDD1),(0xEDD2),(0xEDD3),(0xEDD4),(0xEDD5),(0xEDD6),(0xEDD7),
+(0xEDD8),(0xEDD9),(0xEDDA),(0xEDDB),(0xEDDC),(0xEDDD),(0xEDDE),(0xEDDF),
+(0xEDE0),(0xEDE1),(0xEDE2),(0xEDE3),(0xEDE4),(0xEDE5),(0xEDE6),(0xEDE7),
+(0xEDE8),(0xEDE9),(0xEDEA),(0xEDEB),(0xEDEC),(0xEDED),(0xEDEE),(0xEDEF),
+(0xEDF0),(0xEDF1),(0xEDF2),(0xEDF3),(0xEDF4),(0xEDF5),(0xEDF6),(0xEDF7),
+(0xEDF8),(0xEDF9),(0xEDFA),(0xEDFB),(0xEDFC),
+(0xEE40),(0xEE41),(0xEE42),(0xEE43),(0xEE44),(0xEE45),(0xEE46),(0xEE47),
+(0xEE48),(0xEE49),(0xEE4A),(0xEE4B),(0xEE4C),(0xEE4D),(0xEE4E),(0xEE4F),
+(0xEE50),(0xEE51),(0xEE52),(0xEE53),(0xEE54),(0xEE55),(0xEE56),(0xEE57),
+(0xEE58),(0xEE59),(0xEE5A),(0xEE5B),(0xEE5C),(0xEE5D),(0xEE5E),(0xEE5F),
+(0xEE60),(0xEE61),(0xEE62),(0xEE63),(0xEE64),(0xEE65),(0xEE66),(0xEE67),
+(0xEE68),(0xEE69),(0xEE6A),(0xEE6B),(0xEE6C),(0xEE6D),(0xEE6E),(0xEE6F),
+(0xEE70),(0xEE71),(0xEE72),(0xEE73),(0xEE74),(0xEE75),(0xEE76),(0xEE77),
+(0xEE78),(0xEE79),(0xEE7A),(0xEE7B),(0xEE7C),(0xEE7D),(0xEE7E),
+(0xEE80),(0xEE81),(0xEE82),(0xEE83),(0xEE84),(0xEE85),(0xEE86),(0xEE87),
+(0xEE88),(0xEE89),(0xEE8A),(0xEE8B),(0xEE8C),(0xEE8D),(0xEE8E),(0xEE8F),
+(0xEE90),(0xEE91),(0xEE92),(0xEE93),(0xEE94),(0xEE95),(0xEE96),(0xEE97),
+(0xEE98),(0xEE99),(0xEE9A),(0xEE9B),(0xEE9C),(0xEE9D),(0xEE9E),(0xEE9F),
+(0xEEA0),(0xEEA1),(0xEEA2),(0xEEA3),(0xEEA4),(0xEEA5),(0xEEA6),(0xEEA7),
+(0xEEA8),(0xEEA9),(0xEEAA),(0xEEAB),(0xEEAC),(0xEEAD),(0xEEAE),(0xEEAF),
+(0xEEB0),(0xEEB1),(0xEEB2),(0xEEB3),(0xEEB4),(0xEEB5),(0xEEB6),(0xEEB7),
+(0xEEB8),(0xEEB9),(0xEEBA),(0xEEBB),(0xEEBC),(0xEEBD),(0xEEBE),(0xEEBF),
+(0xEEC0),(0xEEC1),(0xEEC2),(0xEEC3),(0xEEC4),(0xEEC5),(0xEEC6),(0xEEC7),
+(0xEEC8),(0xEEC9),(0xEECA),(0xEECB),(0xEECC),(0xEECD),(0xEECE),(0xEECF),
+(0xEED0),(0xEED1),(0xEED2),(0xEED3),(0xEED4),(0xEED5),(0xEED6),(0xEED7),
+(0xEED8),(0xEED9),(0xEEDA),(0xEEDB),(0xEEDC),(0xEEDD),(0xEEDE),(0xEEDF),
+(0xEEE0),(0xEEE1),(0xEEE2),(0xEEE3),(0xEEE4),(0xEEE5),(0xEEE6),(0xEEE7),
+(0xEEE8),(0xEEE9),(0xEEEA),(0xEEEB),(0xEEEC),(0xEEEF),
+(0xEEF0),(0xEEF1),(0xEEF2),(0xEEF3),(0xEEF4),(0xEEF5),(0xEEF6),(0xEEF7),
+(0xEEF8),(0xEEF9),(0xEEFA),(0xEEFB),(0xEEFC);
+INSERT INTO t1 VALUES
+(0xFA40),(0xFA41),(0xFA42),(0xFA43),(0xFA44),(0xFA45),(0xFA46),(0xFA47),
+(0xFA48),(0xFA49),(0xFA4A),(0xFA4B),(0xFA4C),(0xFA4D),(0xFA4E),(0xFA4F),
+(0xFA50),(0xFA51),(0xFA52),(0xFA53),(0xFA54),(0xFA55),(0xFA56),(0xFA57),
+(0xFA58),(0xFA59),(0xFA5A),(0xFA5B),(0xFA5C),(0xFA5D),(0xFA5E),(0xFA5F),
+(0xFA60),(0xFA61),(0xFA62),(0xFA63),(0xFA64),(0xFA65),(0xFA66),(0xFA67),
+(0xFA68),(0xFA69),(0xFA6A),(0xFA6B),(0xFA6C),(0xFA6D),(0xFA6E),(0xFA6F),
+(0xFA70),(0xFA71),(0xFA72),(0xFA73),(0xFA74),(0xFA75),(0xFA76),(0xFA77),
+(0xFA78),(0xFA79),(0xFA7A),(0xFA7B),(0xFA7C),(0xFA7D),(0xFA7E),
+(0xFA80),(0xFA81),(0xFA82),(0xFA83),(0xFA84),(0xFA85),(0xFA86),(0xFA87),
+(0xFA88),(0xFA89),(0xFA8A),(0xFA8B),(0xFA8C),(0xFA8D),(0xFA8E),(0xFA8F),
+(0xFA90),(0xFA91),(0xFA92),(0xFA93),(0xFA94),(0xFA95),(0xFA96),(0xFA97),
+(0xFA98),(0xFA99),(0xFA9A),(0xFA9B),(0xFA9C),(0xFA9D),(0xFA9E),(0xFA9F),
+(0xFAA0),(0xFAA1),(0xFAA2),(0xFAA3),(0xFAA4),(0xFAA5),(0xFAA6),(0xFAA7),
+(0xFAA8),(0xFAA9),(0xFAAA),(0xFAAB),(0xFAAC),(0xFAAD),(0xFAAE),(0xFAAF),
+(0xFAB0),(0xFAB1),(0xFAB2),(0xFAB3),(0xFAB4),(0xFAB5),(0xFAB6),(0xFAB7),
+(0xFAB8),(0xFAB9),(0xFABA),(0xFABB),(0xFABC),(0xFABD),(0xFABE),(0xFABF),
+(0xFAC0),(0xFAC1),(0xFAC2),(0xFAC3),(0xFAC4),(0xFAC5),(0xFAC6),(0xFAC7),
+(0xFAC8),(0xFAC9),(0xFACA),(0xFACB),(0xFACC),(0xFACD),(0xFACE),(0xFACF),
+(0xFAD0),(0xFAD1),(0xFAD2),(0xFAD3),(0xFAD4),(0xFAD5),(0xFAD6),(0xFAD7),
+(0xFAD8),(0xFAD9),(0xFADA),(0xFADB),(0xFADC),(0xFADD),(0xFADE),(0xFADF),
+(0xFAE0),(0xFAE1),(0xFAE2),(0xFAE3),(0xFAE4),(0xFAE5),(0xFAE6),(0xFAE7),
+(0xFAE8),(0xFAE9),(0xFAEA),(0xFAEB),(0xFAEC),(0xFAED),(0xFAEE),(0xFAEF),
+(0xFAF0),(0xFAF1),(0xFAF2),(0xFAF3),(0xFAF4),(0xFAF5),(0xFAF6),(0xFAF7),
+(0xFAF8),(0xFAF9),(0xFAFA),(0xFAFB),(0xFAFC),
+(0xFB40),(0xFB41),(0xFB42),(0xFB43),(0xFB44),(0xFB45),(0xFB46),(0xFB47),
+(0xFB48),(0xFB49),(0xFB4A),(0xFB4B),(0xFB4C),(0xFB4D),(0xFB4E),(0xFB4F),
+(0xFB50),(0xFB51),(0xFB52),(0xFB53),(0xFB54),(0xFB55),(0xFB56),(0xFB57),
+(0xFB58),(0xFB59),(0xFB5A),(0xFB5B),(0xFB5C),(0xFB5D),(0xFB5E),(0xFB5F),
+(0xFB60),(0xFB61),(0xFB62),(0xFB63),(0xFB64),(0xFB65),(0xFB66),(0xFB67),
+(0xFB68),(0xFB69),(0xFB6A),(0xFB6B),(0xFB6C),(0xFB6D),(0xFB6E),(0xFB6F),
+(0xFB70),(0xFB71),(0xFB72),(0xFB73),(0xFB74),(0xFB75),(0xFB76),(0xFB77),
+(0xFB78),(0xFB79),(0xFB7A),(0xFB7B),(0xFB7C),(0xFB7D),(0xFB7E),
+(0xFB80),(0xFB81),(0xFB82),(0xFB83),(0xFB84),(0xFB85),(0xFB86),(0xFB87),
+(0xFB88),(0xFB89),(0xFB8A),(0xFB8B),(0xFB8C),(0xFB8D),(0xFB8E),(0xFB8F),
+(0xFB90),(0xFB91),(0xFB92),(0xFB93),(0xFB94),(0xFB95),(0xFB96),(0xFB97),
+(0xFB98),(0xFB99),(0xFB9A),(0xFB9B),(0xFB9C),(0xFB9D),(0xFB9E),(0xFB9F),
+(0xFBA0),(0xFBA1),(0xFBA2),(0xFBA3),(0xFBA4),(0xFBA5),(0xFBA6),(0xFBA7),
+(0xFBA8),(0xFBA9),(0xFBAA),(0xFBAB),(0xFBAC),(0xFBAD),(0xFBAE),(0xFBAF),
+(0xFBB0),(0xFBB1),(0xFBB2),(0xFBB3),(0xFBB4),(0xFBB5),(0xFBB6),(0xFBB7),
+(0xFBB8),(0xFBB9),(0xFBBA),(0xFBBB),(0xFBBC),(0xFBBD),(0xFBBE),(0xFBBF),
+(0xFBC0),(0xFBC1),(0xFBC2),(0xFBC3),(0xFBC4),(0xFBC5),(0xFBC6),(0xFBC7),
+(0xFBC8),(0xFBC9),(0xFBCA),(0xFBCB),(0xFBCC),(0xFBCD),(0xFBCE),(0xFBCF),
+(0xFBD0),(0xFBD1),(0xFBD2),(0xFBD3),(0xFBD4),(0xFBD5),(0xFBD6),(0xFBD7),
+(0xFBD8),(0xFBD9),(0xFBDA),(0xFBDB),(0xFBDC),(0xFBDD),(0xFBDE),(0xFBDF),
+(0xFBE0),(0xFBE1),(0xFBE2),(0xFBE3),(0xFBE4),(0xFBE5),(0xFBE6),(0xFBE7),
+(0xFBE8),(0xFBE9),(0xFBEA),(0xFBEB),(0xFBEC),(0xFBED),(0xFBEE),(0xFBEF),
+(0xFBF0),(0xFBF1),(0xFBF2),(0xFBF3),(0xFBF4),(0xFBF5),(0xFBF6),(0xFBF7),
+(0xFBF8),(0xFBF9),(0xFBFA),(0xFBFB),(0xFBFC),
+(0xFC40),(0xFC41),(0xFC42),(0xFC43),(0xFC44),(0xFC45),(0xFC46),(0xFC47),
+(0xFC48),(0xFC49),(0xFC4A),(0xFC4B);
+INSERT INTO t1 VALUES
+(0xF040),(0xF041),(0xF042),(0xF043),(0xF044),(0xF045),(0xF046),(0xF047),
+(0xF048),(0xF049),(0xF04A),(0xF04B),(0xF04C),(0xF04D),(0xF04E),(0xF04F),
+(0xF050),(0xF051),(0xF052),(0xF053),(0xF054),(0xF055),(0xF056),(0xF057),
+(0xF058),(0xF059),(0xF05A),(0xF05B),(0xF05C),(0xF05D),(0xF05E),(0xF05F),
+(0xF060),(0xF061),(0xF062),(0xF063),(0xF064),(0xF065),(0xF066),(0xF067),
+(0xF068),(0xF069),(0xF06A),(0xF06B),(0xF06C),(0xF06D),(0xF06E),(0xF06F),
+(0xF070),(0xF071),(0xF072),(0xF073),(0xF074),(0xF075),(0xF076),(0xF077),
+(0xF078),(0xF079),(0xF07A),(0xF07B),(0xF07C),(0xF07D),(0xF07E),
+(0xF080),(0xF081),(0xF082),(0xF083),(0xF084),(0xF085),(0xF086),(0xF087),
+(0xF088),(0xF089),(0xF08A),(0xF08B),(0xF08C),(0xF08D),(0xF08E),(0xF08F),
+(0xF090),(0xF091),(0xF092),(0xF093),(0xF094),(0xF095),(0xF096),(0xF097),
+(0xF098),(0xF099),(0xF09A),(0xF09B),(0xF09C),(0xF09D),(0xF09E),(0xF09F),
+(0xF0A0),(0xF0A1),(0xF0A2),(0xF0A3),(0xF0A4),(0xF0A5),(0xF0A6),(0xF0A7),
+(0xF0A8),(0xF0A9),(0xF0AA),(0xF0AB),(0xF0AC),(0xF0AD),(0xF0AE),(0xF0AF),
+(0xF0B0),(0xF0B1),(0xF0B2),(0xF0B3),(0xF0B4),(0xF0B5),(0xF0B6),(0xF0B7),
+(0xF0B8),(0xF0B9),(0xF0BA),(0xF0BB),(0xF0BC),(0xF0BD),(0xF0BE),(0xF0BF),
+(0xF0C0),(0xF0C1),(0xF0C2),(0xF0C3),(0xF0C4),(0xF0C5),(0xF0C6),(0xF0C7),
+(0xF0C8),(0xF0C9),(0xF0CA),(0xF0CB),(0xF0CC),(0xF0CD),(0xF0CE),(0xF0CF),
+(0xF0D0),(0xF0D1),(0xF0D2),(0xF0D3),(0xF0D4),(0xF0D5),(0xF0D6),(0xF0D7),
+(0xF0D8),(0xF0D9),(0xF0DA),(0xF0DB),(0xF0DC),(0xF0DD),(0xF0DE),(0xF0DF),
+(0xF0E0),(0xF0E1),(0xF0E2),(0xF0E3),(0xF0E4),(0xF0E5),(0xF0E6),(0xF0E7),
+(0xF0E8),(0xF0E9),(0xF0EA),(0xF0EB),(0xF0EC),(0xF0ED),(0xF0EE),(0xF0EF),
+(0xF0F0),(0xF0F1),(0xF0F2),(0xF0F3),(0xF0F4),(0xF0F5),(0xF0F6),(0xF0F7),
+(0xF0F8),(0xF0F9),(0xF0FA),(0xF0FB),(0xF0FC),
+(0xF140),(0xF141),(0xF142),(0xF143),(0xF144),(0xF145),(0xF146),(0xF147),
+(0xF148),(0xF149),(0xF14A),(0xF14B),(0xF14C),(0xF14D),(0xF14E),(0xF14F),
+(0xF150),(0xF151),(0xF152),(0xF153),(0xF154),(0xF155),(0xF156),(0xF157),
+(0xF158),(0xF159),(0xF15A),(0xF15B),(0xF15C),(0xF15D),(0xF15E),(0xF15F),
+(0xF160),(0xF161),(0xF162),(0xF163),(0xF164),(0xF165),(0xF166),(0xF167),
+(0xF168),(0xF169),(0xF16A),(0xF16B),(0xF16C),(0xF16D),(0xF16E),(0xF16F),
+(0xF170),(0xF171),(0xF172),(0xF173),(0xF174),(0xF175),(0xF176),(0xF177),
+(0xF178),(0xF179),(0xF17A),(0xF17B),(0xF17C),(0xF17D),(0xF17E),
+(0xF180),(0xF181),(0xF182),(0xF183),(0xF184),(0xF185),(0xF186),(0xF187),
+(0xF188),(0xF189),(0xF18A),(0xF18B),(0xF18C),(0xF18D),(0xF18E),(0xF18F),
+(0xF190),(0xF191),(0xF192),(0xF193),(0xF194),(0xF195),(0xF196),(0xF197),
+(0xF198),(0xF199),(0xF19A),(0xF19B),(0xF19C),(0xF19D),(0xF19E),(0xF19F),
+(0xF1A0),(0xF1A1),(0xF1A2),(0xF1A3),(0xF1A4),(0xF1A5),(0xF1A6),(0xF1A7),
+(0xF1A8),(0xF1A9),(0xF1AA),(0xF1AB),(0xF1AC),(0xF1AD),(0xF1AE),(0xF1AF),
+(0xF1B0),(0xF1B1),(0xF1B2),(0xF1B3),(0xF1B4),(0xF1B5),(0xF1B6),(0xF1B7),
+(0xF1B8),(0xF1B9),(0xF1BA),(0xF1BB),(0xF1BC),(0xF1BD),(0xF1BE),(0xF1BF),
+(0xF1C0),(0xF1C1),(0xF1C2),(0xF1C3),(0xF1C4),(0xF1C5),(0xF1C6),(0xF1C7),
+(0xF1C8),(0xF1C9),(0xF1CA),(0xF1CB),(0xF1CC),(0xF1CD),(0xF1CE),(0xF1CF),
+(0xF1D0),(0xF1D1),(0xF1D2),(0xF1D3),(0xF1D4),(0xF1D5),(0xF1D6),(0xF1D7),
+(0xF1D8),(0xF1D9),(0xF1DA),(0xF1DB),(0xF1DC),(0xF1DD),(0xF1DE),(0xF1DF),
+(0xF1E0),(0xF1E1),(0xF1E2),(0xF1E3),(0xF1E4),(0xF1E5),(0xF1E6),(0xF1E7),
+(0xF1E8),(0xF1E9),(0xF1EA),(0xF1EB),(0xF1EC),(0xF1ED),(0xF1EE),(0xF1EF),
+(0xF1F0),(0xF1F1),(0xF1F2),(0xF1F3),(0xF1F4),(0xF1F5),(0xF1F6),(0xF1F7),
+(0xF1F8),(0xF1F9),(0xF1FA),(0xF1FB),(0xF1FC),
+(0xF240),(0xF241),(0xF242),(0xF243),(0xF244),(0xF245),(0xF246),(0xF247),
+(0xF248),(0xF249),(0xF24A),(0xF24B),(0xF24C),(0xF24D),(0xF24E),(0xF24F),
+(0xF250),(0xF251),(0xF252),(0xF253),(0xF254),(0xF255),(0xF256),(0xF257),
+(0xF258),(0xF259),(0xF25A),(0xF25B),(0xF25C),(0xF25D),(0xF25E),(0xF25F),
+(0xF260),(0xF261),(0xF262),(0xF263),(0xF264),(0xF265),(0xF266),(0xF267),
+(0xF268),(0xF269),(0xF26A),(0xF26B),(0xF26C),(0xF26D),(0xF26E),(0xF26F),
+(0xF270),(0xF271),(0xF272),(0xF273),(0xF274),(0xF275),(0xF276),(0xF277),
+(0xF278),(0xF279),(0xF27A),(0xF27B),(0xF27C),(0xF27D),(0xF27E),
+(0xF280),(0xF281),(0xF282),(0xF283),(0xF284),(0xF285),(0xF286),(0xF287),
+(0xF288),(0xF289),(0xF28A),(0xF28B),(0xF28C),(0xF28D),(0xF28E),(0xF28F),
+(0xF290),(0xF291),(0xF292),(0xF293),(0xF294),(0xF295),(0xF296),(0xF297),
+(0xF298),(0xF299),(0xF29A),(0xF29B),(0xF29C),(0xF29D),(0xF29E),(0xF29F),
+(0xF2A0),(0xF2A1),(0xF2A2),(0xF2A3),(0xF2A4),(0xF2A5),(0xF2A6),(0xF2A7),
+(0xF2A8),(0xF2A9),(0xF2AA),(0xF2AB),(0xF2AC),(0xF2AD),(0xF2AE),(0xF2AF),
+(0xF2B0),(0xF2B1),(0xF2B2),(0xF2B3),(0xF2B4),(0xF2B5),(0xF2B6),(0xF2B7),
+(0xF2B8),(0xF2B9),(0xF2BA),(0xF2BB),(0xF2BC),(0xF2BD),(0xF2BE),(0xF2BF),
+(0xF2C0),(0xF2C1),(0xF2C2),(0xF2C3),(0xF2C4),(0xF2C5),(0xF2C6),(0xF2C7),
+(0xF2C8),(0xF2C9),(0xF2CA),(0xF2CB),(0xF2CC),(0xF2CD),(0xF2CE),(0xF2CF),
+(0xF2D0),(0xF2D1),(0xF2D2),(0xF2D3),(0xF2D4),(0xF2D5),(0xF2D6),(0xF2D7),
+(0xF2D8),(0xF2D9),(0xF2DA),(0xF2DB),(0xF2DC),(0xF2DD),(0xF2DE),(0xF2DF),
+(0xF2E0),(0xF2E1),(0xF2E2),(0xF2E3),(0xF2E4),(0xF2E5),(0xF2E6),(0xF2E7),
+(0xF2E8),(0xF2E9),(0xF2EA),(0xF2EB),(0xF2EC),(0xF2ED),(0xF2EE),(0xF2EF),
+(0xF2F0),(0xF2F1),(0xF2F2),(0xF2F3),(0xF2F4),(0xF2F5),(0xF2F6),(0xF2F7),
+(0xF2F8),(0xF2F9),(0xF2FA),(0xF2FB),(0xF2FC),
+(0xF340),(0xF341),(0xF342),(0xF343),(0xF344),(0xF345),(0xF346),(0xF347),
+(0xF348),(0xF349),(0xF34A),(0xF34B),(0xF34C),(0xF34D),(0xF34E),(0xF34F),
+(0xF350),(0xF351),(0xF352),(0xF353),(0xF354),(0xF355),(0xF356),(0xF357),
+(0xF358),(0xF359),(0xF35A),(0xF35B),(0xF35C),(0xF35D),(0xF35E),(0xF35F),
+(0xF360),(0xF361),(0xF362),(0xF363),(0xF364),(0xF365),(0xF366),(0xF367),
+(0xF368),(0xF369),(0xF36A),(0xF36B),(0xF36C),(0xF36D),(0xF36E),(0xF36F),
+(0xF370),(0xF371),(0xF372),(0xF373),(0xF374),(0xF375),(0xF376),(0xF377),
+(0xF378),(0xF379),(0xF37A),(0xF37B),(0xF37C),(0xF37D),(0xF37E),
+(0xF380),(0xF381),(0xF382),(0xF383),(0xF384),(0xF385),(0xF386),(0xF387),
+(0xF388),(0xF389),(0xF38A),(0xF38B),(0xF38C),(0xF38D),(0xF38E),(0xF38F),
+(0xF390),(0xF391),(0xF392),(0xF393),(0xF394),(0xF395),(0xF396),(0xF397),
+(0xF398),(0xF399),(0xF39A),(0xF39B),(0xF39C),(0xF39D),(0xF39E),(0xF39F),
+(0xF3A0),(0xF3A1),(0xF3A2),(0xF3A3),(0xF3A4),(0xF3A5),(0xF3A6),(0xF3A7),
+(0xF3A8),(0xF3A9),(0xF3AA),(0xF3AB),(0xF3AC),(0xF3AD),(0xF3AE),(0xF3AF),
+(0xF3B0),(0xF3B1),(0xF3B2),(0xF3B3),(0xF3B4),(0xF3B5),(0xF3B6),(0xF3B7),
+(0xF3B8),(0xF3B9),(0xF3BA),(0xF3BB),(0xF3BC),(0xF3BD),(0xF3BE),(0xF3BF),
+(0xF3C0),(0xF3C1),(0xF3C2),(0xF3C3),(0xF3C4),(0xF3C5),(0xF3C6),(0xF3C7),
+(0xF3C8),(0xF3C9),(0xF3CA),(0xF3CB),(0xF3CC),(0xF3CD),(0xF3CE),(0xF3CF),
+(0xF3D0),(0xF3D1),(0xF3D2),(0xF3D3),(0xF3D4),(0xF3D5),(0xF3D6),(0xF3D7),
+(0xF3D8),(0xF3D9),(0xF3DA),(0xF3DB),(0xF3DC),(0xF3DD),(0xF3DE),(0xF3DF),
+(0xF3E0),(0xF3E1),(0xF3E2),(0xF3E3),(0xF3E4),(0xF3E5),(0xF3E6),(0xF3E7),
+(0xF3E8),(0xF3E9),(0xF3EA),(0xF3EB),(0xF3EC),(0xF3ED),(0xF3EE),(0xF3EF),
+(0xF3F0),(0xF3F1),(0xF3F2),(0xF3F3),(0xF3F4),(0xF3F5),(0xF3F6),(0xF3F7),
+(0xF3F8),(0xF3F9),(0xF3FA),(0xF3FB),(0xF3FC),
+(0xF440),(0xF441),(0xF442),(0xF443),(0xF444),(0xF445),(0xF446),(0xF447),
+(0xF448),(0xF449),(0xF44A),(0xF44B),(0xF44C),(0xF44D),(0xF44E),(0xF44F),
+(0xF450),(0xF451),(0xF452),(0xF453),(0xF454),(0xF455),(0xF456),(0xF457),
+(0xF458),(0xF459),(0xF45A),(0xF45B),(0xF45C),(0xF45D),(0xF45E),(0xF45F),
+(0xF460),(0xF461),(0xF462),(0xF463),(0xF464),(0xF465),(0xF466),(0xF467),
+(0xF468),(0xF469),(0xF46A),(0xF46B),(0xF46C),(0xF46D),(0xF46E),(0xF46F),
+(0xF470),(0xF471),(0xF472),(0xF473),(0xF474),(0xF475),(0xF476),(0xF477),
+(0xF478),(0xF479),(0xF47A),(0xF47B),(0xF47C),(0xF47D),(0xF47E),
+(0xF480),(0xF481),(0xF482),(0xF483),(0xF484),(0xF485),(0xF486),(0xF487),
+(0xF488),(0xF489),(0xF48A),(0xF48B),(0xF48C),(0xF48D),(0xF48E),(0xF48F),
+(0xF490),(0xF491),(0xF492),(0xF493),(0xF494),(0xF495),(0xF496),(0xF497),
+(0xF498),(0xF499),(0xF49A),(0xF49B),(0xF49C),(0xF49D),(0xF49E),(0xF49F),
+(0xF4A0),(0xF4A1),(0xF4A2),(0xF4A3),(0xF4A4),(0xF4A5),(0xF4A6),(0xF4A7),
+(0xF4A8),(0xF4A9),(0xF4AA),(0xF4AB),(0xF4AC),(0xF4AD),(0xF4AE),(0xF4AF),
+(0xF4B0),(0xF4B1),(0xF4B2),(0xF4B3),(0xF4B4),(0xF4B5),(0xF4B6),(0xF4B7),
+(0xF4B8),(0xF4B9),(0xF4BA),(0xF4BB),(0xF4BC),(0xF4BD),(0xF4BE),(0xF4BF),
+(0xF4C0),(0xF4C1),(0xF4C2),(0xF4C3),(0xF4C4),(0xF4C5),(0xF4C6),(0xF4C7),
+(0xF4C8),(0xF4C9),(0xF4CA),(0xF4CB),(0xF4CC),(0xF4CD),(0xF4CE),(0xF4CF),
+(0xF4D0),(0xF4D1),(0xF4D2),(0xF4D3),(0xF4D4),(0xF4D5),(0xF4D6),(0xF4D7),
+(0xF4D8),(0xF4D9),(0xF4DA),(0xF4DB),(0xF4DC),(0xF4DD),(0xF4DE),(0xF4DF),
+(0xF4E0),(0xF4E1),(0xF4E2),(0xF4E3),(0xF4E4),(0xF4E5),(0xF4E6),(0xF4E7),
+(0xF4E8),(0xF4E9),(0xF4EA),(0xF4EB),(0xF4EC),(0xF4ED),(0xF4EE),(0xF4EF),
+(0xF4F0),(0xF4F1),(0xF4F2),(0xF4F3),(0xF4F4),(0xF4F5),(0xF4F6),(0xF4F7),
+(0xF4F8),(0xF4F9),(0xF4FA),(0xF4FB),(0xF4FC),
+(0xF540),(0xF541),(0xF542),(0xF543),(0xF544),(0xF545),(0xF546),(0xF547),
+(0xF548),(0xF549),(0xF54A),(0xF54B),(0xF54C),(0xF54D),(0xF54E),(0xF54F),
+(0xF550),(0xF551),(0xF552),(0xF553),(0xF554),(0xF555),(0xF556),(0xF557),
+(0xF558),(0xF559),(0xF55A),(0xF55B),(0xF55C),(0xF55D),(0xF55E),(0xF55F),
+(0xF560),(0xF561),(0xF562),(0xF563),(0xF564),(0xF565),(0xF566),(0xF567),
+(0xF568),(0xF569),(0xF56A),(0xF56B),(0xF56C),(0xF56D),(0xF56E),(0xF56F),
+(0xF570),(0xF571),(0xF572),(0xF573),(0xF574),(0xF575),(0xF576),(0xF577),
+(0xF578),(0xF579),(0xF57A),(0xF57B),(0xF57C),(0xF57D),(0xF57E),
+(0xF580),(0xF581),(0xF582),(0xF583),(0xF584),(0xF585),(0xF586),(0xF587),
+(0xF588),(0xF589),(0xF58A),(0xF58B),(0xF58C),(0xF58D),(0xF58E),(0xF58F),
+(0xF590),(0xF591),(0xF592),(0xF593),(0xF594),(0xF595),(0xF596),(0xF597),
+(0xF598),(0xF599),(0xF59A),(0xF59B),(0xF59C),(0xF59D),(0xF59E),(0xF59F),
+(0xF5A0),(0xF5A1),(0xF5A2),(0xF5A3),(0xF5A4),(0xF5A5),(0xF5A6),(0xF5A7),
+(0xF5A8),(0xF5A9),(0xF5AA),(0xF5AB),(0xF5AC),(0xF5AD),(0xF5AE),(0xF5AF),
+(0xF5B0),(0xF5B1),(0xF5B2),(0xF5B3),(0xF5B4),(0xF5B5),(0xF5B6),(0xF5B7),
+(0xF5B8),(0xF5B9),(0xF5BA),(0xF5BB),(0xF5BC),(0xF5BD),(0xF5BE),(0xF5BF),
+(0xF5C0),(0xF5C1),(0xF5C2),(0xF5C3),(0xF5C4),(0xF5C5),(0xF5C6),(0xF5C7),
+(0xF5C8),(0xF5C9),(0xF5CA),(0xF5CB),(0xF5CC),(0xF5CD),(0xF5CE),(0xF5CF),
+(0xF5D0),(0xF5D1),(0xF5D2),(0xF5D3),(0xF5D4),(0xF5D5),(0xF5D6),(0xF5D7),
+(0xF5D8),(0xF5D9),(0xF5DA),(0xF5DB),(0xF5DC),(0xF5DD),(0xF5DE),(0xF5DF),
+(0xF5E0),(0xF5E1),(0xF5E2),(0xF5E3),(0xF5E4),(0xF5E5),(0xF5E6),(0xF5E7),
+(0xF5E8),(0xF5E9),(0xF5EA),(0xF5EB),(0xF5EC),(0xF5ED),(0xF5EE),(0xF5EF),
+(0xF5F0),(0xF5F1),(0xF5F2),(0xF5F3),(0xF5F4),(0xF5F5),(0xF5F6),(0xF5F7),
+(0xF5F8),(0xF5F9),(0xF5FA),(0xF5FB),(0xF5FC),
+(0xF640),(0xF641),(0xF642),(0xF643),(0xF644),(0xF645),(0xF646),(0xF647),
+(0xF648),(0xF649),(0xF64A),(0xF64B),(0xF64C),(0xF64D),(0xF64E),(0xF64F),
+(0xF650),(0xF651),(0xF652),(0xF653),(0xF654),(0xF655),(0xF656),(0xF657),
+(0xF658),(0xF659),(0xF65A),(0xF65B),(0xF65C),(0xF65D),(0xF65E),(0xF65F),
+(0xF660),(0xF661),(0xF662),(0xF663),(0xF664),(0xF665),(0xF666),(0xF667),
+(0xF668),(0xF669),(0xF66A),(0xF66B),(0xF66C),(0xF66D),(0xF66E),(0xF66F),
+(0xF670),(0xF671),(0xF672),(0xF673),(0xF674),(0xF675),(0xF676),(0xF677),
+(0xF678),(0xF679),(0xF67A),(0xF67B),(0xF67C),(0xF67D),(0xF67E),
+(0xF680),(0xF681),(0xF682),(0xF683),(0xF684),(0xF685),(0xF686),(0xF687),
+(0xF688),(0xF689),(0xF68A),(0xF68B),(0xF68C),(0xF68D),(0xF68E),(0xF68F),
+(0xF690),(0xF691),(0xF692),(0xF693),(0xF694),(0xF695),(0xF696),(0xF697),
+(0xF698),(0xF699),(0xF69A),(0xF69B),(0xF69C),(0xF69D),(0xF69E),(0xF69F),
+(0xF6A0),(0xF6A1),(0xF6A2),(0xF6A3),(0xF6A4),(0xF6A5),(0xF6A6),(0xF6A7),
+(0xF6A8),(0xF6A9),(0xF6AA),(0xF6AB),(0xF6AC),(0xF6AD),(0xF6AE),(0xF6AF),
+(0xF6B0),(0xF6B1),(0xF6B2),(0xF6B3),(0xF6B4),(0xF6B5),(0xF6B6),(0xF6B7),
+(0xF6B8),(0xF6B9),(0xF6BA),(0xF6BB),(0xF6BC),(0xF6BD),(0xF6BE),(0xF6BF),
+(0xF6C0),(0xF6C1),(0xF6C2),(0xF6C3),(0xF6C4),(0xF6C5),(0xF6C6),(0xF6C7),
+(0xF6C8),(0xF6C9),(0xF6CA),(0xF6CB),(0xF6CC),(0xF6CD),(0xF6CE),(0xF6CF),
+(0xF6D0),(0xF6D1),(0xF6D2),(0xF6D3),(0xF6D4),(0xF6D5),(0xF6D6),(0xF6D7),
+(0xF6D8),(0xF6D9),(0xF6DA),(0xF6DB),(0xF6DC),(0xF6DD),(0xF6DE),(0xF6DF),
+(0xF6E0),(0xF6E1),(0xF6E2),(0xF6E3),(0xF6E4),(0xF6E5),(0xF6E6),(0xF6E7),
+(0xF6E8),(0xF6E9),(0xF6EA),(0xF6EB),(0xF6EC),(0xF6ED),(0xF6EE),(0xF6EF),
+(0xF6F0),(0xF6F1),(0xF6F2),(0xF6F3),(0xF6F4),(0xF6F5),(0xF6F6),(0xF6F7),
+(0xF6F8),(0xF6F9),(0xF6FA),(0xF6FB),(0xF6FC),
+(0xF740),(0xF741),(0xF742),(0xF743),(0xF744),(0xF745),(0xF746),(0xF747),
+(0xF748),(0xF749),(0xF74A),(0xF74B),(0xF74C),(0xF74D),(0xF74E),(0xF74F),
+(0xF750),(0xF751),(0xF752),(0xF753),(0xF754),(0xF755),(0xF756),(0xF757),
+(0xF758),(0xF759),(0xF75A),(0xF75B),(0xF75C),(0xF75D),(0xF75E),(0xF75F),
+(0xF760),(0xF761),(0xF762),(0xF763),(0xF764),(0xF765),(0xF766),(0xF767),
+(0xF768),(0xF769),(0xF76A),(0xF76B),(0xF76C),(0xF76D),(0xF76E),(0xF76F),
+(0xF770),(0xF771),(0xF772),(0xF773),(0xF774),(0xF775),(0xF776),(0xF777),
+(0xF778),(0xF779),(0xF77A),(0xF77B),(0xF77C),(0xF77D),(0xF77E),
+(0xF780),(0xF781),(0xF782),(0xF783),(0xF784),(0xF785),(0xF786),(0xF787),
+(0xF788),(0xF789),(0xF78A),(0xF78B),(0xF78C),(0xF78D),(0xF78E),(0xF78F),
+(0xF790),(0xF791),(0xF792),(0xF793),(0xF794),(0xF795),(0xF796),(0xF797),
+(0xF798),(0xF799),(0xF79A),(0xF79B),(0xF79C),(0xF79D),(0xF79E),(0xF79F),
+(0xF7A0),(0xF7A1),(0xF7A2),(0xF7A3),(0xF7A4),(0xF7A5),(0xF7A6),(0xF7A7),
+(0xF7A8),(0xF7A9),(0xF7AA),(0xF7AB),(0xF7AC),(0xF7AD),(0xF7AE),(0xF7AF),
+(0xF7B0),(0xF7B1),(0xF7B2),(0xF7B3),(0xF7B4),(0xF7B5),(0xF7B6),(0xF7B7),
+(0xF7B8),(0xF7B9),(0xF7BA),(0xF7BB),(0xF7BC),(0xF7BD),(0xF7BE),(0xF7BF),
+(0xF7C0),(0xF7C1),(0xF7C2),(0xF7C3),(0xF7C4),(0xF7C5),(0xF7C6),(0xF7C7),
+(0xF7C8),(0xF7C9),(0xF7CA),(0xF7CB),(0xF7CC),(0xF7CD),(0xF7CE),(0xF7CF),
+(0xF7D0),(0xF7D1),(0xF7D2),(0xF7D3),(0xF7D4),(0xF7D5),(0xF7D6),(0xF7D7),
+(0xF7D8),(0xF7D9),(0xF7DA),(0xF7DB),(0xF7DC),(0xF7DD),(0xF7DE),(0xF7DF),
+(0xF7E0),(0xF7E1),(0xF7E2),(0xF7E3),(0xF7E4),(0xF7E5),(0xF7E6),(0xF7E7),
+(0xF7E8),(0xF7E9),(0xF7EA),(0xF7EB),(0xF7EC),(0xF7ED),(0xF7EE),(0xF7EF),
+(0xF7F0),(0xF7F1),(0xF7F2),(0xF7F3),(0xF7F4),(0xF7F5),(0xF7F6),(0xF7F7),
+(0xF7F8),(0xF7F9),(0xF7FA),(0xF7FB),(0xF7FC),
+(0xF840),(0xF841),(0xF842),(0xF843),(0xF844),(0xF845),(0xF846),(0xF847),
+(0xF848),(0xF849),(0xF84A),(0xF84B),(0xF84C),(0xF84D),(0xF84E),(0xF84F),
+(0xF850),(0xF851),(0xF852),(0xF853),(0xF854),(0xF855),(0xF856),(0xF857),
+(0xF858),(0xF859),(0xF85A),(0xF85B),(0xF85C),(0xF85D),(0xF85E),(0xF85F),
+(0xF860),(0xF861),(0xF862),(0xF863),(0xF864),(0xF865),(0xF866),(0xF867),
+(0xF868),(0xF869),(0xF86A),(0xF86B),(0xF86C),(0xF86D),(0xF86E),(0xF86F),
+(0xF870),(0xF871),(0xF872),(0xF873),(0xF874),(0xF875),(0xF876),(0xF877),
+(0xF878),(0xF879),(0xF87A),(0xF87B),(0xF87C),(0xF87D),(0xF87E),
+(0xF880),(0xF881),(0xF882),(0xF883),(0xF884),(0xF885),(0xF886),(0xF887),
+(0xF888),(0xF889),(0xF88A),(0xF88B),(0xF88C),(0xF88D),(0xF88E),(0xF88F),
+(0xF890),(0xF891),(0xF892),(0xF893),(0xF894),(0xF895),(0xF896),(0xF897),
+(0xF898),(0xF899),(0xF89A),(0xF89B),(0xF89C),(0xF89D),(0xF89E),(0xF89F),
+(0xF8A0),(0xF8A1),(0xF8A2),(0xF8A3),(0xF8A4),(0xF8A5),(0xF8A6),(0xF8A7),
+(0xF8A8),(0xF8A9),(0xF8AA),(0xF8AB),(0xF8AC),(0xF8AD),(0xF8AE),(0xF8AF),
+(0xF8B0),(0xF8B1),(0xF8B2),(0xF8B3),(0xF8B4),(0xF8B5),(0xF8B6),(0xF8B7),
+(0xF8B8),(0xF8B9),(0xF8BA),(0xF8BB),(0xF8BC),(0xF8BD),(0xF8BE),(0xF8BF),
+(0xF8C0),(0xF8C1),(0xF8C2),(0xF8C3),(0xF8C4),(0xF8C5),(0xF8C6),(0xF8C7),
+(0xF8C8),(0xF8C9),(0xF8CA),(0xF8CB),(0xF8CC),(0xF8CD),(0xF8CE),(0xF8CF),
+(0xF8D0),(0xF8D1),(0xF8D2),(0xF8D3),(0xF8D4),(0xF8D5),(0xF8D6),(0xF8D7),
+(0xF8D8),(0xF8D9),(0xF8DA),(0xF8DB),(0xF8DC),(0xF8DD),(0xF8DE),(0xF8DF),
+(0xF8E0),(0xF8E1),(0xF8E2),(0xF8E3),(0xF8E4),(0xF8E5),(0xF8E6),(0xF8E7),
+(0xF8E8),(0xF8E9),(0xF8EA),(0xF8EB),(0xF8EC),(0xF8ED),(0xF8EE),(0xF8EF),
+(0xF8F0),(0xF8F1),(0xF8F2),(0xF8F3),(0xF8F4),(0xF8F5),(0xF8F6),(0xF8F7),
+(0xF8F8),(0xF8F9),(0xF8FA),(0xF8FB),(0xF8FC),
+(0xF940),(0xF941),(0xF942),(0xF943),(0xF944),(0xF945),(0xF946),(0xF947),
+(0xF948),(0xF949),(0xF94A),(0xF94B),(0xF94C),(0xF94D),(0xF94E),(0xF94F),
+(0xF950),(0xF951),(0xF952),(0xF953),(0xF954),(0xF955),(0xF956),(0xF957),
+(0xF958),(0xF959),(0xF95A),(0xF95B),(0xF95C),(0xF95D),(0xF95E),(0xF95F),
+(0xF960),(0xF961),(0xF962),(0xF963),(0xF964),(0xF965),(0xF966),(0xF967),
+(0xF968),(0xF969),(0xF96A),(0xF96B),(0xF96C),(0xF96D),(0xF96E),(0xF96F),
+(0xF970),(0xF971),(0xF972),(0xF973),(0xF974),(0xF975),(0xF976),(0xF977),
+(0xF978),(0xF979),(0xF97A),(0xF97B),(0xF97C),(0xF97D),(0xF97E),
+(0xF980),(0xF981),(0xF982),(0xF983),(0xF984),(0xF985),(0xF986),(0xF987),
+(0xF988),(0xF989),(0xF98A),(0xF98B),(0xF98C),(0xF98D),(0xF98E),(0xF98F),
+(0xF990),(0xF991),(0xF992),(0xF993),(0xF994),(0xF995),(0xF996),(0xF997),
+(0xF998),(0xF999),(0xF99A),(0xF99B),(0xF99C),(0xF99D),(0xF99E),(0xF99F),
+(0xF9A0),(0xF9A1),(0xF9A2),(0xF9A3),(0xF9A4),(0xF9A5),(0xF9A6),(0xF9A7),
+(0xF9A8),(0xF9A9),(0xF9AA),(0xF9AB),(0xF9AC),(0xF9AD),(0xF9AE),(0xF9AF),
+(0xF9B0),(0xF9B1),(0xF9B2),(0xF9B3),(0xF9B4),(0xF9B5),(0xF9B6),(0xF9B7),
+(0xF9B8),(0xF9B9),(0xF9BA),(0xF9BB),(0xF9BC),(0xF9BD),(0xF9BE),(0xF9BF),
+(0xF9C0),(0xF9C1),(0xF9C2),(0xF9C3),(0xF9C4),(0xF9C5),(0xF9C6),(0xF9C7),
+(0xF9C8),(0xF9C9),(0xF9CA),(0xF9CB),(0xF9CC),(0xF9CD),(0xF9CE),(0xF9CF),
+(0xF9D0),(0xF9D1),(0xF9D2),(0xF9D3),(0xF9D4),(0xF9D5),(0xF9D6),(0xF9D7),
+(0xF9D8),(0xF9D9),(0xF9DA),(0xF9DB),(0xF9DC),(0xF9DD),(0xF9DE),(0xF9DF),
+(0xF9E0),(0xF9E1),(0xF9E2),(0xF9E3),(0xF9E4),(0xF9E5),(0xF9E6),(0xF9E7),
+(0xF9E8),(0xF9E9),(0xF9EA),(0xF9EB),(0xF9EC),(0xF9ED),(0xF9EE),(0xF9EF),
+(0xF9F0),(0xF9F1),(0xF9F2),(0xF9F3),(0xF9F4),(0xF9F5),(0xF9F6),(0xF9F7),
+(0xF9F8),(0xF9F9),(0xF9FA),(0xF9FB),(0xF9FC);
+SELECT HEX(c1) FROM t1;
+HEX(c1)
+05
+7E
+815C
+815F
+8160
+8161
+817C
+8191
+8192
+81CA
+8740
+8741
+8742
+8743
+8744
+8745
+8746
+8747
+8748
+8749
+874A
+874B
+874C
+874D
+874E
+874F
+8750
+8751
+8752
+8753
+8754
+8755
+8756
+8757
+8758
+8759
+875A
+875B
+875C
+875D
+875F
+8760
+8761
+8762
+8763
+8764
+8765
+8766
+8767
+8768
+8769
+876A
+876B
+876C
+876D
+876E
+876F
+8770
+8771
+8772
+8773
+8774
+8775
+877E
+8780
+8781
+8782
+8783
+8784
+8785
+8786
+8787
+8788
+8789
+878A
+878B
+878C
+878D
+878E
+878F
+8790
+8791
+8792
+8793
+8794
+8795
+8796
+8797
+8798
+8799
+879A
+879B
+879C
+ED40
+ED41
+ED42
+ED43
+ED44
+ED45
+ED46
+ED47
+ED48
+ED49
+ED4A
+ED4B
+ED4C
+ED4D
+ED4E
+ED4F
+ED50
+ED51
+ED52
+ED53
+ED54
+ED55
+ED56
+ED57
+ED58
+ED59
+ED5A
+ED5B
+ED5C
+ED5D
+ED5E
+ED5F
+ED60
+ED61
+ED62
+ED63
+ED64
+ED65
+ED66
+ED67
+ED68
+ED69
+ED6A
+ED6B
+ED6C
+ED6D
+ED6E
+ED6F
+ED70
+ED71
+ED72
+ED73
+ED74
+ED75
+ED76
+ED77
+ED78
+ED79
+ED7A
+ED7B
+ED7C
+ED7D
+ED7E
+ED80
+ED81
+ED82
+ED83
+ED84
+ED85
+ED86
+ED87
+ED88
+ED89
+ED8A
+ED8B
+ED8C
+ED8D
+ED8E
+ED8F
+ED90
+ED91
+ED92
+ED93
+ED94
+ED95
+ED96
+ED97
+ED98
+ED99
+ED9A
+ED9B
+ED9C
+ED9D
+ED9E
+ED9F
+EDA0
+EDA1
+EDA2
+EDA3
+EDA4
+EDA5
+EDA6
+EDA7
+EDA8
+EDA9
+EDAA
+EDAB
+EDAC
+EDAD
+EDAE
+EDAF
+EDB0
+EDB1
+EDB2
+EDB3
+EDB4
+EDB5
+EDB6
+EDB7
+EDB8
+EDB9
+EDBA
+EDBB
+EDBC
+EDBD
+EDBE
+EDBF
+EDC0
+EDC1
+EDC2
+EDC3
+EDC4
+EDC5
+EDC6
+EDC7
+EDC8
+EDC9
+EDCA
+EDCB
+EDCC
+EDCD
+EDCE
+EDCF
+EDD0
+EDD1
+EDD2
+EDD3
+EDD4
+EDD5
+EDD6
+EDD7
+EDD8
+EDD9
+EDDA
+EDDB
+EDDC
+EDDD
+EDDE
+EDDF
+EDE0
+EDE1
+EDE2
+EDE3
+EDE4
+EDE5
+EDE6
+EDE7
+EDE8
+EDE9
+EDEA
+EDEB
+EDEC
+EDED
+EDEE
+EDEF
+EDF0
+EDF1
+EDF2
+EDF3
+EDF4
+EDF5
+EDF6
+EDF7
+EDF8
+EDF9
+EDFA
+EDFB
+EDFC
+EE40
+EE41
+EE42
+EE43
+EE44
+EE45
+EE46
+EE47
+EE48
+EE49
+EE4A
+EE4B
+EE4C
+EE4D
+EE4E
+EE4F
+EE50
+EE51
+EE52
+EE53
+EE54
+EE55
+EE56
+EE57
+EE58
+EE59
+EE5A
+EE5B
+EE5C
+EE5D
+EE5E
+EE5F
+EE60
+EE61
+EE62
+EE63
+EE64
+EE65
+EE66
+EE67
+EE68
+EE69
+EE6A
+EE6B
+EE6C
+EE6D
+EE6E
+EE6F
+EE70
+EE71
+EE72
+EE73
+EE74
+EE75
+EE76
+EE77
+EE78
+EE79
+EE7A
+EE7B
+EE7C
+EE7D
+EE7E
+EE80
+EE81
+EE82
+EE83
+EE84
+EE85
+EE86
+EE87
+EE88
+EE89
+EE8A
+EE8B
+EE8C
+EE8D
+EE8E
+EE8F
+EE90
+EE91
+EE92
+EE93
+EE94
+EE95
+EE96
+EE97
+EE98
+EE99
+EE9A
+EE9B
+EE9C
+EE9D
+EE9E
+EE9F
+EEA0
+EEA1
+EEA2
+EEA3
+EEA4
+EEA5
+EEA6
+EEA7
+EEA8
+EEA9
+EEAA
+EEAB
+EEAC
+EEAD
+EEAE
+EEAF
+EEB0
+EEB1
+EEB2
+EEB3
+EEB4
+EEB5
+EEB6
+EEB7
+EEB8
+EEB9
+EEBA
+EEBB
+EEBC
+EEBD
+EEBE
+EEBF
+EEC0
+EEC1
+EEC2
+EEC3
+EEC4
+EEC5
+EEC6
+EEC7
+EEC8
+EEC9
+EECA
+EECB
+EECC
+EECD
+EECE
+EECF
+EED0
+EED1
+EED2
+EED3
+EED4
+EED5
+EED6
+EED7
+EED8
+EED9
+EEDA
+EEDB
+EEDC
+EEDD
+EEDE
+EEDF
+EEE0
+EEE1
+EEE2
+EEE3
+EEE4
+EEE5
+EEE6
+EEE7
+EEE8
+EEE9
+EEEA
+EEEB
+EEEC
+EEEF
+EEF0
+EEF1
+EEF2
+EEF3
+EEF4
+EEF5
+EEF6
+EEF7
+EEF8
+EEF9
+EEFA
+EEFB
+EEFC
+FA40
+FA41
+FA42
+FA43
+FA44
+FA45
+FA46
+FA47
+FA48
+FA49
+FA4A
+FA4B
+FA4C
+FA4D
+FA4E
+FA4F
+FA50
+FA51
+FA52
+FA53
+FA54
+FA55
+FA56
+FA57
+FA58
+FA59
+FA5A
+FA5B
+FA5C
+FA5D
+FA5E
+FA5F
+FA60
+FA61
+FA62
+FA63
+FA64
+FA65
+FA66
+FA67
+FA68
+FA69
+FA6A
+FA6B
+FA6C
+FA6D
+FA6E
+FA6F
+FA70
+FA71
+FA72
+FA73
+FA74
+FA75
+FA76
+FA77
+FA78
+FA79
+FA7A
+FA7B
+FA7C
+FA7D
+FA7E
+FA80
+FA81
+FA82
+FA83
+FA84
+FA85
+FA86
+FA87
+FA88
+FA89
+FA8A
+FA8B
+FA8C
+FA8D
+FA8E
+FA8F
+FA90
+FA91
+FA92
+FA93
+FA94
+FA95
+FA96
+FA97
+FA98
+FA99
+FA9A
+FA9B
+FA9C
+FA9D
+FA9E
+FA9F
+FAA0
+FAA1
+FAA2
+FAA3
+FAA4
+FAA5
+FAA6
+FAA7
+FAA8
+FAA9
+FAAA
+FAAB
+FAAC
+FAAD
+FAAE
+FAAF
+FAB0
+FAB1
+FAB2
+FAB3
+FAB4
+FAB5
+FAB6
+FAB7
+FAB8
+FAB9
+FABA
+FABB
+FABC
+FABD
+FABE
+FABF
+FAC0
+FAC1
+FAC2
+FAC3
+FAC4
+FAC5
+FAC6
+FAC7
+FAC8
+FAC9
+FACA
+FACB
+FACC
+FACD
+FACE
+FACF
+FAD0
+FAD1
+FAD2
+FAD3
+FAD4
+FAD5
+FAD6
+FAD7
+FAD8
+FAD9
+FADA
+FADB
+FADC
+FADD
+FADE
+FADF
+FAE0
+FAE1
+FAE2
+FAE3
+FAE4
+FAE5
+FAE6
+FAE7
+FAE8
+FAE9
+FAEA
+FAEB
+FAEC
+FAED
+FAEE
+FAEF
+FAF0
+FAF1
+FAF2
+FAF3
+FAF4
+FAF5
+FAF6
+FAF7
+FAF8
+FAF9
+FAFA
+FAFB
+FAFC
+FB40
+FB41
+FB42
+FB43
+FB44
+FB45
+FB46
+FB47
+FB48
+FB49
+FB4A
+FB4B
+FB4C
+FB4D
+FB4E
+FB4F
+FB50
+FB51
+FB52
+FB53
+FB54
+FB55
+FB56
+FB57
+FB58
+FB59
+FB5A
+FB5B
+FB5C
+FB5D
+FB5E
+FB5F
+FB60
+FB61
+FB62
+FB63
+FB64
+FB65
+FB66
+FB67
+FB68
+FB69
+FB6A
+FB6B
+FB6C
+FB6D
+FB6E
+FB6F
+FB70
+FB71
+FB72
+FB73
+FB74
+FB75
+FB76
+FB77
+FB78
+FB79
+FB7A
+FB7B
+FB7C
+FB7D
+FB7E
+FB80
+FB81
+FB82
+FB83
+FB84
+FB85
+FB86
+FB87
+FB88
+FB89
+FB8A
+FB8B
+FB8C
+FB8D
+FB8E
+FB8F
+FB90
+FB91
+FB92
+FB93
+FB94
+FB95
+FB96
+FB97
+FB98
+FB99
+FB9A
+FB9B
+FB9C
+FB9D
+FB9E
+FB9F
+FBA0
+FBA1
+FBA2
+FBA3
+FBA4
+FBA5
+FBA6
+FBA7
+FBA8
+FBA9
+FBAA
+FBAB
+FBAC
+FBAD
+FBAE
+FBAF
+FBB0
+FBB1
+FBB2
+FBB3
+FBB4
+FBB5
+FBB6
+FBB7
+FBB8
+FBB9
+FBBA
+FBBB
+FBBC
+FBBD
+FBBE
+FBBF
+FBC0
+FBC1
+FBC2
+FBC3
+FBC4
+FBC5
+FBC6
+FBC7
+FBC8
+FBC9
+FBCA
+FBCB
+FBCC
+FBCD
+FBCE
+FBCF
+FBD0
+FBD1
+FBD2
+FBD3
+FBD4
+FBD5
+FBD6
+FBD7
+FBD8
+FBD9
+FBDA
+FBDB
+FBDC
+FBDD
+FBDE
+FBDF
+FBE0
+FBE1
+FBE2
+FBE3
+FBE4
+FBE5
+FBE6
+FBE7
+FBE8
+FBE9
+FBEA
+FBEB
+FBEC
+FBED
+FBEE
+FBEF
+FBF0
+FBF1
+FBF2
+FBF3
+FBF4
+FBF5
+FBF6
+FBF7
+FBF8
+FBF9
+FBFA
+FBFB
+FBFC
+FC40
+FC41
+FC42
+FC43
+FC44
+FC45
+FC46
+FC47
+FC48
+FC49
+FC4A
+FC4B
+F040
+F041
+F042
+F043
+F044
+F045
+F046
+F047
+F048
+F049
+F04A
+F04B
+F04C
+F04D
+F04E
+F04F
+F050
+F051
+F052
+F053
+F054
+F055
+F056
+F057
+F058
+F059
+F05A
+F05B
+F05C
+F05D
+F05E
+F05F
+F060
+F061
+F062
+F063
+F064
+F065
+F066
+F067
+F068
+F069
+F06A
+F06B
+F06C
+F06D
+F06E
+F06F
+F070
+F071
+F072
+F073
+F074
+F075
+F076
+F077
+F078
+F079
+F07A
+F07B
+F07C
+F07D
+F07E
+F080
+F081
+F082
+F083
+F084
+F085
+F086
+F087
+F088
+F089
+F08A
+F08B
+F08C
+F08D
+F08E
+F08F
+F090
+F091
+F092
+F093
+F094
+F095
+F096
+F097
+F098
+F099
+F09A
+F09B
+F09C
+F09D
+F09E
+F09F
+F0A0
+F0A1
+F0A2
+F0A3
+F0A4
+F0A5
+F0A6
+F0A7
+F0A8
+F0A9
+F0AA
+F0AB
+F0AC
+F0AD
+F0AE
+F0AF
+F0B0
+F0B1
+F0B2
+F0B3
+F0B4
+F0B5
+F0B6
+F0B7
+F0B8
+F0B9
+F0BA
+F0BB
+F0BC
+F0BD
+F0BE
+F0BF
+F0C0
+F0C1
+F0C2
+F0C3
+F0C4
+F0C5
+F0C6
+F0C7
+F0C8
+F0C9
+F0CA
+F0CB
+F0CC
+F0CD
+F0CE
+F0CF
+F0D0
+F0D1
+F0D2
+F0D3
+F0D4
+F0D5
+F0D6
+F0D7
+F0D8
+F0D9
+F0DA
+F0DB
+F0DC
+F0DD
+F0DE
+F0DF
+F0E0
+F0E1
+F0E2
+F0E3
+F0E4
+F0E5
+F0E6
+F0E7
+F0E8
+F0E9
+F0EA
+F0EB
+F0EC
+F0ED
+F0EE
+F0EF
+F0F0
+F0F1
+F0F2
+F0F3
+F0F4
+F0F5
+F0F6
+F0F7
+F0F8
+F0F9
+F0FA
+F0FB
+F0FC
+F140
+F141
+F142
+F143
+F144
+F145
+F146
+F147
+F148
+F149
+F14A
+F14B
+F14C
+F14D
+F14E
+F14F
+F150
+F151
+F152
+F153
+F154
+F155
+F156
+F157
+F158
+F159
+F15A
+F15B
+F15C
+F15D
+F15E
+F15F
+F160
+F161
+F162
+F163
+F164
+F165
+F166
+F167
+F168
+F169
+F16A
+F16B
+F16C
+F16D
+F16E
+F16F
+F170
+F171
+F172
+F173
+F174
+F175
+F176
+F177
+F178
+F179
+F17A
+F17B
+F17C
+F17D
+F17E
+F180
+F181
+F182
+F183
+F184
+F185
+F186
+F187
+F188
+F189
+F18A
+F18B
+F18C
+F18D
+F18E
+F18F
+F190
+F191
+F192
+F193
+F194
+F195
+F196
+F197
+F198
+F199
+F19A
+F19B
+F19C
+F19D
+F19E
+F19F
+F1A0
+F1A1
+F1A2
+F1A3
+F1A4
+F1A5
+F1A6
+F1A7
+F1A8
+F1A9
+F1AA
+F1AB
+F1AC
+F1AD
+F1AE
+F1AF
+F1B0
+F1B1
+F1B2
+F1B3
+F1B4
+F1B5
+F1B6
+F1B7
+F1B8
+F1B9
+F1BA
+F1BB
+F1BC
+F1BD
+F1BE
+F1BF
+F1C0
+F1C1
+F1C2
+F1C3
+F1C4
+F1C5
+F1C6
+F1C7
+F1C8
+F1C9
+F1CA
+F1CB
+F1CC
+F1CD
+F1CE
+F1CF
+F1D0
+F1D1
+F1D2
+F1D3
+F1D4
+F1D5
+F1D6
+F1D7
+F1D8
+F1D9
+F1DA
+F1DB
+F1DC
+F1DD
+F1DE
+F1DF
+F1E0
+F1E1
+F1E2
+F1E3
+F1E4
+F1E5
+F1E6
+F1E7
+F1E8
+F1E9
+F1EA
+F1EB
+F1EC
+F1ED
+F1EE
+F1EF
+F1F0
+F1F1
+F1F2
+F1F3
+F1F4
+F1F5
+F1F6
+F1F7
+F1F8
+F1F9
+F1FA
+F1FB
+F1FC
+F240
+F241
+F242
+F243
+F244
+F245
+F246
+F247
+F248
+F249
+F24A
+F24B
+F24C
+F24D
+F24E
+F24F
+F250
+F251
+F252
+F253
+F254
+F255
+F256
+F257
+F258
+F259
+F25A
+F25B
+F25C
+F25D
+F25E
+F25F
+F260
+F261
+F262
+F263
+F264
+F265
+F266
+F267
+F268
+F269
+F26A
+F26B
+F26C
+F26D
+F26E
+F26F
+F270
+F271
+F272
+F273
+F274
+F275
+F276
+F277
+F278
+F279
+F27A
+F27B
+F27C
+F27D
+F27E
+F280
+F281
+F282
+F283
+F284
+F285
+F286
+F287
+F288
+F289
+F28A
+F28B
+F28C
+F28D
+F28E
+F28F
+F290
+F291
+F292
+F293
+F294
+F295
+F296
+F297
+F298
+F299
+F29A
+F29B
+F29C
+F29D
+F29E
+F29F
+F2A0
+F2A1
+F2A2
+F2A3
+F2A4
+F2A5
+F2A6
+F2A7
+F2A8
+F2A9
+F2AA
+F2AB
+F2AC
+F2AD
+F2AE
+F2AF
+F2B0
+F2B1
+F2B2
+F2B3
+F2B4
+F2B5
+F2B6
+F2B7
+F2B8
+F2B9
+F2BA
+F2BB
+F2BC
+F2BD
+F2BE
+F2BF
+F2C0
+F2C1
+F2C2
+F2C3
+F2C4
+F2C5
+F2C6
+F2C7
+F2C8
+F2C9
+F2CA
+F2CB
+F2CC
+F2CD
+F2CE
+F2CF
+F2D0
+F2D1
+F2D2
+F2D3
+F2D4
+F2D5
+F2D6
+F2D7
+F2D8
+F2D9
+F2DA
+F2DB
+F2DC
+F2DD
+F2DE
+F2DF
+F2E0
+F2E1
+F2E2
+F2E3
+F2E4
+F2E5
+F2E6
+F2E7
+F2E8
+F2E9
+F2EA
+F2EB
+F2EC
+F2ED
+F2EE
+F2EF
+F2F0
+F2F1
+F2F2
+F2F3
+F2F4
+F2F5
+F2F6
+F2F7
+F2F8
+F2F9
+F2FA
+F2FB
+F2FC
+F340
+F341
+F342
+F343
+F344
+F345
+F346
+F347
+F348
+F349
+F34A
+F34B
+F34C
+F34D
+F34E
+F34F
+F350
+F351
+F352
+F353
+F354
+F355
+F356
+F357
+F358
+F359
+F35A
+F35B
+F35C
+F35D
+F35E
+F35F
+F360
+F361
+F362
+F363
+F364
+F365
+F366
+F367
+F368
+F369
+F36A
+F36B
+F36C
+F36D
+F36E
+F36F
+F370
+F371
+F372
+F373
+F374
+F375
+F376
+F377
+F378
+F379
+F37A
+F37B
+F37C
+F37D
+F37E
+F380
+F381
+F382
+F383
+F384
+F385
+F386
+F387
+F388
+F389
+F38A
+F38B
+F38C
+F38D
+F38E
+F38F
+F390
+F391
+F392
+F393
+F394
+F395
+F396
+F397
+F398
+F399
+F39A
+F39B
+F39C
+F39D
+F39E
+F39F
+F3A0
+F3A1
+F3A2
+F3A3
+F3A4
+F3A5
+F3A6
+F3A7
+F3A8
+F3A9
+F3AA
+F3AB
+F3AC
+F3AD
+F3AE
+F3AF
+F3B0
+F3B1
+F3B2
+F3B3
+F3B4
+F3B5
+F3B6
+F3B7
+F3B8
+F3B9
+F3BA
+F3BB
+F3BC
+F3BD
+F3BE
+F3BF
+F3C0
+F3C1
+F3C2
+F3C3
+F3C4
+F3C5
+F3C6
+F3C7
+F3C8
+F3C9
+F3CA
+F3CB
+F3CC
+F3CD
+F3CE
+F3CF
+F3D0
+F3D1
+F3D2
+F3D3
+F3D4
+F3D5
+F3D6
+F3D7
+F3D8
+F3D9
+F3DA
+F3DB
+F3DC
+F3DD
+F3DE
+F3DF
+F3E0
+F3E1
+F3E2
+F3E3
+F3E4
+F3E5
+F3E6
+F3E7
+F3E8
+F3E9
+F3EA
+F3EB
+F3EC
+F3ED
+F3EE
+F3EF
+F3F0
+F3F1
+F3F2
+F3F3
+F3F4
+F3F5
+F3F6
+F3F7
+F3F8
+F3F9
+F3FA
+F3FB
+F3FC
+F440
+F441
+F442
+F443
+F444
+F445
+F446
+F447
+F448
+F449
+F44A
+F44B
+F44C
+F44D
+F44E
+F44F
+F450
+F451
+F452
+F453
+F454
+F455
+F456
+F457
+F458
+F459
+F45A
+F45B
+F45C
+F45D
+F45E
+F45F
+F460
+F461
+F462
+F463
+F464
+F465
+F466
+F467
+F468
+F469
+F46A
+F46B
+F46C
+F46D
+F46E
+F46F
+F470
+F471
+F472
+F473
+F474
+F475
+F476
+F477
+F478
+F479
+F47A
+F47B
+F47C
+F47D
+F47E
+F480
+F481
+F482
+F483
+F484
+F485
+F486
+F487
+F488
+F489
+F48A
+F48B
+F48C
+F48D
+F48E
+F48F
+F490
+F491
+F492
+F493
+F494
+F495
+F496
+F497
+F498
+F499
+F49A
+F49B
+F49C
+F49D
+F49E
+F49F
+F4A0
+F4A1
+F4A2
+F4A3
+F4A4
+F4A5
+F4A6
+F4A7
+F4A8
+F4A9
+F4AA
+F4AB
+F4AC
+F4AD
+F4AE
+F4AF
+F4B0
+F4B1
+F4B2
+F4B3
+F4B4
+F4B5
+F4B6
+F4B7
+F4B8
+F4B9
+F4BA
+F4BB
+F4BC
+F4BD
+F4BE
+F4BF
+F4C0
+F4C1
+F4C2
+F4C3
+F4C4
+F4C5
+F4C6
+F4C7
+F4C8
+F4C9
+F4CA
+F4CB
+F4CC
+F4CD
+F4CE
+F4CF
+F4D0
+F4D1
+F4D2
+F4D3
+F4D4
+F4D5
+F4D6
+F4D7
+F4D8
+F4D9
+F4DA
+F4DB
+F4DC
+F4DD
+F4DE
+F4DF
+F4E0
+F4E1
+F4E2
+F4E3
+F4E4
+F4E5
+F4E6
+F4E7
+F4E8
+F4E9
+F4EA
+F4EB
+F4EC
+F4ED
+F4EE
+F4EF
+F4F0
+F4F1
+F4F2
+F4F3
+F4F4
+F4F5
+F4F6
+F4F7
+F4F8
+F4F9
+F4FA
+F4FB
+F4FC
+F540
+F541
+F542
+F543
+F544
+F545
+F546
+F547
+F548
+F549
+F54A
+F54B
+F54C
+F54D
+F54E
+F54F
+F550
+F551
+F552
+F553
+F554
+F555
+F556
+F557
+F558
+F559
+F55A
+F55B
+F55C
+F55D
+F55E
+F55F
+F560
+F561
+F562
+F563
+F564
+F565
+F566
+F567
+F568
+F569
+F56A
+F56B
+F56C
+F56D
+F56E
+F56F
+F570
+F571
+F572
+F573
+F574
+F575
+F576
+F577
+F578
+F579
+F57A
+F57B
+F57C
+F57D
+F57E
+F580
+F581
+F582
+F583
+F584
+F585
+F586
+F587
+F588
+F589
+F58A
+F58B
+F58C
+F58D
+F58E
+F58F
+F590
+F591
+F592
+F593
+F594
+F595
+F596
+F597
+F598
+F599
+F59A
+F59B
+F59C
+F59D
+F59E
+F59F
+F5A0
+F5A1
+F5A2
+F5A3
+F5A4
+F5A5
+F5A6
+F5A7
+F5A8
+F5A9
+F5AA
+F5AB
+F5AC
+F5AD
+F5AE
+F5AF
+F5B0
+F5B1
+F5B2
+F5B3
+F5B4
+F5B5
+F5B6
+F5B7
+F5B8
+F5B9
+F5BA
+F5BB
+F5BC
+F5BD
+F5BE
+F5BF
+F5C0
+F5C1
+F5C2
+F5C3
+F5C4
+F5C5
+F5C6
+F5C7
+F5C8
+F5C9
+F5CA
+F5CB
+F5CC
+F5CD
+F5CE
+F5CF
+F5D0
+F5D1
+F5D2
+F5D3
+F5D4
+F5D5
+F5D6
+F5D7
+F5D8
+F5D9
+F5DA
+F5DB
+F5DC
+F5DD
+F5DE
+F5DF
+F5E0
+F5E1
+F5E2
+F5E3
+F5E4
+F5E5
+F5E6
+F5E7
+F5E8
+F5E9
+F5EA
+F5EB
+F5EC
+F5ED
+F5EE
+F5EF
+F5F0
+F5F1
+F5F2
+F5F3
+F5F4
+F5F5
+F5F6
+F5F7
+F5F8
+F5F9
+F5FA
+F5FB
+F5FC
+F640
+F641
+F642
+F643
+F644
+F645
+F646
+F647
+F648
+F649
+F64A
+F64B
+F64C
+F64D
+F64E
+F64F
+F650
+F651
+F652
+F653
+F654
+F655
+F656
+F657
+F658
+F659
+F65A
+F65B
+F65C
+F65D
+F65E
+F65F
+F660
+F661
+F662
+F663
+F664
+F665
+F666
+F667
+F668
+F669
+F66A
+F66B
+F66C
+F66D
+F66E
+F66F
+F670
+F671
+F672
+F673
+F674
+F675
+F676
+F677
+F678
+F679
+F67A
+F67B
+F67C
+F67D
+F67E
+F680
+F681
+F682
+F683
+F684
+F685
+F686
+F687
+F688
+F689
+F68A
+F68B
+F68C
+F68D
+F68E
+F68F
+F690
+F691
+F692
+F693
+F694
+F695
+F696
+F697
+F698
+F699
+F69A
+F69B
+F69C
+F69D
+F69E
+F69F
+F6A0
+F6A1
+F6A2
+F6A3
+F6A4
+F6A5
+F6A6
+F6A7
+F6A8
+F6A9
+F6AA
+F6AB
+F6AC
+F6AD
+F6AE
+F6AF
+F6B0
+F6B1
+F6B2
+F6B3
+F6B4
+F6B5
+F6B6
+F6B7
+F6B8
+F6B9
+F6BA
+F6BB
+F6BC
+F6BD
+F6BE
+F6BF
+F6C0
+F6C1
+F6C2
+F6C3
+F6C4
+F6C5
+F6C6
+F6C7
+F6C8
+F6C9
+F6CA
+F6CB
+F6CC
+F6CD
+F6CE
+F6CF
+F6D0
+F6D1
+F6D2
+F6D3
+F6D4
+F6D5
+F6D6
+F6D7
+F6D8
+F6D9
+F6DA
+F6DB
+F6DC
+F6DD
+F6DE
+F6DF
+F6E0
+F6E1
+F6E2
+F6E3
+F6E4
+F6E5
+F6E6
+F6E7
+F6E8
+F6E9
+F6EA
+F6EB
+F6EC
+F6ED
+F6EE
+F6EF
+F6F0
+F6F1
+F6F2
+F6F3
+F6F4
+F6F5
+F6F6
+F6F7
+F6F8
+F6F9
+F6FA
+F6FB
+F6FC
+F740
+F741
+F742
+F743
+F744
+F745
+F746
+F747
+F748
+F749
+F74A
+F74B
+F74C
+F74D
+F74E
+F74F
+F750
+F751
+F752
+F753
+F754
+F755
+F756
+F757
+F758
+F759
+F75A
+F75B
+F75C
+F75D
+F75E
+F75F
+F760
+F761
+F762
+F763
+F764
+F765
+F766
+F767
+F768
+F769
+F76A
+F76B
+F76C
+F76D
+F76E
+F76F
+F770
+F771
+F772
+F773
+F774
+F775
+F776
+F777
+F778
+F779
+F77A
+F77B
+F77C
+F77D
+F77E
+F780
+F781
+F782
+F783
+F784
+F785
+F786
+F787
+F788
+F789
+F78A
+F78B
+F78C
+F78D
+F78E
+F78F
+F790
+F791
+F792
+F793
+F794
+F795
+F796
+F797
+F798
+F799
+F79A
+F79B
+F79C
+F79D
+F79E
+F79F
+F7A0
+F7A1
+F7A2
+F7A3
+F7A4
+F7A5
+F7A6
+F7A7
+F7A8
+F7A9
+F7AA
+F7AB
+F7AC
+F7AD
+F7AE
+F7AF
+F7B0
+F7B1
+F7B2
+F7B3
+F7B4
+F7B5
+F7B6
+F7B7
+F7B8
+F7B9
+F7BA
+F7BB
+F7BC
+F7BD
+F7BE
+F7BF
+F7C0
+F7C1
+F7C2
+F7C3
+F7C4
+F7C5
+F7C6
+F7C7
+F7C8
+F7C9
+F7CA
+F7CB
+F7CC
+F7CD
+F7CE
+F7CF
+F7D0
+F7D1
+F7D2
+F7D3
+F7D4
+F7D5
+F7D6
+F7D7
+F7D8
+F7D9
+F7DA
+F7DB
+F7DC
+F7DD
+F7DE
+F7DF
+F7E0
+F7E1
+F7E2
+F7E3
+F7E4
+F7E5
+F7E6
+F7E7
+F7E8
+F7E9
+F7EA
+F7EB
+F7EC
+F7ED
+F7EE
+F7EF
+F7F0
+F7F1
+F7F2
+F7F3
+F7F4
+F7F5
+F7F6
+F7F7
+F7F8
+F7F9
+F7FA
+F7FB
+F7FC
+F840
+F841
+F842
+F843
+F844
+F845
+F846
+F847
+F848
+F849
+F84A
+F84B
+F84C
+F84D
+F84E
+F84F
+F850
+F851
+F852
+F853
+F854
+F855
+F856
+F857
+F858
+F859
+F85A
+F85B
+F85C
+F85D
+F85E
+F85F
+F860
+F861
+F862
+F863
+F864
+F865
+F866
+F867
+F868
+F869
+F86A
+F86B
+F86C
+F86D
+F86E
+F86F
+F870
+F871
+F872
+F873
+F874
+F875
+F876
+F877
+F878
+F879
+F87A
+F87B
+F87C
+F87D
+F87E
+F880
+F881
+F882
+F883
+F884
+F885
+F886
+F887
+F888
+F889
+F88A
+F88B
+F88C
+F88D
+F88E
+F88F
+F890
+F891
+F892
+F893
+F894
+F895
+F896
+F897
+F898
+F899
+F89A
+F89B
+F89C
+F89D
+F89E
+F89F
+F8A0
+F8A1
+F8A2
+F8A3
+F8A4
+F8A5
+F8A6
+F8A7
+F8A8
+F8A9
+F8AA
+F8AB
+F8AC
+F8AD
+F8AE
+F8AF
+F8B0
+F8B1
+F8B2
+F8B3
+F8B4
+F8B5
+F8B6
+F8B7
+F8B8
+F8B9
+F8BA
+F8BB
+F8BC
+F8BD
+F8BE
+F8BF
+F8C0
+F8C1
+F8C2
+F8C3
+F8C4
+F8C5
+F8C6
+F8C7
+F8C8
+F8C9
+F8CA
+F8CB
+F8CC
+F8CD
+F8CE
+F8CF
+F8D0
+F8D1
+F8D2
+F8D3
+F8D4
+F8D5
+F8D6
+F8D7
+F8D8
+F8D9
+F8DA
+F8DB
+F8DC
+F8DD
+F8DE
+F8DF
+F8E0
+F8E1
+F8E2
+F8E3
+F8E4
+F8E5
+F8E6
+F8E7
+F8E8
+F8E9
+F8EA
+F8EB
+F8EC
+F8ED
+F8EE
+F8EF
+F8F0
+F8F1
+F8F2
+F8F3
+F8F4
+F8F5
+F8F6
+F8F7
+F8F8
+F8F9
+F8FA
+F8FB
+F8FC
+F940
+F941
+F942
+F943
+F944
+F945
+F946
+F947
+F948
+F949
+F94A
+F94B
+F94C
+F94D
+F94E
+F94F
+F950
+F951
+F952
+F953
+F954
+F955
+F956
+F957
+F958
+F959
+F95A
+F95B
+F95C
+F95D
+F95E
+F95F
+F960
+F961
+F962
+F963
+F964
+F965
+F966
+F967
+F968
+F969
+F96A
+F96B
+F96C
+F96D
+F96E
+F96F
+F970
+F971
+F972
+F973
+F974
+F975
+F976
+F977
+F978
+F979
+F97A
+F97B
+F97C
+F97D
+F97E
+F980
+F981
+F982
+F983
+F984
+F985
+F986
+F987
+F988
+F989
+F98A
+F98B
+F98C
+F98D
+F98E
+F98F
+F990
+F991
+F992
+F993
+F994
+F995
+F996
+F997
+F998
+F999
+F99A
+F99B
+F99C
+F99D
+F99E
+F99F
+F9A0
+F9A1
+F9A2
+F9A3
+F9A4
+F9A5
+F9A6
+F9A7
+F9A8
+F9A9
+F9AA
+F9AB
+F9AC
+F9AD
+F9AE
+F9AF
+F9B0
+F9B1
+F9B2
+F9B3
+F9B4
+F9B5
+F9B6
+F9B7
+F9B8
+F9B9
+F9BA
+F9BB
+F9BC
+F9BD
+F9BE
+F9BF
+F9C0
+F9C1
+F9C2
+F9C3
+F9C4
+F9C5
+F9C6
+F9C7
+F9C8
+F9C9
+F9CA
+F9CB
+F9CC
+F9CD
+F9CE
+F9CF
+F9D0
+F9D1
+F9D2
+F9D3
+F9D4
+F9D5
+F9D6
+F9D7
+F9D8
+F9D9
+F9DA
+F9DB
+F9DC
+F9DD
+F9DE
+F9DF
+F9E0
+F9E1
+F9E2
+F9E3
+F9E4
+F9E5
+F9E6
+F9E7
+F9E8
+F9E9
+F9EA
+F9EB
+F9EC
+F9ED
+F9EE
+F9EF
+F9F0
+F9F1
+F9F2
+F9F3
+F9F4
+F9F5
+F9F6
+F9F7
+F9F8
+F9F9
+F9FA
+F9FB
+F9FC
+CREATE TABLE t2 SELECT CONVERT(c1 USING ucs2) AS c1 FROM t1;
+SELECT HEX(c1) FROM t2;
+HEX(c1)
+0005
+007E
+2015
+FF3C
+FF5E
+2225
+FF0D
+FFE0
+FFE1
+FFE2
+2460
+2461
+2462
+2463
+2464
+2465
+2466
+2467
+2468
+2469
+246A
+246B
+246C
+246D
+246E
+246F
+2470
+2471
+2472
+2473
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+3349
+3314
+3322
+334D
+3318
+3327
+3303
+3336
+3351
+3357
+330D
+3326
+3323
+332B
+334A
+333B
+339C
+339D
+339E
+338E
+338F
+33C4
+33A1
+337B
+301D
+301F
+2116
+33CD
+2121
+32A4
+32A5
+32A6
+32A7
+32A8
+3231
+3232
+3239
+337E
+337D
+337C
+2252
+2261
+222B
+222E
+2211
+221A
+22A5
+2220
+221F
+22BF
+2235
+2229
+222A
+7E8A
+891C
+9348
+9288
+84DC
+4FC9
+70BB
+6631
+68C8
+92F9
+66FB
+5F45
+4E28
+4EE1
+4EFC
+4F00
+4F03
+4F39
+4F56
+4F92
+4F8A
+4F9A
+4F94
+4FCD
+5040
+5022
+4FFF
+501E
+5046
+5070
+5042
+5094
+50F4
+50D8
+514A
+5164
+519D
+51BE
+51EC
+5215
+529C
+52A6
+52C0
+52DB
+5300
+5307
+5324
+5372
+5393
+53B2
+53DD
+FA0E
+549C
+548A
+54A9
+54FF
+5586
+5759
+5765
+57AC
+57C8
+57C7
+FA0F
+FA10
+589E
+58B2
+590B
+5953
+595B
+595D
+5963
+59A4
+59BA
+5B56
+5BC0
+752F
+5BD8
+5BEC
+5C1E
+5CA6
+5CBA
+5CF5
+5D27
+5D53
+FA11
+5D42
+5D6D
+5DB8
+5DB9
+5DD0
+5F21
+5F34
+5F67
+5FB7
+5FDE
+605D
+6085
+608A
+60DE
+60D5
+6120
+60F2
+6111
+6137
+6130
+6198
+6213
+62A6
+63F5
+6460
+649D
+64CE
+654E
+6600
+6615
+663B
+6609
+662E
+661E
+6624
+6665
+6657
+6659
+FA12
+6673
+6699
+66A0
+66B2
+66BF
+66FA
+670E
+F929
+6766
+67BB
+6852
+67C0
+6801
+6844
+68CF
+FA13
+6968
+FA14
+6998
+69E2
+6A30
+6A6B
+6A46
+6A73
+6A7E
+6AE2
+6AE4
+6BD6
+6C3F
+6C5C
+6C86
+6C6F
+6CDA
+6D04
+6D87
+6D6F
+6D96
+6DAC
+6DCF
+6DF8
+6DF2
+6DFC
+6E39
+6E5C
+6E27
+6E3C
+6EBF
+6F88
+6FB5
+6FF5
+7005
+7007
+7028
+7085
+70AB
+710F
+7104
+715C
+7146
+7147
+FA15
+71C1
+71FE
+72B1
+72BE
+7324
+FA16
+7377
+73BD
+73C9
+73D6
+73E3
+73D2
+7407
+73F5
+7426
+742A
+7429
+742E
+7462
+7489
+749F
+7501
+756F
+7682
+769C
+769E
+769B
+76A6
+FA17
+7746
+52AF
+7821
+784E
+7864
+787A
+7930
+FA18
+FA19
+FA1A
+7994
+FA1B
+799B
+7AD1
+7AE7
+FA1C
+7AEB
+7B9E
+FA1D
+7D48
+7D5C
+7DB7
+7DA0
+7DD6
+7E52
+7F47
+7FA1
+FA1E
+8301
+8362
+837F
+83C7
+83F6
+8448
+84B4
+8553
+8559
+856B
+FA1F
+85B0
+FA20
+FA21
+8807
+88F5
+8A12
+8A37
+8A79
+8AA7
+8ABE
+8ADF
+FA22
+8AF6
+8B53
+8B7F
+8CF0
+8CF4
+8D12
+8D76
+FA23
+8ECF
+FA24
+FA25
+9067
+90DE
+FA26
+9115
+9127
+91DA
+91D7
+91DE
+91ED
+91EE
+91E4
+91E5
+9206
+9210
+920A
+923A
+9240
+923C
+924E
+9259
+9251
+9239
+9267
+92A7
+9277
+9278
+92E7
+92D7
+92D9
+92D0
+FA27
+92D5
+92E0
+92D3
+9325
+9321
+92FB
+FA28
+931E
+92FF
+931D
+9302
+9370
+9357
+93A4
+93C6
+93DE
+93F8
+9431
+9445
+9448
+9592
+F9DC
+FA29
+969D
+96AF
+9733
+973B
+9743
+974D
+974F
+9751
+9755
+9857
+9865
+FA2A
+FA2B
+9927
+FA2C
+999E
+9A4E
+9AD9
+9ADC
+9B75
+9B72
+9B8F
+9BB1
+9BBB
+9C00
+9D70
+9D6B
+FA2D
+9E19
+9ED1
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+FFE2
+FFE4
+FF07
+FF02
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+FFE2
+FFE4
+FF07
+FF02
+3231
+2116
+2121
+2235
+7E8A
+891C
+9348
+9288
+84DC
+4FC9
+70BB
+6631
+68C8
+92F9
+66FB
+5F45
+4E28
+4EE1
+4EFC
+4F00
+4F03
+4F39
+4F56
+4F92
+4F8A
+4F9A
+4F94
+4FCD
+5040
+5022
+4FFF
+501E
+5046
+5070
+5042
+5094
+50F4
+50D8
+514A
+5164
+519D
+51BE
+51EC
+5215
+529C
+52A6
+52C0
+52DB
+5300
+5307
+5324
+5372
+5393
+53B2
+53DD
+FA0E
+549C
+548A
+54A9
+54FF
+5586
+5759
+5765
+57AC
+57C8
+57C7
+FA0F
+FA10
+589E
+58B2
+590B
+5953
+595B
+595D
+5963
+59A4
+59BA
+5B56
+5BC0
+752F
+5BD8
+5BEC
+5C1E
+5CA6
+5CBA
+5CF5
+5D27
+5D53
+FA11
+5D42
+5D6D
+5DB8
+5DB9
+5DD0
+5F21
+5F34
+5F67
+5FB7
+5FDE
+605D
+6085
+608A
+60DE
+60D5
+6120
+60F2
+6111
+6137
+6130
+6198
+6213
+62A6
+63F5
+6460
+649D
+64CE
+654E
+6600
+6615
+663B
+6609
+662E
+661E
+6624
+6665
+6657
+6659
+FA12
+6673
+6699
+66A0
+66B2
+66BF
+66FA
+670E
+F929
+6766
+67BB
+6852
+67C0
+6801
+6844
+68CF
+FA13
+6968
+FA14
+6998
+69E2
+6A30
+6A6B
+6A46
+6A73
+6A7E
+6AE2
+6AE4
+6BD6
+6C3F
+6C5C
+6C86
+6C6F
+6CDA
+6D04
+6D87
+6D6F
+6D96
+6DAC
+6DCF
+6DF8
+6DF2
+6DFC
+6E39
+6E5C
+6E27
+6E3C
+6EBF
+6F88
+6FB5
+6FF5
+7005
+7007
+7028
+7085
+70AB
+710F
+7104
+715C
+7146
+7147
+FA15
+71C1
+71FE
+72B1
+72BE
+7324
+FA16
+7377
+73BD
+73C9
+73D6
+73E3
+73D2
+7407
+73F5
+7426
+742A
+7429
+742E
+7462
+7489
+749F
+7501
+756F
+7682
+769C
+769E
+769B
+76A6
+FA17
+7746
+52AF
+7821
+784E
+7864
+787A
+7930
+FA18
+FA19
+FA1A
+7994
+FA1B
+799B
+7AD1
+7AE7
+FA1C
+7AEB
+7B9E
+FA1D
+7D48
+7D5C
+7DB7
+7DA0
+7DD6
+7E52
+7F47
+7FA1
+FA1E
+8301
+8362
+837F
+83C7
+83F6
+8448
+84B4
+8553
+8559
+856B
+FA1F
+85B0
+FA20
+FA21
+8807
+88F5
+8A12
+8A37
+8A79
+8AA7
+8ABE
+8ADF
+FA22
+8AF6
+8B53
+8B7F
+8CF0
+8CF4
+8D12
+8D76
+FA23
+8ECF
+FA24
+FA25
+9067
+90DE
+FA26
+9115
+9127
+91DA
+91D7
+91DE
+91ED
+91EE
+91E4
+91E5
+9206
+9210
+920A
+923A
+9240
+923C
+924E
+9259
+9251
+9239
+9267
+92A7
+9277
+9278
+92E7
+92D7
+92D9
+92D0
+FA27
+92D5
+92E0
+92D3
+9325
+9321
+92FB
+FA28
+931E
+92FF
+931D
+9302
+9370
+9357
+93A4
+93C6
+93DE
+93F8
+9431
+9445
+9448
+9592
+F9DC
+FA29
+969D
+96AF
+9733
+973B
+9743
+974D
+974F
+9751
+9755
+9857
+9865
+FA2A
+FA2B
+9927
+FA2C
+999E
+9A4E
+9AD9
+9ADC
+9B75
+9B72
+9B8F
+9BB1
+9BBB
+9C00
+9D70
+9D6B
+FA2D
+9E19
+9ED1
+E000
+E001
+E002
+E003
+E004
+E005
+E006
+E007
+E008
+E009
+E00A
+E00B
+E00C
+E00D
+E00E
+E00F
+E010
+E011
+E012
+E013
+E014
+E015
+E016
+E017
+E018
+E019
+E01A
+E01B
+E01C
+E01D
+E01E
+E01F
+E020
+E021
+E022
+E023
+E024
+E025
+E026
+E027
+E028
+E029
+E02A
+E02B
+E02C
+E02D
+E02E
+E02F
+E030
+E031
+E032
+E033
+E034
+E035
+E036
+E037
+E038
+E039
+E03A
+E03B
+E03C
+E03D
+E03E
+E03F
+E040
+E041
+E042
+E043
+E044
+E045
+E046
+E047
+E048
+E049
+E04A
+E04B
+E04C
+E04D
+E04E
+E04F
+E050
+E051
+E052
+E053
+E054
+E055
+E056
+E057
+E058
+E059
+E05A
+E05B
+E05C
+E05D
+E05E
+E05F
+E060
+E061
+E062
+E063
+E064
+E065
+E066
+E067
+E068
+E069
+E06A
+E06B
+E06C
+E06D
+E06E
+E06F
+E070
+E071
+E072
+E073
+E074
+E075
+E076
+E077
+E078
+E079
+E07A
+E07B
+E07C
+E07D
+E07E
+E07F
+E080
+E081
+E082
+E083
+E084
+E085
+E086
+E087
+E088
+E089
+E08A
+E08B
+E08C
+E08D
+E08E
+E08F
+E090
+E091
+E092
+E093
+E094
+E095
+E096
+E097
+E098
+E099
+E09A
+E09B
+E09C
+E09D
+E09E
+E09F
+E0A0
+E0A1
+E0A2
+E0A3
+E0A4
+E0A5
+E0A6
+E0A7
+E0A8
+E0A9
+E0AA
+E0AB
+E0AC
+E0AD
+E0AE
+E0AF
+E0B0
+E0B1
+E0B2
+E0B3
+E0B4
+E0B5
+E0B6
+E0B7
+E0B8
+E0B9
+E0BA
+E0BB
+E0BC
+E0BD
+E0BE
+E0BF
+E0C0
+E0C1
+E0C2
+E0C3
+E0C4
+E0C5
+E0C6
+E0C7
+E0C8
+E0C9
+E0CA
+E0CB
+E0CC
+E0CD
+E0CE
+E0CF
+E0D0
+E0D1
+E0D2
+E0D3
+E0D4
+E0D5
+E0D6
+E0D7
+E0D8
+E0D9
+E0DA
+E0DB
+E0DC
+E0DD
+E0DE
+E0DF
+E0E0
+E0E1
+E0E2
+E0E3
+E0E4
+E0E5
+E0E6
+E0E7
+E0E8
+E0E9
+E0EA
+E0EB
+E0EC
+E0ED
+E0EE
+E0EF
+E0F0
+E0F1
+E0F2
+E0F3
+E0F4
+E0F5
+E0F6
+E0F7
+E0F8
+E0F9
+E0FA
+E0FB
+E0FC
+E0FD
+E0FE
+E0FF
+E100
+E101
+E102
+E103
+E104
+E105
+E106
+E107
+E108
+E109
+E10A
+E10B
+E10C
+E10D
+E10E
+E10F
+E110
+E111
+E112
+E113
+E114
+E115
+E116
+E117
+E118
+E119
+E11A
+E11B
+E11C
+E11D
+E11E
+E11F
+E120
+E121
+E122
+E123
+E124
+E125
+E126
+E127
+E128
+E129
+E12A
+E12B
+E12C
+E12D
+E12E
+E12F
+E130
+E131
+E132
+E133
+E134
+E135
+E136
+E137
+E138
+E139
+E13A
+E13B
+E13C
+E13D
+E13E
+E13F
+E140
+E141
+E142
+E143
+E144
+E145
+E146
+E147
+E148
+E149
+E14A
+E14B
+E14C
+E14D
+E14E
+E14F
+E150
+E151
+E152
+E153
+E154
+E155
+E156
+E157
+E158
+E159
+E15A
+E15B
+E15C
+E15D
+E15E
+E15F
+E160
+E161
+E162
+E163
+E164
+E165
+E166
+E167
+E168
+E169
+E16A
+E16B
+E16C
+E16D
+E16E
+E16F
+E170
+E171
+E172
+E173
+E174
+E175
+E176
+E177
+E178
+E179
+E17A
+E17B
+E17C
+E17D
+E17E
+E17F
+E180
+E181
+E182
+E183
+E184
+E185
+E186
+E187
+E188
+E189
+E18A
+E18B
+E18C
+E18D
+E18E
+E18F
+E190
+E191
+E192
+E193
+E194
+E195
+E196
+E197
+E198
+E199
+E19A
+E19B
+E19C
+E19D
+E19E
+E19F
+E1A0
+E1A1
+E1A2
+E1A3
+E1A4
+E1A5
+E1A6
+E1A7
+E1A8
+E1A9
+E1AA
+E1AB
+E1AC
+E1AD
+E1AE
+E1AF
+E1B0
+E1B1
+E1B2
+E1B3
+E1B4
+E1B5
+E1B6
+E1B7
+E1B8
+E1B9
+E1BA
+E1BB
+E1BC
+E1BD
+E1BE
+E1BF
+E1C0
+E1C1
+E1C2
+E1C3
+E1C4
+E1C5
+E1C6
+E1C7
+E1C8
+E1C9
+E1CA
+E1CB
+E1CC
+E1CD
+E1CE
+E1CF
+E1D0
+E1D1
+E1D2
+E1D3
+E1D4
+E1D5
+E1D6
+E1D7
+E1D8
+E1D9
+E1DA
+E1DB
+E1DC
+E1DD
+E1DE
+E1DF
+E1E0
+E1E1
+E1E2
+E1E3
+E1E4
+E1E5
+E1E6
+E1E7
+E1E8
+E1E9
+E1EA
+E1EB
+E1EC
+E1ED
+E1EE
+E1EF
+E1F0
+E1F1
+E1F2
+E1F3
+E1F4
+E1F5
+E1F6
+E1F7
+E1F8
+E1F9
+E1FA
+E1FB
+E1FC
+E1FD
+E1FE
+E1FF
+E200
+E201
+E202
+E203
+E204
+E205
+E206
+E207
+E208
+E209
+E20A
+E20B
+E20C
+E20D
+E20E
+E20F
+E210
+E211
+E212
+E213
+E214
+E215
+E216
+E217
+E218
+E219
+E21A
+E21B
+E21C
+E21D
+E21E
+E21F
+E220
+E221
+E222
+E223
+E224
+E225
+E226
+E227
+E228
+E229
+E22A
+E22B
+E22C
+E22D
+E22E
+E22F
+E230
+E231
+E232
+E233
+E234
+E235
+E236
+E237
+E238
+E239
+E23A
+E23B
+E23C
+E23D
+E23E
+E23F
+E240
+E241
+E242
+E243
+E244
+E245
+E246
+E247
+E248
+E249
+E24A
+E24B
+E24C
+E24D
+E24E
+E24F
+E250
+E251
+E252
+E253
+E254
+E255
+E256
+E257
+E258
+E259
+E25A
+E25B
+E25C
+E25D
+E25E
+E25F
+E260
+E261
+E262
+E263
+E264
+E265
+E266
+E267
+E268
+E269
+E26A
+E26B
+E26C
+E26D
+E26E
+E26F
+E270
+E271
+E272
+E273
+E274
+E275
+E276
+E277
+E278
+E279
+E27A
+E27B
+E27C
+E27D
+E27E
+E27F
+E280
+E281
+E282
+E283
+E284
+E285
+E286
+E287
+E288
+E289
+E28A
+E28B
+E28C
+E28D
+E28E
+E28F
+E290
+E291
+E292
+E293
+E294
+E295
+E296
+E297
+E298
+E299
+E29A
+E29B
+E29C
+E29D
+E29E
+E29F
+E2A0
+E2A1
+E2A2
+E2A3
+E2A4
+E2A5
+E2A6
+E2A7
+E2A8
+E2A9
+E2AA
+E2AB
+E2AC
+E2AD
+E2AE
+E2AF
+E2B0
+E2B1
+E2B2
+E2B3
+E2B4
+E2B5
+E2B6
+E2B7
+E2B8
+E2B9
+E2BA
+E2BB
+E2BC
+E2BD
+E2BE
+E2BF
+E2C0
+E2C1
+E2C2
+E2C3
+E2C4
+E2C5
+E2C6
+E2C7
+E2C8
+E2C9
+E2CA
+E2CB
+E2CC
+E2CD
+E2CE
+E2CF
+E2D0
+E2D1
+E2D2
+E2D3
+E2D4
+E2D5
+E2D6
+E2D7
+E2D8
+E2D9
+E2DA
+E2DB
+E2DC
+E2DD
+E2DE
+E2DF
+E2E0
+E2E1
+E2E2
+E2E3
+E2E4
+E2E5
+E2E6
+E2E7
+E2E8
+E2E9
+E2EA
+E2EB
+E2EC
+E2ED
+E2EE
+E2EF
+E2F0
+E2F1
+E2F2
+E2F3
+E2F4
+E2F5
+E2F6
+E2F7
+E2F8
+E2F9
+E2FA
+E2FB
+E2FC
+E2FD
+E2FE
+E2FF
+E300
+E301
+E302
+E303
+E304
+E305
+E306
+E307
+E308
+E309
+E30A
+E30B
+E30C
+E30D
+E30E
+E30F
+E310
+E311
+E312
+E313
+E314
+E315
+E316
+E317
+E318
+E319
+E31A
+E31B
+E31C
+E31D
+E31E
+E31F
+E320
+E321
+E322
+E323
+E324
+E325
+E326
+E327
+E328
+E329
+E32A
+E32B
+E32C
+E32D
+E32E
+E32F
+E330
+E331
+E332
+E333
+E334
+E335
+E336
+E337
+E338
+E339
+E33A
+E33B
+E33C
+E33D
+E33E
+E33F
+E340
+E341
+E342
+E343
+E344
+E345
+E346
+E347
+E348
+E349
+E34A
+E34B
+E34C
+E34D
+E34E
+E34F
+E350
+E351
+E352
+E353
+E354
+E355
+E356
+E357
+E358
+E359
+E35A
+E35B
+E35C
+E35D
+E35E
+E35F
+E360
+E361
+E362
+E363
+E364
+E365
+E366
+E367
+E368
+E369
+E36A
+E36B
+E36C
+E36D
+E36E
+E36F
+E370
+E371
+E372
+E373
+E374
+E375
+E376
+E377
+E378
+E379
+E37A
+E37B
+E37C
+E37D
+E37E
+E37F
+E380
+E381
+E382
+E383
+E384
+E385
+E386
+E387
+E388
+E389
+E38A
+E38B
+E38C
+E38D
+E38E
+E38F
+E390
+E391
+E392
+E393
+E394
+E395
+E396
+E397
+E398
+E399
+E39A
+E39B
+E39C
+E39D
+E39E
+E39F
+E3A0
+E3A1
+E3A2
+E3A3
+E3A4
+E3A5
+E3A6
+E3A7
+E3A8
+E3A9
+E3AA
+E3AB
+E3AC
+E3AD
+E3AE
+E3AF
+E3B0
+E3B1
+E3B2
+E3B3
+E3B4
+E3B5
+E3B6
+E3B7
+E3B8
+E3B9
+E3BA
+E3BB
+E3BC
+E3BD
+E3BE
+E3BF
+E3C0
+E3C1
+E3C2
+E3C3
+E3C4
+E3C5
+E3C6
+E3C7
+E3C8
+E3C9
+E3CA
+E3CB
+E3CC
+E3CD
+E3CE
+E3CF
+E3D0
+E3D1
+E3D2
+E3D3
+E3D4
+E3D5
+E3D6
+E3D7
+E3D8
+E3D9
+E3DA
+E3DB
+E3DC
+E3DD
+E3DE
+E3DF
+E3E0
+E3E1
+E3E2
+E3E3
+E3E4
+E3E5
+E3E6
+E3E7
+E3E8
+E3E9
+E3EA
+E3EB
+E3EC
+E3ED
+E3EE
+E3EF
+E3F0
+E3F1
+E3F2
+E3F3
+E3F4
+E3F5
+E3F6
+E3F7
+E3F8
+E3F9
+E3FA
+E3FB
+E3FC
+E3FD
+E3FE
+E3FF
+E400
+E401
+E402
+E403
+E404
+E405
+E406
+E407
+E408
+E409
+E40A
+E40B
+E40C
+E40D
+E40E
+E40F
+E410
+E411
+E412
+E413
+E414
+E415
+E416
+E417
+E418
+E419
+E41A
+E41B
+E41C
+E41D
+E41E
+E41F
+E420
+E421
+E422
+E423
+E424
+E425
+E426
+E427
+E428
+E429
+E42A
+E42B
+E42C
+E42D
+E42E
+E42F
+E430
+E431
+E432
+E433
+E434
+E435
+E436
+E437
+E438
+E439
+E43A
+E43B
+E43C
+E43D
+E43E
+E43F
+E440
+E441
+E442
+E443
+E444
+E445
+E446
+E447
+E448
+E449
+E44A
+E44B
+E44C
+E44D
+E44E
+E44F
+E450
+E451
+E452
+E453
+E454
+E455
+E456
+E457
+E458
+E459
+E45A
+E45B
+E45C
+E45D
+E45E
+E45F
+E460
+E461
+E462
+E463
+E464
+E465
+E466
+E467
+E468
+E469
+E46A
+E46B
+E46C
+E46D
+E46E
+E46F
+E470
+E471
+E472
+E473
+E474
+E475
+E476
+E477
+E478
+E479
+E47A
+E47B
+E47C
+E47D
+E47E
+E47F
+E480
+E481
+E482
+E483
+E484
+E485
+E486
+E487
+E488
+E489
+E48A
+E48B
+E48C
+E48D
+E48E
+E48F
+E490
+E491
+E492
+E493
+E494
+E495
+E496
+E497
+E498
+E499
+E49A
+E49B
+E49C
+E49D
+E49E
+E49F
+E4A0
+E4A1
+E4A2
+E4A3
+E4A4
+E4A5
+E4A6
+E4A7
+E4A8
+E4A9
+E4AA
+E4AB
+E4AC
+E4AD
+E4AE
+E4AF
+E4B0
+E4B1
+E4B2
+E4B3
+E4B4
+E4B5
+E4B6
+E4B7
+E4B8
+E4B9
+E4BA
+E4BB
+E4BC
+E4BD
+E4BE
+E4BF
+E4C0
+E4C1
+E4C2
+E4C3
+E4C4
+E4C5
+E4C6
+E4C7
+E4C8
+E4C9
+E4CA
+E4CB
+E4CC
+E4CD
+E4CE
+E4CF
+E4D0
+E4D1
+E4D2
+E4D3
+E4D4
+E4D5
+E4D6
+E4D7
+E4D8
+E4D9
+E4DA
+E4DB
+E4DC
+E4DD
+E4DE
+E4DF
+E4E0
+E4E1
+E4E2
+E4E3
+E4E4
+E4E5
+E4E6
+E4E7
+E4E8
+E4E9
+E4EA
+E4EB
+E4EC
+E4ED
+E4EE
+E4EF
+E4F0
+E4F1
+E4F2
+E4F3
+E4F4
+E4F5
+E4F6
+E4F7
+E4F8
+E4F9
+E4FA
+E4FB
+E4FC
+E4FD
+E4FE
+E4FF
+E500
+E501
+E502
+E503
+E504
+E505
+E506
+E507
+E508
+E509
+E50A
+E50B
+E50C
+E50D
+E50E
+E50F
+E510
+E511
+E512
+E513
+E514
+E515
+E516
+E517
+E518
+E519
+E51A
+E51B
+E51C
+E51D
+E51E
+E51F
+E520
+E521
+E522
+E523
+E524
+E525
+E526
+E527
+E528
+E529
+E52A
+E52B
+E52C
+E52D
+E52E
+E52F
+E530
+E531
+E532
+E533
+E534
+E535
+E536
+E537
+E538
+E539
+E53A
+E53B
+E53C
+E53D
+E53E
+E53F
+E540
+E541
+E542
+E543
+E544
+E545
+E546
+E547
+E548
+E549
+E54A
+E54B
+E54C
+E54D
+E54E
+E54F
+E550
+E551
+E552
+E553
+E554
+E555
+E556
+E557
+E558
+E559
+E55A
+E55B
+E55C
+E55D
+E55E
+E55F
+E560
+E561
+E562
+E563
+E564
+E565
+E566
+E567
+E568
+E569
+E56A
+E56B
+E56C
+E56D
+E56E
+E56F
+E570
+E571
+E572
+E573
+E574
+E575
+E576
+E577
+E578
+E579
+E57A
+E57B
+E57C
+E57D
+E57E
+E57F
+E580
+E581
+E582
+E583
+E584
+E585
+E586
+E587
+E588
+E589
+E58A
+E58B
+E58C
+E58D
+E58E
+E58F
+E590
+E591
+E592
+E593
+E594
+E595
+E596
+E597
+E598
+E599
+E59A
+E59B
+E59C
+E59D
+E59E
+E59F
+E5A0
+E5A1
+E5A2
+E5A3
+E5A4
+E5A5
+E5A6
+E5A7
+E5A8
+E5A9
+E5AA
+E5AB
+E5AC
+E5AD
+E5AE
+E5AF
+E5B0
+E5B1
+E5B2
+E5B3
+E5B4
+E5B5
+E5B6
+E5B7
+E5B8
+E5B9
+E5BA
+E5BB
+E5BC
+E5BD
+E5BE
+E5BF
+E5C0
+E5C1
+E5C2
+E5C3
+E5C4
+E5C5
+E5C6
+E5C7
+E5C8
+E5C9
+E5CA
+E5CB
+E5CC
+E5CD
+E5CE
+E5CF
+E5D0
+E5D1
+E5D2
+E5D3
+E5D4
+E5D5
+E5D6
+E5D7
+E5D8
+E5D9
+E5DA
+E5DB
+E5DC
+E5DD
+E5DE
+E5DF
+E5E0
+E5E1
+E5E2
+E5E3
+E5E4
+E5E5
+E5E6
+E5E7
+E5E8
+E5E9
+E5EA
+E5EB
+E5EC
+E5ED
+E5EE
+E5EF
+E5F0
+E5F1
+E5F2
+E5F3
+E5F4
+E5F5
+E5F6
+E5F7
+E5F8
+E5F9
+E5FA
+E5FB
+E5FC
+E5FD
+E5FE
+E5FF
+E600
+E601
+E602
+E603
+E604
+E605
+E606
+E607
+E608
+E609
+E60A
+E60B
+E60C
+E60D
+E60E
+E60F
+E610
+E611
+E612
+E613
+E614
+E615
+E616
+E617
+E618
+E619
+E61A
+E61B
+E61C
+E61D
+E61E
+E61F
+E620
+E621
+E622
+E623
+E624
+E625
+E626
+E627
+E628
+E629
+E62A
+E62B
+E62C
+E62D
+E62E
+E62F
+E630
+E631
+E632
+E633
+E634
+E635
+E636
+E637
+E638
+E639
+E63A
+E63B
+E63C
+E63D
+E63E
+E63F
+E640
+E641
+E642
+E643
+E644
+E645
+E646
+E647
+E648
+E649
+E64A
+E64B
+E64C
+E64D
+E64E
+E64F
+E650
+E651
+E652
+E653
+E654
+E655
+E656
+E657
+E658
+E659
+E65A
+E65B
+E65C
+E65D
+E65E
+E65F
+E660
+E661
+E662
+E663
+E664
+E665
+E666
+E667
+E668
+E669
+E66A
+E66B
+E66C
+E66D
+E66E
+E66F
+E670
+E671
+E672
+E673
+E674
+E675
+E676
+E677
+E678
+E679
+E67A
+E67B
+E67C
+E67D
+E67E
+E67F
+E680
+E681
+E682
+E683
+E684
+E685
+E686
+E687
+E688
+E689
+E68A
+E68B
+E68C
+E68D
+E68E
+E68F
+E690
+E691
+E692
+E693
+E694
+E695
+E696
+E697
+E698
+E699
+E69A
+E69B
+E69C
+E69D
+E69E
+E69F
+E6A0
+E6A1
+E6A2
+E6A3
+E6A4
+E6A5
+E6A6
+E6A7
+E6A8
+E6A9
+E6AA
+E6AB
+E6AC
+E6AD
+E6AE
+E6AF
+E6B0
+E6B1
+E6B2
+E6B3
+E6B4
+E6B5
+E6B6
+E6B7
+E6B8
+E6B9
+E6BA
+E6BB
+E6BC
+E6BD
+E6BE
+E6BF
+E6C0
+E6C1
+E6C2
+E6C3
+E6C4
+E6C5
+E6C6
+E6C7
+E6C8
+E6C9
+E6CA
+E6CB
+E6CC
+E6CD
+E6CE
+E6CF
+E6D0
+E6D1
+E6D2
+E6D3
+E6D4
+E6D5
+E6D6
+E6D7
+E6D8
+E6D9
+E6DA
+E6DB
+E6DC
+E6DD
+E6DE
+E6DF
+E6E0
+E6E1
+E6E2
+E6E3
+E6E4
+E6E5
+E6E6
+E6E7
+E6E8
+E6E9
+E6EA
+E6EB
+E6EC
+E6ED
+E6EE
+E6EF
+E6F0
+E6F1
+E6F2
+E6F3
+E6F4
+E6F5
+E6F6
+E6F7
+E6F8
+E6F9
+E6FA
+E6FB
+E6FC
+E6FD
+E6FE
+E6FF
+E700
+E701
+E702
+E703
+E704
+E705
+E706
+E707
+E708
+E709
+E70A
+E70B
+E70C
+E70D
+E70E
+E70F
+E710
+E711
+E712
+E713
+E714
+E715
+E716
+E717
+E718
+E719
+E71A
+E71B
+E71C
+E71D
+E71E
+E71F
+E720
+E721
+E722
+E723
+E724
+E725
+E726
+E727
+E728
+E729
+E72A
+E72B
+E72C
+E72D
+E72E
+E72F
+E730
+E731
+E732
+E733
+E734
+E735
+E736
+E737
+E738
+E739
+E73A
+E73B
+E73C
+E73D
+E73E
+E73F
+E740
+E741
+E742
+E743
+E744
+E745
+E746
+E747
+E748
+E749
+E74A
+E74B
+E74C
+E74D
+E74E
+E74F
+E750
+E751
+E752
+E753
+E754
+E755
+E756
+E757
+CREATE TABLE t3 SELECT CONVERT(c1 USING cp932) AS c1 FROM t2;
+SELECT HEX(c1) FROM t3;
+HEX(c1)
+05
+7E
+815C
+815F
+8160
+8161
+817C
+8191
+8192
+81CA
+8740
+8741
+8742
+8743
+8744
+8745
+8746
+8747
+8748
+8749
+874A
+874B
+874C
+874D
+874E
+874F
+8750
+8751
+8752
+8753
+8754
+8755
+8756
+8757
+8758
+8759
+875A
+875B
+875C
+875D
+875F
+8760
+8761
+8762
+8763
+8764
+8765
+8766
+8767
+8768
+8769
+876A
+876B
+876C
+876D
+876E
+876F
+8770
+8771
+8772
+8773
+8774
+8775
+877E
+8780
+8781
+8782
+8783
+8784
+8785
+8786
+8787
+8788
+8789
+878A
+878B
+878C
+878D
+878E
+878F
+81E0
+81DF
+81E7
+8793
+8794
+81E3
+81DB
+81DA
+8798
+8799
+81E6
+81BF
+81BE
+FA5C
+FA5D
+FA5E
+FA5F
+FA60
+FA61
+FA62
+FA63
+FA64
+FA65
+FA66
+FA67
+FA68
+FA69
+FA6A
+FA6B
+FA6C
+FA6D
+FA6E
+FA6F
+FA70
+FA71
+FA72
+FA73
+FA74
+FA75
+FA76
+FA77
+FA78
+FA79
+FA7A
+FA7B
+FA7C
+FA7D
+FA7E
+FA80
+FA81
+FA82
+FA83
+FA84
+FA85
+FA86
+FA87
+FA88
+FA89
+FA8A
+FA8B
+FA8C
+FA8D
+FA8E
+FA8F
+FA90
+FA91
+FA92
+FA93
+FA94
+FA95
+FA96
+FA97
+FA98
+FA99
+FA9A
+FA9B
+FA9C
+FA9D
+FA9E
+FA9F
+FAA0
+FAA1
+FAA2
+FAA3
+FAA4
+FAA5
+FAA6
+FAA7
+FAA8
+FAA9
+FAAA
+FAAB
+FAAC
+FAAD
+FAAE
+FAAF
+FAB0
+FAB1
+FAB2
+FAB3
+FAB4
+FAB5
+FAB6
+FAB7
+FAB8
+FAB9
+FABA
+FABB
+FABC
+FABD
+FABE
+FABF
+FAC0
+FAC1
+FAC2
+FAC3
+FAC4
+FAC5
+FAC6
+FAC7
+FAC8
+FAC9
+FACA
+FACB
+FACC
+FACD
+FACE
+FACF
+FAD0
+FAD1
+FAD2
+FAD3
+FAD4
+FAD5
+FAD6
+FAD7
+FAD8
+FAD9
+FADA
+FADB
+FADC
+FADD
+FADE
+FADF
+FAE0
+FAE1
+FAE2
+FAE3
+FAE4
+FAE5
+FAE6
+FAE7
+FAE8
+FAE9
+FAEA
+FAEB
+FAEC
+FAED
+FAEE
+FAEF
+FAF0
+FAF1
+FAF2
+FAF3
+FAF4
+FAF5
+FAF6
+FAF7
+FAF8
+FAF9
+FAFA
+FAFB
+FAFC
+FB40
+FB41
+FB42
+FB43
+FB44
+FB45
+FB46
+FB47
+FB48
+FB49
+FB4A
+FB4B
+FB4C
+FB4D
+FB4E
+FB4F
+FB50
+FB51
+FB52
+FB53
+FB54
+FB55
+FB56
+FB57
+FB58
+FB59
+FB5A
+FB5B
+FB5C
+FB5D
+FB5E
+FB5F
+FB60
+FB61
+FB62
+FB63
+FB64
+FB65
+FB66
+FB67
+FB68
+FB69
+FB6A
+FB6B
+FB6C
+FB6D
+FB6E
+FB6F
+FB70
+FB71
+FB72
+FB73
+FB74
+FB75
+FB76
+FB77
+FB78
+FB79
+FB7A
+FB7B
+FB7C
+FB7D
+FB7E
+FB80
+FB81
+FB82
+FB83
+FB84
+FB85
+FB86
+FB87
+FB88
+FB89
+FB8A
+FB8B
+FB8C
+FB8D
+FB8E
+FB8F
+FB90
+FB91
+FB92
+FB93
+FB94
+FB95
+FB96
+FB97
+FB98
+FB99
+FB9A
+FB9B
+FB9C
+FB9D
+FB9E
+FB9F
+FBA0
+FBA1
+FBA2
+FBA3
+FBA4
+FBA5
+FBA6
+FBA7
+FBA8
+FBA9
+FBAA
+FBAB
+FBAC
+FBAD
+FBAE
+FBAF
+FBB0
+FBB1
+FBB2
+FBB3
+FBB4
+FBB5
+FBB6
+FBB7
+FBB8
+FBB9
+FBBA
+FBBB
+FBBC
+FBBD
+FBBE
+FBBF
+FBC0
+FBC1
+FBC2
+FBC3
+FBC4
+FBC5
+FBC6
+FBC7
+FBC8
+FBC9
+FBCA
+FBCB
+FBCC
+FBCD
+FBCE
+FBCF
+FBD0
+FBD1
+FBD2
+FBD3
+FBD4
+FBD5
+FBD6
+FBD7
+FBD8
+FBD9
+FBDA
+FBDB
+FBDC
+FBDD
+FBDE
+FBDF
+FBE0
+FBE1
+FBE2
+FBE3
+FBE4
+FBE5
+FBE6
+FBE7
+FBE8
+FBE9
+FBEA
+FBEB
+FBEC
+FBED
+FBEE
+FBEF
+FBF0
+FBF1
+FBF2
+FBF3
+FBF4
+FBF5
+FBF6
+FBF7
+FBF8
+FBF9
+FBFA
+FBFB
+FBFC
+FC40
+FC41
+FC42
+FC43
+FC44
+FC45
+FC46
+FC47
+FC48
+FC49
+FC4A
+FC4B
+FA40
+FA41
+FA42
+FA43
+FA44
+FA45
+FA46
+FA47
+FA48
+FA49
+81CA
+FA55
+FA56
+FA57
+FA40
+FA41
+FA42
+FA43
+FA44
+FA45
+FA46
+FA47
+FA48
+FA49
+8754
+8755
+8756
+8757
+8758
+8759
+875A
+875B
+875C
+875D
+81CA
+FA55
+FA56
+FA57
+878A
+8782
+8784
+81E6
+FA5C
+FA5D
+FA5E
+FA5F
+FA60
+FA61
+FA62
+FA63
+FA64
+FA65
+FA66
+FA67
+FA68
+FA69
+FA6A
+FA6B
+FA6C
+FA6D
+FA6E
+FA6F
+FA70
+FA71
+FA72
+FA73
+FA74
+FA75
+FA76
+FA77
+FA78
+FA79
+FA7A
+FA7B
+FA7C
+FA7D
+FA7E
+FA80
+FA81
+FA82
+FA83
+FA84
+FA85
+FA86
+FA87
+FA88
+FA89
+FA8A
+FA8B
+FA8C
+FA8D
+FA8E
+FA8F
+FA90
+FA91
+FA92
+FA93
+FA94
+FA95
+FA96
+FA97
+FA98
+FA99
+FA9A
+FA9B
+FA9C
+FA9D
+FA9E
+FA9F
+FAA0
+FAA1
+FAA2
+FAA3
+FAA4
+FAA5
+FAA6
+FAA7
+FAA8
+FAA9
+FAAA
+FAAB
+FAAC
+FAAD
+FAAE
+FAAF
+FAB0
+FAB1
+FAB2
+FAB3
+FAB4
+FAB5
+FAB6
+FAB7
+FAB8
+FAB9
+FABA
+FABB
+FABC
+FABD
+FABE
+FABF
+FAC0
+FAC1
+FAC2
+FAC3
+FAC4
+FAC5
+FAC6
+FAC7
+FAC8
+FAC9
+FACA
+FACB
+FACC
+FACD
+FACE
+FACF
+FAD0
+FAD1
+FAD2
+FAD3
+FAD4
+FAD5
+FAD6
+FAD7
+FAD8
+FAD9
+FADA
+FADB
+FADC
+FADD
+FADE
+FADF
+FAE0
+FAE1
+FAE2
+FAE3
+FAE4
+FAE5
+FAE6
+FAE7
+FAE8
+FAE9
+FAEA
+FAEB
+FAEC
+FAED
+FAEE
+FAEF
+FAF0
+FAF1
+FAF2
+FAF3
+FAF4
+FAF5
+FAF6
+FAF7
+FAF8
+FAF9
+FAFA
+FAFB
+FAFC
+FB40
+FB41
+FB42
+FB43
+FB44
+FB45
+FB46
+FB47
+FB48
+FB49
+FB4A
+FB4B
+FB4C
+FB4D
+FB4E
+FB4F
+FB50
+FB51
+FB52
+FB53
+FB54
+FB55
+FB56
+FB57
+FB58
+FB59
+FB5A
+FB5B
+FB5C
+FB5D
+FB5E
+FB5F
+FB60
+FB61
+FB62
+FB63
+FB64
+FB65
+FB66
+FB67
+FB68
+FB69
+FB6A
+FB6B
+FB6C
+FB6D
+FB6E
+FB6F
+FB70
+FB71
+FB72
+FB73
+FB74
+FB75
+FB76
+FB77
+FB78
+FB79
+FB7A
+FB7B
+FB7C
+FB7D
+FB7E
+FB80
+FB81
+FB82
+FB83
+FB84
+FB85
+FB86
+FB87
+FB88
+FB89
+FB8A
+FB8B
+FB8C
+FB8D
+FB8E
+FB8F
+FB90
+FB91
+FB92
+FB93
+FB94
+FB95
+FB96
+FB97
+FB98
+FB99
+FB9A
+FB9B
+FB9C
+FB9D
+FB9E
+FB9F
+FBA0
+FBA1
+FBA2
+FBA3
+FBA4
+FBA5
+FBA6
+FBA7
+FBA8
+FBA9
+FBAA
+FBAB
+FBAC
+FBAD
+FBAE
+FBAF
+FBB0
+FBB1
+FBB2
+FBB3
+FBB4
+FBB5
+FBB6
+FBB7
+FBB8
+FBB9
+FBBA
+FBBB
+FBBC
+FBBD
+FBBE
+FBBF
+FBC0
+FBC1
+FBC2
+FBC3
+FBC4
+FBC5
+FBC6
+FBC7
+FBC8
+FBC9
+FBCA
+FBCB
+FBCC
+FBCD
+FBCE
+FBCF
+FBD0
+FBD1
+FBD2
+FBD3
+FBD4
+FBD5
+FBD6
+FBD7
+FBD8
+FBD9
+FBDA
+FBDB
+FBDC
+FBDD
+FBDE
+FBDF
+FBE0
+FBE1
+FBE2
+FBE3
+FBE4
+FBE5
+FBE6
+FBE7
+FBE8
+FBE9
+FBEA
+FBEB
+FBEC
+FBED
+FBEE
+FBEF
+FBF0
+FBF1
+FBF2
+FBF3
+FBF4
+FBF5
+FBF6
+FBF7
+FBF8
+FBF9
+FBFA
+FBFB
+FBFC
+FC40
+FC41
+FC42
+FC43
+FC44
+FC45
+FC46
+FC47
+FC48
+FC49
+FC4A
+FC4B
+F040
+F041
+F042
+F043
+F044
+F045
+F046
+F047
+F048
+F049
+F04A
+F04B
+F04C
+F04D
+F04E
+F04F
+F050
+F051
+F052
+F053
+F054
+F055
+F056
+F057
+F058
+F059
+F05A
+F05B
+F05C
+F05D
+F05E
+F05F
+F060
+F061
+F062
+F063
+F064
+F065
+F066
+F067
+F068
+F069
+F06A
+F06B
+F06C
+F06D
+F06E
+F06F
+F070
+F071
+F072
+F073
+F074
+F075
+F076
+F077
+F078
+F079
+F07A
+F07B
+F07C
+F07D
+F07E
+F080
+F081
+F082
+F083
+F084
+F085
+F086
+F087
+F088
+F089
+F08A
+F08B
+F08C
+F08D
+F08E
+F08F
+F090
+F091
+F092
+F093
+F094
+F095
+F096
+F097
+F098
+F099
+F09A
+F09B
+F09C
+F09D
+F09E
+F09F
+F0A0
+F0A1
+F0A2
+F0A3
+F0A4
+F0A5
+F0A6
+F0A7
+F0A8
+F0A9
+F0AA
+F0AB
+F0AC
+F0AD
+F0AE
+F0AF
+F0B0
+F0B1
+F0B2
+F0B3
+F0B4
+F0B5
+F0B6
+F0B7
+F0B8
+F0B9
+F0BA
+F0BB
+F0BC
+F0BD
+F0BE
+F0BF
+F0C0
+F0C1
+F0C2
+F0C3
+F0C4
+F0C5
+F0C6
+F0C7
+F0C8
+F0C9
+F0CA
+F0CB
+F0CC
+F0CD
+F0CE
+F0CF
+F0D0
+F0D1
+F0D2
+F0D3
+F0D4
+F0D5
+F0D6
+F0D7
+F0D8
+F0D9
+F0DA
+F0DB
+F0DC
+F0DD
+F0DE
+F0DF
+F0E0
+F0E1
+F0E2
+F0E3
+F0E4
+F0E5
+F0E6
+F0E7
+F0E8
+F0E9
+F0EA
+F0EB
+F0EC
+F0ED
+F0EE
+F0EF
+F0F0
+F0F1
+F0F2
+F0F3
+F0F4
+F0F5
+F0F6
+F0F7
+F0F8
+F0F9
+F0FA
+F0FB
+F0FC
+F140
+F141
+F142
+F143
+F144
+F145
+F146
+F147
+F148
+F149
+F14A
+F14B
+F14C
+F14D
+F14E
+F14F
+F150
+F151
+F152
+F153
+F154
+F155
+F156
+F157
+F158
+F159
+F15A
+F15B
+F15C
+F15D
+F15E
+F15F
+F160
+F161
+F162
+F163
+F164
+F165
+F166
+F167
+F168
+F169
+F16A
+F16B
+F16C
+F16D
+F16E
+F16F
+F170
+F171
+F172
+F173
+F174
+F175
+F176
+F177
+F178
+F179
+F17A
+F17B
+F17C
+F17D
+F17E
+F180
+F181
+F182
+F183
+F184
+F185
+F186
+F187
+F188
+F189
+F18A
+F18B
+F18C
+F18D
+F18E
+F18F
+F190
+F191
+F192
+F193
+F194
+F195
+F196
+F197
+F198
+F199
+F19A
+F19B
+F19C
+F19D
+F19E
+F19F
+F1A0
+F1A1
+F1A2
+F1A3
+F1A4
+F1A5
+F1A6
+F1A7
+F1A8
+F1A9
+F1AA
+F1AB
+F1AC
+F1AD
+F1AE
+F1AF
+F1B0
+F1B1
+F1B2
+F1B3
+F1B4
+F1B5
+F1B6
+F1B7
+F1B8
+F1B9
+F1BA
+F1BB
+F1BC
+F1BD
+F1BE
+F1BF
+F1C0
+F1C1
+F1C2
+F1C3
+F1C4
+F1C5
+F1C6
+F1C7
+F1C8
+F1C9
+F1CA
+F1CB
+F1CC
+F1CD
+F1CE
+F1CF
+F1D0
+F1D1
+F1D2
+F1D3
+F1D4
+F1D5
+F1D6
+F1D7
+F1D8
+F1D9
+F1DA
+F1DB
+F1DC
+F1DD
+F1DE
+F1DF
+F1E0
+F1E1
+F1E2
+F1E3
+F1E4
+F1E5
+F1E6
+F1E7
+F1E8
+F1E9
+F1EA
+F1EB
+F1EC
+F1ED
+F1EE
+F1EF
+F1F0
+F1F1
+F1F2
+F1F3
+F1F4
+F1F5
+F1F6
+F1F7
+F1F8
+F1F9
+F1FA
+F1FB
+F1FC
+F240
+F241
+F242
+F243
+F244
+F245
+F246
+F247
+F248
+F249
+F24A
+F24B
+F24C
+F24D
+F24E
+F24F
+F250
+F251
+F252
+F253
+F254
+F255
+F256
+F257
+F258
+F259
+F25A
+F25B
+F25C
+F25D
+F25E
+F25F
+F260
+F261
+F262
+F263
+F264
+F265
+F266
+F267
+F268
+F269
+F26A
+F26B
+F26C
+F26D
+F26E
+F26F
+F270
+F271
+F272
+F273
+F274
+F275
+F276
+F277
+F278
+F279
+F27A
+F27B
+F27C
+F27D
+F27E
+F280
+F281
+F282
+F283
+F284
+F285
+F286
+F287
+F288
+F289
+F28A
+F28B
+F28C
+F28D
+F28E
+F28F
+F290
+F291
+F292
+F293
+F294
+F295
+F296
+F297
+F298
+F299
+F29A
+F29B
+F29C
+F29D
+F29E
+F29F
+F2A0
+F2A1
+F2A2
+F2A3
+F2A4
+F2A5
+F2A6
+F2A7
+F2A8
+F2A9
+F2AA
+F2AB
+F2AC
+F2AD
+F2AE
+F2AF
+F2B0
+F2B1
+F2B2
+F2B3
+F2B4
+F2B5
+F2B6
+F2B7
+F2B8
+F2B9
+F2BA
+F2BB
+F2BC
+F2BD
+F2BE
+F2BF
+F2C0
+F2C1
+F2C2
+F2C3
+F2C4
+F2C5
+F2C6
+F2C7
+F2C8
+F2C9
+F2CA
+F2CB
+F2CC
+F2CD
+F2CE
+F2CF
+F2D0
+F2D1
+F2D2
+F2D3
+F2D4
+F2D5
+F2D6
+F2D7
+F2D8
+F2D9
+F2DA
+F2DB
+F2DC
+F2DD
+F2DE
+F2DF
+F2E0
+F2E1
+F2E2
+F2E3
+F2E4
+F2E5
+F2E6
+F2E7
+F2E8
+F2E9
+F2EA
+F2EB
+F2EC
+F2ED
+F2EE
+F2EF
+F2F0
+F2F1
+F2F2
+F2F3
+F2F4
+F2F5
+F2F6
+F2F7
+F2F8
+F2F9
+F2FA
+F2FB
+F2FC
+F340
+F341
+F342
+F343
+F344
+F345
+F346
+F347
+F348
+F349
+F34A
+F34B
+F34C
+F34D
+F34E
+F34F
+F350
+F351
+F352
+F353
+F354
+F355
+F356
+F357
+F358
+F359
+F35A
+F35B
+F35C
+F35D
+F35E
+F35F
+F360
+F361
+F362
+F363
+F364
+F365
+F366
+F367
+F368
+F369
+F36A
+F36B
+F36C
+F36D
+F36E
+F36F
+F370
+F371
+F372
+F373
+F374
+F375
+F376
+F377
+F378
+F379
+F37A
+F37B
+F37C
+F37D
+F37E
+F380
+F381
+F382
+F383
+F384
+F385
+F386
+F387
+F388
+F389
+F38A
+F38B
+F38C
+F38D
+F38E
+F38F
+F390
+F391
+F392
+F393
+F394
+F395
+F396
+F397
+F398
+F399
+F39A
+F39B
+F39C
+F39D
+F39E
+F39F
+F3A0
+F3A1
+F3A2
+F3A3
+F3A4
+F3A5
+F3A6
+F3A7
+F3A8
+F3A9
+F3AA
+F3AB
+F3AC
+F3AD
+F3AE
+F3AF
+F3B0
+F3B1
+F3B2
+F3B3
+F3B4
+F3B5
+F3B6
+F3B7
+F3B8
+F3B9
+F3BA
+F3BB
+F3BC
+F3BD
+F3BE
+F3BF
+F3C0
+F3C1
+F3C2
+F3C3
+F3C4
+F3C5
+F3C6
+F3C7
+F3C8
+F3C9
+F3CA
+F3CB
+F3CC
+F3CD
+F3CE
+F3CF
+F3D0
+F3D1
+F3D2
+F3D3
+F3D4
+F3D5
+F3D6
+F3D7
+F3D8
+F3D9
+F3DA
+F3DB
+F3DC
+F3DD
+F3DE
+F3DF
+F3E0
+F3E1
+F3E2
+F3E3
+F3E4
+F3E5
+F3E6
+F3E7
+F3E8
+F3E9
+F3EA
+F3EB
+F3EC
+F3ED
+F3EE
+F3EF
+F3F0
+F3F1
+F3F2
+F3F3
+F3F4
+F3F5
+F3F6
+F3F7
+F3F8
+F3F9
+F3FA
+F3FB
+F3FC
+F440
+F441
+F442
+F443
+F444
+F445
+F446
+F447
+F448
+F449
+F44A
+F44B
+F44C
+F44D
+F44E
+F44F
+F450
+F451
+F452
+F453
+F454
+F455
+F456
+F457
+F458
+F459
+F45A
+F45B
+F45C
+F45D
+F45E
+F45F
+F460
+F461
+F462
+F463
+F464
+F465
+F466
+F467
+F468
+F469
+F46A
+F46B
+F46C
+F46D
+F46E
+F46F
+F470
+F471
+F472
+F473
+F474
+F475
+F476
+F477
+F478
+F479
+F47A
+F47B
+F47C
+F47D
+F47E
+F480
+F481
+F482
+F483
+F484
+F485
+F486
+F487
+F488
+F489
+F48A
+F48B
+F48C
+F48D
+F48E
+F48F
+F490
+F491
+F492
+F493
+F494
+F495
+F496
+F497
+F498
+F499
+F49A
+F49B
+F49C
+F49D
+F49E
+F49F
+F4A0
+F4A1
+F4A2
+F4A3
+F4A4
+F4A5
+F4A6
+F4A7
+F4A8
+F4A9
+F4AA
+F4AB
+F4AC
+F4AD
+F4AE
+F4AF
+F4B0
+F4B1
+F4B2
+F4B3
+F4B4
+F4B5
+F4B6
+F4B7
+F4B8
+F4B9
+F4BA
+F4BB
+F4BC
+F4BD
+F4BE
+F4BF
+F4C0
+F4C1
+F4C2
+F4C3
+F4C4
+F4C5
+F4C6
+F4C7
+F4C8
+F4C9
+F4CA
+F4CB
+F4CC
+F4CD
+F4CE
+F4CF
+F4D0
+F4D1
+F4D2
+F4D3
+F4D4
+F4D5
+F4D6
+F4D7
+F4D8
+F4D9
+F4DA
+F4DB
+F4DC
+F4DD
+F4DE
+F4DF
+F4E0
+F4E1
+F4E2
+F4E3
+F4E4
+F4E5
+F4E6
+F4E7
+F4E8
+F4E9
+F4EA
+F4EB
+F4EC
+F4ED
+F4EE
+F4EF
+F4F0
+F4F1
+F4F2
+F4F3
+F4F4
+F4F5
+F4F6
+F4F7
+F4F8
+F4F9
+F4FA
+F4FB
+F4FC
+F540
+F541
+F542
+F543
+F544
+F545
+F546
+F547
+F548
+F549
+F54A
+F54B
+F54C
+F54D
+F54E
+F54F
+F550
+F551
+F552
+F553
+F554
+F555
+F556
+F557
+F558
+F559
+F55A
+F55B
+F55C
+F55D
+F55E
+F55F
+F560
+F561
+F562
+F563
+F564
+F565
+F566
+F567
+F568
+F569
+F56A
+F56B
+F56C
+F56D
+F56E
+F56F
+F570
+F571
+F572
+F573
+F574
+F575
+F576
+F577
+F578
+F579
+F57A
+F57B
+F57C
+F57D
+F57E
+F580
+F581
+F582
+F583
+F584
+F585
+F586
+F587
+F588
+F589
+F58A
+F58B
+F58C
+F58D
+F58E
+F58F
+F590
+F591
+F592
+F593
+F594
+F595
+F596
+F597
+F598
+F599
+F59A
+F59B
+F59C
+F59D
+F59E
+F59F
+F5A0
+F5A1
+F5A2
+F5A3
+F5A4
+F5A5
+F5A6
+F5A7
+F5A8
+F5A9
+F5AA
+F5AB
+F5AC
+F5AD
+F5AE
+F5AF
+F5B0
+F5B1
+F5B2
+F5B3
+F5B4
+F5B5
+F5B6
+F5B7
+F5B8
+F5B9
+F5BA
+F5BB
+F5BC
+F5BD
+F5BE
+F5BF
+F5C0
+F5C1
+F5C2
+F5C3
+F5C4
+F5C5
+F5C6
+F5C7
+F5C8
+F5C9
+F5CA
+F5CB
+F5CC
+F5CD
+F5CE
+F5CF
+F5D0
+F5D1
+F5D2
+F5D3
+F5D4
+F5D5
+F5D6
+F5D7
+F5D8
+F5D9
+F5DA
+F5DB
+F5DC
+F5DD
+F5DE
+F5DF
+F5E0
+F5E1
+F5E2
+F5E3
+F5E4
+F5E5
+F5E6
+F5E7
+F5E8
+F5E9
+F5EA
+F5EB
+F5EC
+F5ED
+F5EE
+F5EF
+F5F0
+F5F1
+F5F2
+F5F3
+F5F4
+F5F5
+F5F6
+F5F7
+F5F8
+F5F9
+F5FA
+F5FB
+F5FC
+F640
+F641
+F642
+F643
+F644
+F645
+F646
+F647
+F648
+F649
+F64A
+F64B
+F64C
+F64D
+F64E
+F64F
+F650
+F651
+F652
+F653
+F654
+F655
+F656
+F657
+F658
+F659
+F65A
+F65B
+F65C
+F65D
+F65E
+F65F
+F660
+F661
+F662
+F663
+F664
+F665
+F666
+F667
+F668
+F669
+F66A
+F66B
+F66C
+F66D
+F66E
+F66F
+F670
+F671
+F672
+F673
+F674
+F675
+F676
+F677
+F678
+F679
+F67A
+F67B
+F67C
+F67D
+F67E
+F680
+F681
+F682
+F683
+F684
+F685
+F686
+F687
+F688
+F689
+F68A
+F68B
+F68C
+F68D
+F68E
+F68F
+F690
+F691
+F692
+F693
+F694
+F695
+F696
+F697
+F698
+F699
+F69A
+F69B
+F69C
+F69D
+F69E
+F69F
+F6A0
+F6A1
+F6A2
+F6A3
+F6A4
+F6A5
+F6A6
+F6A7
+F6A8
+F6A9
+F6AA
+F6AB
+F6AC
+F6AD
+F6AE
+F6AF
+F6B0
+F6B1
+F6B2
+F6B3
+F6B4
+F6B5
+F6B6
+F6B7
+F6B8
+F6B9
+F6BA
+F6BB
+F6BC
+F6BD
+F6BE
+F6BF
+F6C0
+F6C1
+F6C2
+F6C3
+F6C4
+F6C5
+F6C6
+F6C7
+F6C8
+F6C9
+F6CA
+F6CB
+F6CC
+F6CD
+F6CE
+F6CF
+F6D0
+F6D1
+F6D2
+F6D3
+F6D4
+F6D5
+F6D6
+F6D7
+F6D8
+F6D9
+F6DA
+F6DB
+F6DC
+F6DD
+F6DE
+F6DF
+F6E0
+F6E1
+F6E2
+F6E3
+F6E4
+F6E5
+F6E6
+F6E7
+F6E8
+F6E9
+F6EA
+F6EB
+F6EC
+F6ED
+F6EE
+F6EF
+F6F0
+F6F1
+F6F2
+F6F3
+F6F4
+F6F5
+F6F6
+F6F7
+F6F8
+F6F9
+F6FA
+F6FB
+F6FC
+F740
+F741
+F742
+F743
+F744
+F745
+F746
+F747
+F748
+F749
+F74A
+F74B
+F74C
+F74D
+F74E
+F74F
+F750
+F751
+F752
+F753
+F754
+F755
+F756
+F757
+F758
+F759
+F75A
+F75B
+F75C
+F75D
+F75E
+F75F
+F760
+F761
+F762
+F763
+F764
+F765
+F766
+F767
+F768
+F769
+F76A
+F76B
+F76C
+F76D
+F76E
+F76F
+F770
+F771
+F772
+F773
+F774
+F775
+F776
+F777
+F778
+F779
+F77A
+F77B
+F77C
+F77D
+F77E
+F780
+F781
+F782
+F783
+F784
+F785
+F786
+F787
+F788
+F789
+F78A
+F78B
+F78C
+F78D
+F78E
+F78F
+F790
+F791
+F792
+F793
+F794
+F795
+F796
+F797
+F798
+F799
+F79A
+F79B
+F79C
+F79D
+F79E
+F79F
+F7A0
+F7A1
+F7A2
+F7A3
+F7A4
+F7A5
+F7A6
+F7A7
+F7A8
+F7A9
+F7AA
+F7AB
+F7AC
+F7AD
+F7AE
+F7AF
+F7B0
+F7B1
+F7B2
+F7B3
+F7B4
+F7B5
+F7B6
+F7B7
+F7B8
+F7B9
+F7BA
+F7BB
+F7BC
+F7BD
+F7BE
+F7BF
+F7C0
+F7C1
+F7C2
+F7C3
+F7C4
+F7C5
+F7C6
+F7C7
+F7C8
+F7C9
+F7CA
+F7CB
+F7CC
+F7CD
+F7CE
+F7CF
+F7D0
+F7D1
+F7D2
+F7D3
+F7D4
+F7D5
+F7D6
+F7D7
+F7D8
+F7D9
+F7DA
+F7DB
+F7DC
+F7DD
+F7DE
+F7DF
+F7E0
+F7E1
+F7E2
+F7E3
+F7E4
+F7E5
+F7E6
+F7E7
+F7E8
+F7E9
+F7EA
+F7EB
+F7EC
+F7ED
+F7EE
+F7EF
+F7F0
+F7F1
+F7F2
+F7F3
+F7F4
+F7F5
+F7F6
+F7F7
+F7F8
+F7F9
+F7FA
+F7FB
+F7FC
+F840
+F841
+F842
+F843
+F844
+F845
+F846
+F847
+F848
+F849
+F84A
+F84B
+F84C
+F84D
+F84E
+F84F
+F850
+F851
+F852
+F853
+F854
+F855
+F856
+F857
+F858
+F859
+F85A
+F85B
+F85C
+F85D
+F85E
+F85F
+F860
+F861
+F862
+F863
+F864
+F865
+F866
+F867
+F868
+F869
+F86A
+F86B
+F86C
+F86D
+F86E
+F86F
+F870
+F871
+F872
+F873
+F874
+F875
+F876
+F877
+F878
+F879
+F87A
+F87B
+F87C
+F87D
+F87E
+F880
+F881
+F882
+F883
+F884
+F885
+F886
+F887
+F888
+F889
+F88A
+F88B
+F88C
+F88D
+F88E
+F88F
+F890
+F891
+F892
+F893
+F894
+F895
+F896
+F897
+F898
+F899
+F89A
+F89B
+F89C
+F89D
+F89E
+F89F
+F8A0
+F8A1
+F8A2
+F8A3
+F8A4
+F8A5
+F8A6
+F8A7
+F8A8
+F8A9
+F8AA
+F8AB
+F8AC
+F8AD
+F8AE
+F8AF
+F8B0
+F8B1
+F8B2
+F8B3
+F8B4
+F8B5
+F8B6
+F8B7
+F8B8
+F8B9
+F8BA
+F8BB
+F8BC
+F8BD
+F8BE
+F8BF
+F8C0
+F8C1
+F8C2
+F8C3
+F8C4
+F8C5
+F8C6
+F8C7
+F8C8
+F8C9
+F8CA
+F8CB
+F8CC
+F8CD
+F8CE
+F8CF
+F8D0
+F8D1
+F8D2
+F8D3
+F8D4
+F8D5
+F8D6
+F8D7
+F8D8
+F8D9
+F8DA
+F8DB
+F8DC
+F8DD
+F8DE
+F8DF
+F8E0
+F8E1
+F8E2
+F8E3
+F8E4
+F8E5
+F8E6
+F8E7
+F8E8
+F8E9
+F8EA
+F8EB
+F8EC
+F8ED
+F8EE
+F8EF
+F8F0
+F8F1
+F8F2
+F8F3
+F8F4
+F8F5
+F8F6
+F8F7
+F8F8
+F8F9
+F8FA
+F8FB
+F8FC
+F940
+F941
+F942
+F943
+F944
+F945
+F946
+F947
+F948
+F949
+F94A
+F94B
+F94C
+F94D
+F94E
+F94F
+F950
+F951
+F952
+F953
+F954
+F955
+F956
+F957
+F958
+F959
+F95A
+F95B
+F95C
+F95D
+F95E
+F95F
+F960
+F961
+F962
+F963
+F964
+F965
+F966
+F967
+F968
+F969
+F96A
+F96B
+F96C
+F96D
+F96E
+F96F
+F970
+F971
+F972
+F973
+F974
+F975
+F976
+F977
+F978
+F979
+F97A
+F97B
+F97C
+F97D
+F97E
+F980
+F981
+F982
+F983
+F984
+F985
+F986
+F987
+F988
+F989
+F98A
+F98B
+F98C
+F98D
+F98E
+F98F
+F990
+F991
+F992
+F993
+F994
+F995
+F996
+F997
+F998
+F999
+F99A
+F99B
+F99C
+F99D
+F99E
+F99F
+F9A0
+F9A1
+F9A2
+F9A3
+F9A4
+F9A5
+F9A6
+F9A7
+F9A8
+F9A9
+F9AA
+F9AB
+F9AC
+F9AD
+F9AE
+F9AF
+F9B0
+F9B1
+F9B2
+F9B3
+F9B4
+F9B5
+F9B6
+F9B7
+F9B8
+F9B9
+F9BA
+F9BB
+F9BC
+F9BD
+F9BE
+F9BF
+F9C0
+F9C1
+F9C2
+F9C3
+F9C4
+F9C5
+F9C6
+F9C7
+F9C8
+F9C9
+F9CA
+F9CB
+F9CC
+F9CD
+F9CE
+F9CF
+F9D0
+F9D1
+F9D2
+F9D3
+F9D4
+F9D5
+F9D6
+F9D7
+F9D8
+F9D9
+F9DA
+F9DB
+F9DC
+F9DD
+F9DE
+F9DF
+F9E0
+F9E1
+F9E2
+F9E3
+F9E4
+F9E5
+F9E6
+F9E7
+F9E8
+F9E9
+F9EA
+F9EB
+F9EC
+F9ED
+F9EE
+F9EF
+F9F0
+F9F1
+F9F2
+F9F3
+F9F4
+F9F5
+F9F6
+F9F7
+F9F8
+F9F9
+F9FA
+F9FB
+F9FC
+CREATE TABLE t4 SELECT CONVERT(c1 USING eucjpms) AS c1 FROM t1;
+SELECT HEX(c1) FROM t4;
+HEX(c1)
+05
+7E
+A1BD
+A1C0
+A1C1
+A1C2
+A1DD
+A1F1
+A1F2
+A2CC
+ADA1
+ADA2
+ADA3
+ADA4
+ADA5
+ADA6
+ADA7
+ADA8
+ADA9
+ADAA
+ADAB
+ADAC
+ADAD
+ADAE
+ADAF
+ADB0
+ADB1
+ADB2
+ADB3
+ADB4
+ADB5
+ADB6
+ADB7
+ADB8
+ADB9
+ADBA
+ADBB
+ADBC
+ADBD
+ADBE
+ADC0
+ADC1
+ADC2
+ADC3
+ADC4
+ADC5
+ADC6
+ADC7
+ADC8
+ADC9
+ADCA
+ADCB
+ADCC
+ADCD
+ADCE
+ADCF
+ADD0
+ADD1
+ADD2
+ADD3
+ADD4
+ADD5
+ADD6
+ADDF
+ADE0
+ADE1
+ADE2
+ADE3
+ADE4
+ADE5
+ADE6
+ADE7
+ADE8
+ADE9
+ADEA
+ADEB
+ADEC
+ADED
+ADEE
+ADEF
+A2E2
+A2E1
+A2E9
+ADF3
+ADF4
+A2E5
+A2DD
+A2DC
+ADF8
+ADF9
+A2E8
+A2C1
+A2C0
+8FD4E3
+8FDCDF
+8FE4E9
+8FE3F8
+8FD9A1
+8FB1BB
+8FF4AE
+8FC2AD
+8FC3FC
+8FE4D0
+8FC2BF
+8FBCF4
+8FB0A9
+8FB0C8
+8FF4AF
+8FB0D2
+8FB0D4
+8FB0E3
+8FB0EE
+8FB1A7
+8FB1A3
+8FB1AC
+8FB1A9
+8FB1BE
+8FB1DF
+8FB1D8
+8FB1C8
+8FB1D7
+8FB1E3
+8FB1F4
+8FB1E1
+8FB2A3
+8FF4B0
+8FB2BB
+8FB2E6
+8FB2ED
+8FB2F5
+8FB2FC
+8FF4B1
+8FB3B5
+8FB3D8
+8FB3DB
+8FB3E5
+8FB3EE
+8FB3FB
+8FF4B2
+8FF4B3
+8FB4C0
+8FB4C7
+8FB4D0
+8FB4DE
+8FF4B4
+8FB5AA
+8FF4B5
+8FB5AF
+8FB5C4
+8FB5E8
+8FF4B6
+8FB7C2
+8FB7E4
+8FB7E8
+8FB7E7
+8FF4B7
+8FF4B8
+8FF4B9
+8FB8CE
+8FB8E1
+8FB8F5
+8FB8F7
+8FB8F8
+8FB8FC
+8FB9AF
+8FB9B7
+8FBABE
+8FBADB
+8FCDAA
+8FBAE1
+8FF4BA
+8FBAEB
+8FBBB3
+8FBBB8
+8FF4BB
+8FBBCA
+8FF4BC
+8FF4BD
+8FBBD0
+8FBBDE
+8FBBF4
+8FBBF5
+8FBBF9
+8FBCE4
+8FBCED
+8FBCFE
+8FF4BE
+8FBDC2
+8FBDE7
+8FF4BF
+8FBDF0
+8FBEB0
+8FBEAC
+8FF4C0
+8FBEB3
+8FBEBD
+8FBECD
+8FBEC9
+8FBEE4
+8FBFA8
+8FBFC9
+8FC0C4
+8FC0E4
+8FC0F4
+8FC1A6
+8FF4C1
+8FC1F5
+8FC1FC
+8FF4C2
+8FC1F8
+8FC2AB
+8FC2A1
+8FC2A5
+8FF4C3
+8FC2B8
+8FC2BA
+8FF4C4
+8FC2C4
+8FC2D2
+8FC2D7
+8FC2DB
+8FC2DE
+8FC2ED
+8FC2F0
+8FF4C5
+8FC3A1
+8FC3B5
+8FC3C9
+8FC3B9
+8FF4C6
+8FC3D8
+8FC3FE
+8FF4C7
+8FC4CC
+8FF4C8
+8FC4D9
+8FC4EA
+8FC4FD
+8FF4C9
+8FC5A7
+8FC5B5
+8FC5B6
+8FF4CA
+8FC5D5
+8FC6B8
+8FC6D7
+8FC6E0
+8FC6EA
+8FC6E3
+8FC7A1
+8FC7AB
+8FC7C7
+8FC7C3
+8FC7CB
+8FC7CF
+8FC7D9
+8FF4CB
+8FF4CC
+8FC7E6
+8FC7EE
+8FC7FC
+8FC7EB
+8FC7F0
+8FC8B1
+8FC8E5
+8FC8F8
+8FC9A6
+8FC9AB
+8FC9AD
+8FF4CD
+8FC9CA
+8FC9D3
+8FC9E9
+8FC9E3
+8FC9FC
+8FC9F4
+8FC9F5
+8FF4CE
+8FCAB3
+8FCABD
+8FCAEF
+8FCAF1
+8FCBAE
+8FF4CF
+8FCBCA
+8FCBE6
+8FCBEA
+8FCBF0
+8FCBF4
+8FCBEE
+8FCCA5
+8FCBF9
+8FCCAB
+8FCCAE
+8FCCAD
+8FCCB2
+8FCCC2
+8FCCD0
+8FCCD9
+8FF4D0
+8FCDBB
+8FF4D1
+8FCEBB
+8FF4D2
+8FCEBA
+8FCEC3
+8FF4D3
+8FCEF2
+8FB3DD
+8FCFD5
+8FCFE2
+8FCFE9
+8FCFED
+8FF4D4
+8FF4D5
+8FF4D6
+8FF4D7
+8FD0E5
+8FF4D8
+8FD0E9
+8FD1E8
+8FF4D9
+8FF4DA
+8FD1EC
+8FD2BB
+8FF4DB
+8FD3E1
+8FD3E8
+8FD4A7
+8FF4DC
+8FF4DD
+8FD4D4
+8FD4F2
+8FD5AE
+8FF4DE
+8FD7DE
+8FF4DF
+8FD8A2
+8FD8B7
+8FD8C1
+8FD8D1
+8FD8F4
+8FD9C6
+8FD9C8
+8FD9D1
+8FF4E0
+8FF4E1
+8FF4E2
+8FF4E3
+8FF4E4
+8FDCD3
+8FDDC8
+8FDDD4
+8FDDEA
+8FDDFA
+8FDEA4
+8FDEB0
+8FF4E5
+8FDEB5
+8FDECB
+8FF4E6
+8FDFB9
+8FF4E7
+8FDFC3
+8FF4E8
+8FF4E9
+8FE0D9
+8FF4EA
+8FF4EB
+8FE1E2
+8FF4EC
+8FF4ED
+8FF4EE
+8FE2C7
+8FE3A8
+8FE3A6
+8FE3A9
+8FE3AF
+8FE3B0
+8FE3AA
+8FE3AB
+8FE3BC
+8FE3C1
+8FE3BF
+8FE3D5
+8FE3D8
+8FE3D6
+8FE3DF
+8FE3E3
+8FE3E1
+8FE3D4
+8FE3E9
+8FE4A6
+8FE3F1
+8FE3F2
+8FE4CB
+8FE4C1
+8FE4C3
+8FE4BE
+8FF4EF
+8FE4C0
+8FE4C7
+8FE4BF
+8FE4E0
+8FE4DE
+8FE4D1
+8FF4F0
+8FE4DC
+8FE4D2
+8FE4DB
+8FE4D4
+8FE4FA
+8FE4EF
+8FE5B3
+8FE5BF
+8FE5C9
+8FE5D0
+8FE5E2
+8FE5EA
+8FE5EB
+8FF4F1
+8FF4F2
+8FF4F3
+8FE6E8
+8FE6EF
+8FE7AC
+8FF4F4
+8FE7AE
+8FF4F5
+8FE7B1
+8FF4F6
+8FE7B2
+8FE8B1
+8FE8B6
+8FF4F7
+8FF4F8
+8FE8DD
+8FF4F9
+8FF4FA
+8FE9D1
+8FF4FB
+8FE9ED
+8FEACD
+8FF4FC
+8FEADB
+8FEAE6
+8FEAEA
+8FEBA5
+8FEBFB
+8FEBFA
+8FF4FD
+8FECD6
+8FF4FE
+8FF3F3
+8FF3F4
+8FF3F5
+8FF3F6
+8FF3F7
+8FF3F8
+8FF3F9
+8FF3FA
+8FF3FB
+8FF3FC
+A2CC
+8FA2C3
+8FF4A9
+8FF4AA
+8FF3F3
+8FF3F4
+8FF3F5
+8FF3F6
+8FF3F7
+8FF3F8
+8FF3F9
+8FF3FA
+8FF3FB
+8FF3FC
+ADB5
+ADB6
+ADB7
+ADB8
+ADB9
+ADBA
+ADBB
+ADBC
+ADBD
+ADBE
+A2CC
+8FA2C3
+8FF4A9
+8FF4AA
+ADEA
+ADE2
+ADE4
+A2E8
+8FD4E3
+8FDCDF
+8FE4E9
+8FE3F8
+8FD9A1
+8FB1BB
+8FF4AE
+8FC2AD
+8FC3FC
+8FE4D0
+8FC2BF
+8FBCF4
+8FB0A9
+8FB0C8
+8FF4AF
+8FB0D2
+8FB0D4
+8FB0E3
+8FB0EE
+8FB1A7
+8FB1A3
+8FB1AC
+8FB1A9
+8FB1BE
+8FB1DF
+8FB1D8
+8FB1C8
+8FB1D7
+8FB1E3
+8FB1F4
+8FB1E1
+8FB2A3
+8FF4B0
+8FB2BB
+8FB2E6
+8FB2ED
+8FB2F5
+8FB2FC
+8FF4B1
+8FB3B5
+8FB3D8
+8FB3DB
+8FB3E5
+8FB3EE
+8FB3FB
+8FF4B2
+8FF4B3
+8FB4C0
+8FB4C7
+8FB4D0
+8FB4DE
+8FF4B4
+8FB5AA
+8FF4B5
+8FB5AF
+8FB5C4
+8FB5E8
+8FF4B6
+8FB7C2
+8FB7E4
+8FB7E8
+8FB7E7
+8FF4B7
+8FF4B8
+8FF4B9
+8FB8CE
+8FB8E1
+8FB8F5
+8FB8F7
+8FB8F8
+8FB8FC
+8FB9AF
+8FB9B7
+8FBABE
+8FBADB
+8FCDAA
+8FBAE1
+8FF4BA
+8FBAEB
+8FBBB3
+8FBBB8
+8FF4BB
+8FBBCA
+8FF4BC
+8FF4BD
+8FBBD0
+8FBBDE
+8FBBF4
+8FBBF5
+8FBBF9
+8FBCE4
+8FBCED
+8FBCFE
+8FF4BE
+8FBDC2
+8FBDE7
+8FF4BF
+8FBDF0
+8FBEB0
+8FBEAC
+8FF4C0
+8FBEB3
+8FBEBD
+8FBECD
+8FBEC9
+8FBEE4
+8FBFA8
+8FBFC9
+8FC0C4
+8FC0E4
+8FC0F4
+8FC1A6
+8FF4C1
+8FC1F5
+8FC1FC
+8FF4C2
+8FC1F8
+8FC2AB
+8FC2A1
+8FC2A5
+8FF4C3
+8FC2B8
+8FC2BA
+8FF4C4
+8FC2C4
+8FC2D2
+8FC2D7
+8FC2DB
+8FC2DE
+8FC2ED
+8FC2F0
+8FF4C5
+8FC3A1
+8FC3B5
+8FC3C9
+8FC3B9
+8FF4C6
+8FC3D8
+8FC3FE
+8FF4C7
+8FC4CC
+8FF4C8
+8FC4D9
+8FC4EA
+8FC4FD
+8FF4C9
+8FC5A7
+8FC5B5
+8FC5B6
+8FF4CA
+8FC5D5
+8FC6B8
+8FC6D7
+8FC6E0
+8FC6EA
+8FC6E3
+8FC7A1
+8FC7AB
+8FC7C7
+8FC7C3
+8FC7CB
+8FC7CF
+8FC7D9
+8FF4CB
+8FF4CC
+8FC7E6
+8FC7EE
+8FC7FC
+8FC7EB
+8FC7F0
+8FC8B1
+8FC8E5
+8FC8F8
+8FC9A6
+8FC9AB
+8FC9AD
+8FF4CD
+8FC9CA
+8FC9D3
+8FC9E9
+8FC9E3
+8FC9FC
+8FC9F4
+8FC9F5
+8FF4CE
+8FCAB3
+8FCABD
+8FCAEF
+8FCAF1
+8FCBAE
+8FF4CF
+8FCBCA
+8FCBE6
+8FCBEA
+8FCBF0
+8FCBF4
+8FCBEE
+8FCCA5
+8FCBF9
+8FCCAB
+8FCCAE
+8FCCAD
+8FCCB2
+8FCCC2
+8FCCD0
+8FCCD9
+8FF4D0
+8FCDBB
+8FF4D1
+8FCEBB
+8FF4D2
+8FCEBA
+8FCEC3
+8FF4D3
+8FCEF2
+8FB3DD
+8FCFD5
+8FCFE2
+8FCFE9
+8FCFED
+8FF4D4
+8FF4D5
+8FF4D6
+8FF4D7
+8FD0E5
+8FF4D8
+8FD0E9
+8FD1E8
+8FF4D9
+8FF4DA
+8FD1EC
+8FD2BB
+8FF4DB
+8FD3E1
+8FD3E8
+8FD4A7
+8FF4DC
+8FF4DD
+8FD4D4
+8FD4F2
+8FD5AE
+8FF4DE
+8FD7DE
+8FF4DF
+8FD8A2
+8FD8B7
+8FD8C1
+8FD8D1
+8FD8F4
+8FD9C6
+8FD9C8
+8FD9D1
+8FF4E0
+8FF4E1
+8FF4E2
+8FF4E3
+8FF4E4
+8FDCD3
+8FDDC8
+8FDDD4
+8FDDEA
+8FDDFA
+8FDEA4
+8FDEB0
+8FF4E5
+8FDEB5
+8FDECB
+8FF4E6
+8FDFB9
+8FF4E7
+8FDFC3
+8FF4E8
+8FF4E9
+8FE0D9
+8FF4EA
+8FF4EB
+8FE1E2
+8FF4EC
+8FF4ED
+8FF4EE
+8FE2C7
+8FE3A8
+8FE3A6
+8FE3A9
+8FE3AF
+8FE3B0
+8FE3AA
+8FE3AB
+8FE3BC
+8FE3C1
+8FE3BF
+8FE3D5
+8FE3D8
+8FE3D6
+8FE3DF
+8FE3E3
+8FE3E1
+8FE3D4
+8FE3E9
+8FE4A6
+8FE3F1
+8FE3F2
+8FE4CB
+8FE4C1
+8FE4C3
+8FE4BE
+8FF4EF
+8FE4C0
+8FE4C7
+8FE4BF
+8FE4E0
+8FE4DE
+8FE4D1
+8FF4F0
+8FE4DC
+8FE4D2
+8FE4DB
+8FE4D4
+8FE4FA
+8FE4EF
+8FE5B3
+8FE5BF
+8FE5C9
+8FE5D0
+8FE5E2
+8FE5EA
+8FE5EB
+8FF4F1
+8FF4F2
+8FF4F3
+8FE6E8
+8FE6EF
+8FE7AC
+8FF4F4
+8FE7AE
+8FF4F5
+8FE7B1
+8FF4F6
+8FE7B2
+8FE8B1
+8FE8B6
+8FF4F7
+8FF4F8
+8FE8DD
+8FF4F9
+8FF4FA
+8FE9D1
+8FF4FB
+8FE9ED
+8FEACD
+8FF4FC
+8FEADB
+8FEAE6
+8FEAEA
+8FEBA5
+8FEBFB
+8FEBFA
+8FF4FD
+8FECD6
+8FF4FE
+F5A1
+F5A2
+F5A3
+F5A4
+F5A5
+F5A6
+F5A7
+F5A8
+F5A9
+F5AA
+F5AB
+F5AC
+F5AD
+F5AE
+F5AF
+F5B0
+F5B1
+F5B2
+F5B3
+F5B4
+F5B5
+F5B6
+F5B7
+F5B8
+F5B9
+F5BA
+F5BB
+F5BC
+F5BD
+F5BE
+F5BF
+F5C0
+F5C1
+F5C2
+F5C3
+F5C4
+F5C5
+F5C6
+F5C7
+F5C8
+F5C9
+F5CA
+F5CB
+F5CC
+F5CD
+F5CE
+F5CF
+F5D0
+F5D1
+F5D2
+F5D3
+F5D4
+F5D5
+F5D6
+F5D7
+F5D8
+F5D9
+F5DA
+F5DB
+F5DC
+F5DD
+F5DE
+F5DF
+F5E0
+F5E1
+F5E2
+F5E3
+F5E4
+F5E5
+F5E6
+F5E7
+F5E8
+F5E9
+F5EA
+F5EB
+F5EC
+F5ED
+F5EE
+F5EF
+F5F0
+F5F1
+F5F2
+F5F3
+F5F4
+F5F5
+F5F6
+F5F7
+F5F8
+F5F9
+F5FA
+F5FB
+F5FC
+F5FD
+F5FE
+F6A1
+F6A2
+F6A3
+F6A4
+F6A5
+F6A6
+F6A7
+F6A8
+F6A9
+F6AA
+F6AB
+F6AC
+F6AD
+F6AE
+F6AF
+F6B0
+F6B1
+F6B2
+F6B3
+F6B4
+F6B5
+F6B6
+F6B7
+F6B8
+F6B9
+F6BA
+F6BB
+F6BC
+F6BD
+F6BE
+F6BF
+F6C0
+F6C1
+F6C2
+F6C3
+F6C4
+F6C5
+F6C6
+F6C7
+F6C8
+F6C9
+F6CA
+F6CB
+F6CC
+F6CD
+F6CE
+F6CF
+F6D0
+F6D1
+F6D2
+F6D3
+F6D4
+F6D5
+F6D6
+F6D7
+F6D8
+F6D9
+F6DA
+F6DB
+F6DC
+F6DD
+F6DE
+F6DF
+F6E0
+F6E1
+F6E2
+F6E3
+F6E4
+F6E5
+F6E6
+F6E7
+F6E8
+F6E9
+F6EA
+F6EB
+F6EC
+F6ED
+F6EE
+F6EF
+F6F0
+F6F1
+F6F2
+F6F3
+F6F4
+F6F5
+F6F6
+F6F7
+F6F8
+F6F9
+F6FA
+F6FB
+F6FC
+F6FD
+F6FE
+F7A1
+F7A2
+F7A3
+F7A4
+F7A5
+F7A6
+F7A7
+F7A8
+F7A9
+F7AA
+F7AB
+F7AC
+F7AD
+F7AE
+F7AF
+F7B0
+F7B1
+F7B2
+F7B3
+F7B4
+F7B5
+F7B6
+F7B7
+F7B8
+F7B9
+F7BA
+F7BB
+F7BC
+F7BD
+F7BE
+F7BF
+F7C0
+F7C1
+F7C2
+F7C3
+F7C4
+F7C5
+F7C6
+F7C7
+F7C8
+F7C9
+F7CA
+F7CB
+F7CC
+F7CD
+F7CE
+F7CF
+F7D0
+F7D1
+F7D2
+F7D3
+F7D4
+F7D5
+F7D6
+F7D7
+F7D8
+F7D9
+F7DA
+F7DB
+F7DC
+F7DD
+F7DE
+F7DF
+F7E0
+F7E1
+F7E2
+F7E3
+F7E4
+F7E5
+F7E6
+F7E7
+F7E8
+F7E9
+F7EA
+F7EB
+F7EC
+F7ED
+F7EE
+F7EF
+F7F0
+F7F1
+F7F2
+F7F3
+F7F4
+F7F5
+F7F6
+F7F7
+F7F8
+F7F9
+F7FA
+F7FB
+F7FC
+F7FD
+F7FE
+F8A1
+F8A2
+F8A3
+F8A4
+F8A5
+F8A6
+F8A7
+F8A8
+F8A9
+F8AA
+F8AB
+F8AC
+F8AD
+F8AE
+F8AF
+F8B0
+F8B1
+F8B2
+F8B3
+F8B4
+F8B5
+F8B6
+F8B7
+F8B8
+F8B9
+F8BA
+F8BB
+F8BC
+F8BD
+F8BE
+F8BF
+F8C0
+F8C1
+F8C2
+F8C3
+F8C4
+F8C5
+F8C6
+F8C7
+F8C8
+F8C9
+F8CA
+F8CB
+F8CC
+F8CD
+F8CE
+F8CF
+F8D0
+F8D1
+F8D2
+F8D3
+F8D4
+F8D5
+F8D6
+F8D7
+F8D8
+F8D9
+F8DA
+F8DB
+F8DC
+F8DD
+F8DE
+F8DF
+F8E0
+F8E1
+F8E2
+F8E3
+F8E4
+F8E5
+F8E6
+F8E7
+F8E8
+F8E9
+F8EA
+F8EB
+F8EC
+F8ED
+F8EE
+F8EF
+F8F0
+F8F1
+F8F2
+F8F3
+F8F4
+F8F5
+F8F6
+F8F7
+F8F8
+F8F9
+F8FA
+F8FB
+F8FC
+F8FD
+F8FE
+F9A1
+F9A2
+F9A3
+F9A4
+F9A5
+F9A6
+F9A7
+F9A8
+F9A9
+F9AA
+F9AB
+F9AC
+F9AD
+F9AE
+F9AF
+F9B0
+F9B1
+F9B2
+F9B3
+F9B4
+F9B5
+F9B6
+F9B7
+F9B8
+F9B9
+F9BA
+F9BB
+F9BC
+F9BD
+F9BE
+F9BF
+F9C0
+F9C1
+F9C2
+F9C3
+F9C4
+F9C5
+F9C6
+F9C7
+F9C8
+F9C9
+F9CA
+F9CB
+F9CC
+F9CD
+F9CE
+F9CF
+F9D0
+F9D1
+F9D2
+F9D3
+F9D4
+F9D5
+F9D6
+F9D7
+F9D8
+F9D9
+F9DA
+F9DB
+F9DC
+F9DD
+F9DE
+F9DF
+F9E0
+F9E1
+F9E2
+F9E3
+F9E4
+F9E5
+F9E6
+F9E7
+F9E8
+F9E9
+F9EA
+F9EB
+F9EC
+F9ED
+F9EE
+F9EF
+F9F0
+F9F1
+F9F2
+F9F3
+F9F4
+F9F5
+F9F6
+F9F7
+F9F8
+F9F9
+F9FA
+F9FB
+F9FC
+F9FD
+F9FE
+FAA1
+FAA2
+FAA3
+FAA4
+FAA5
+FAA6
+FAA7
+FAA8
+FAA9
+FAAA
+FAAB
+FAAC
+FAAD
+FAAE
+FAAF
+FAB0
+FAB1
+FAB2
+FAB3
+FAB4
+FAB5
+FAB6
+FAB7
+FAB8
+FAB9
+FABA
+FABB
+FABC
+FABD
+FABE
+FABF
+FAC0
+FAC1
+FAC2
+FAC3
+FAC4
+FAC5
+FAC6
+FAC7
+FAC8
+FAC9
+FACA
+FACB
+FACC
+FACD
+FACE
+FACF
+FAD0
+FAD1
+FAD2
+FAD3
+FAD4
+FAD5
+FAD6
+FAD7
+FAD8
+FAD9
+FADA
+FADB
+FADC
+FADD
+FADE
+FADF
+FAE0
+FAE1
+FAE2
+FAE3
+FAE4
+FAE5
+FAE6
+FAE7
+FAE8
+FAE9
+FAEA
+FAEB
+FAEC
+FAED
+FAEE
+FAEF
+FAF0
+FAF1
+FAF2
+FAF3
+FAF4
+FAF5
+FAF6
+FAF7
+FAF8
+FAF9
+FAFA
+FAFB
+FAFC
+FAFD
+FAFE
+FBA1
+FBA2
+FBA3
+FBA4
+FBA5
+FBA6
+FBA7
+FBA8
+FBA9
+FBAA
+FBAB
+FBAC
+FBAD
+FBAE
+FBAF
+FBB0
+FBB1
+FBB2
+FBB3
+FBB4
+FBB5
+FBB6
+FBB7
+FBB8
+FBB9
+FBBA
+FBBB
+FBBC
+FBBD
+FBBE
+FBBF
+FBC0
+FBC1
+FBC2
+FBC3
+FBC4
+FBC5
+FBC6
+FBC7
+FBC8
+FBC9
+FBCA
+FBCB
+FBCC
+FBCD
+FBCE
+FBCF
+FBD0
+FBD1
+FBD2
+FBD3
+FBD4
+FBD5
+FBD6
+FBD7
+FBD8
+FBD9
+FBDA
+FBDB
+FBDC
+FBDD
+FBDE
+FBDF
+FBE0
+FBE1
+FBE2
+FBE3
+FBE4
+FBE5
+FBE6
+FBE7
+FBE8
+FBE9
+FBEA
+FBEB
+FBEC
+FBED
+FBEE
+FBEF
+FBF0
+FBF1
+FBF2
+FBF3
+FBF4
+FBF5
+FBF6
+FBF7
+FBF8
+FBF9
+FBFA
+FBFB
+FBFC
+FBFD
+FBFE
+FCA1
+FCA2
+FCA3
+FCA4
+FCA5
+FCA6
+FCA7
+FCA8
+FCA9
+FCAA
+FCAB
+FCAC
+FCAD
+FCAE
+FCAF
+FCB0
+FCB1
+FCB2
+FCB3
+FCB4
+FCB5
+FCB6
+FCB7
+FCB8
+FCB9
+FCBA
+FCBB
+FCBC
+FCBD
+FCBE
+FCBF
+FCC0
+FCC1
+FCC2
+FCC3
+FCC4
+FCC5
+FCC6
+FCC7
+FCC8
+FCC9
+FCCA
+FCCB
+FCCC
+FCCD
+FCCE
+FCCF
+FCD0
+FCD1
+FCD2
+FCD3
+FCD4
+FCD5
+FCD6
+FCD7
+FCD8
+FCD9
+FCDA
+FCDB
+FCDC
+FCDD
+FCDE
+FCDF
+FCE0
+FCE1
+FCE2
+FCE3
+FCE4
+FCE5
+FCE6
+FCE7
+FCE8
+FCE9
+FCEA
+FCEB
+FCEC
+FCED
+FCEE
+FCEF
+FCF0
+FCF1
+FCF2
+FCF3
+FCF4
+FCF5
+FCF6
+FCF7
+FCF8
+FCF9
+FCFA
+FCFB
+FCFC
+FCFD
+FCFE
+FDA1
+FDA2
+FDA3
+FDA4
+FDA5
+FDA6
+FDA7
+FDA8
+FDA9
+FDAA
+FDAB
+FDAC
+FDAD
+FDAE
+FDAF
+FDB0
+FDB1
+FDB2
+FDB3
+FDB4
+FDB5
+FDB6
+FDB7
+FDB8
+FDB9
+FDBA
+FDBB
+FDBC
+FDBD
+FDBE
+FDBF
+FDC0
+FDC1
+FDC2
+FDC3
+FDC4
+FDC5
+FDC6
+FDC7
+FDC8
+FDC9
+FDCA
+FDCB
+FDCC
+FDCD
+FDCE
+FDCF
+FDD0
+FDD1
+FDD2
+FDD3
+FDD4
+FDD5
+FDD6
+FDD7
+FDD8
+FDD9
+FDDA
+FDDB
+FDDC
+FDDD
+FDDE
+FDDF
+FDE0
+FDE1
+FDE2
+FDE3
+FDE4
+FDE5
+FDE6
+FDE7
+FDE8
+FDE9
+FDEA
+FDEB
+FDEC
+FDED
+FDEE
+FDEF
+FDF0
+FDF1
+FDF2
+FDF3
+FDF4
+FDF5
+FDF6
+FDF7
+FDF8
+FDF9
+FDFA
+FDFB
+FDFC
+FDFD
+FDFE
+FEA1
+FEA2
+FEA3
+FEA4
+FEA5
+FEA6
+FEA7
+FEA8
+FEA9
+FEAA
+FEAB
+FEAC
+FEAD
+FEAE
+FEAF
+FEB0
+FEB1
+FEB2
+FEB3
+FEB4
+FEB5
+FEB6
+FEB7
+FEB8
+FEB9
+FEBA
+FEBB
+FEBC
+FEBD
+FEBE
+FEBF
+FEC0
+FEC1
+FEC2
+FEC3
+FEC4
+FEC5
+FEC6
+FEC7
+FEC8
+FEC9
+FECA
+FECB
+FECC
+FECD
+FECE
+FECF
+FED0
+FED1
+FED2
+FED3
+FED4
+FED5
+FED6
+FED7
+FED8
+FED9
+FEDA
+FEDB
+FEDC
+FEDD
+FEDE
+FEDF
+FEE0
+FEE1
+FEE2
+FEE3
+FEE4
+FEE5
+FEE6
+FEE7
+FEE8
+FEE9
+FEEA
+FEEB
+FEEC
+FEED
+FEEE
+FEEF
+FEF0
+FEF1
+FEF2
+FEF3
+FEF4
+FEF5
+FEF6
+FEF7
+FEF8
+FEF9
+FEFA
+FEFB
+FEFC
+FEFD
+FEFE
+8FF5A1
+8FF5A2
+8FF5A3
+8FF5A4
+8FF5A5
+8FF5A6
+8FF5A7
+8FF5A8
+8FF5A9
+8FF5AA
+8FF5AB
+8FF5AC
+8FF5AD
+8FF5AE
+8FF5AF
+8FF5B0
+8FF5B1
+8FF5B2
+8FF5B3
+8FF5B4
+8FF5B5
+8FF5B6
+8FF5B7
+8FF5B8
+8FF5B9
+8FF5BA
+8FF5BB
+8FF5BC
+8FF5BD
+8FF5BE
+8FF5BF
+8FF5C0
+8FF5C1
+8FF5C2
+8FF5C3
+8FF5C4
+8FF5C5
+8FF5C6
+8FF5C7
+8FF5C8
+8FF5C9
+8FF5CA
+8FF5CB
+8FF5CC
+8FF5CD
+8FF5CE
+8FF5CF
+8FF5D0
+8FF5D1
+8FF5D2
+8FF5D3
+8FF5D4
+8FF5D5
+8FF5D6
+8FF5D7
+8FF5D8
+8FF5D9
+8FF5DA
+8FF5DB
+8FF5DC
+8FF5DD
+8FF5DE
+8FF5DF
+8FF5E0
+8FF5E1
+8FF5E2
+8FF5E3
+8FF5E4
+8FF5E5
+8FF5E6
+8FF5E7
+8FF5E8
+8FF5E9
+8FF5EA
+8FF5EB
+8FF5EC
+8FF5ED
+8FF5EE
+8FF5EF
+8FF5F0
+8FF5F1
+8FF5F2
+8FF5F3
+8FF5F4
+8FF5F5
+8FF5F6
+8FF5F7
+8FF5F8
+8FF5F9
+8FF5FA
+8FF5FB
+8FF5FC
+8FF5FD
+8FF5FE
+8FF6A1
+8FF6A2
+8FF6A3
+8FF6A4
+8FF6A5
+8FF6A6
+8FF6A7
+8FF6A8
+8FF6A9
+8FF6AA
+8FF6AB
+8FF6AC
+8FF6AD
+8FF6AE
+8FF6AF
+8FF6B0
+8FF6B1
+8FF6B2
+8FF6B3
+8FF6B4
+8FF6B5
+8FF6B6
+8FF6B7
+8FF6B8
+8FF6B9
+8FF6BA
+8FF6BB
+8FF6BC
+8FF6BD
+8FF6BE
+8FF6BF
+8FF6C0
+8FF6C1
+8FF6C2
+8FF6C3
+8FF6C4
+8FF6C5
+8FF6C6
+8FF6C7
+8FF6C8
+8FF6C9
+8FF6CA
+8FF6CB
+8FF6CC
+8FF6CD
+8FF6CE
+8FF6CF
+8FF6D0
+8FF6D1
+8FF6D2
+8FF6D3
+8FF6D4
+8FF6D5
+8FF6D6
+8FF6D7
+8FF6D8
+8FF6D9
+8FF6DA
+8FF6DB
+8FF6DC
+8FF6DD
+8FF6DE
+8FF6DF
+8FF6E0
+8FF6E1
+8FF6E2
+8FF6E3
+8FF6E4
+8FF6E5
+8FF6E6
+8FF6E7
+8FF6E8
+8FF6E9
+8FF6EA
+8FF6EB
+8FF6EC
+8FF6ED
+8FF6EE
+8FF6EF
+8FF6F0
+8FF6F1
+8FF6F2
+8FF6F3
+8FF6F4
+8FF6F5
+8FF6F6
+8FF6F7
+8FF6F8
+8FF6F9
+8FF6FA
+8FF6FB
+8FF6FC
+8FF6FD
+8FF6FE
+8FF7A1
+8FF7A2
+8FF7A3
+8FF7A4
+8FF7A5
+8FF7A6
+8FF7A7
+8FF7A8
+8FF7A9
+8FF7AA
+8FF7AB
+8FF7AC
+8FF7AD
+8FF7AE
+8FF7AF
+8FF7B0
+8FF7B1
+8FF7B2
+8FF7B3
+8FF7B4
+8FF7B5
+8FF7B6
+8FF7B7
+8FF7B8
+8FF7B9
+8FF7BA
+8FF7BB
+8FF7BC
+8FF7BD
+8FF7BE
+8FF7BF
+8FF7C0
+8FF7C1
+8FF7C2
+8FF7C3
+8FF7C4
+8FF7C5
+8FF7C6
+8FF7C7
+8FF7C8
+8FF7C9
+8FF7CA
+8FF7CB
+8FF7CC
+8FF7CD
+8FF7CE
+8FF7CF
+8FF7D0
+8FF7D1
+8FF7D2
+8FF7D3
+8FF7D4
+8FF7D5
+8FF7D6
+8FF7D7
+8FF7D8
+8FF7D9
+8FF7DA
+8FF7DB
+8FF7DC
+8FF7DD
+8FF7DE
+8FF7DF
+8FF7E0
+8FF7E1
+8FF7E2
+8FF7E3
+8FF7E4
+8FF7E5
+8FF7E6
+8FF7E7
+8FF7E8
+8FF7E9
+8FF7EA
+8FF7EB
+8FF7EC
+8FF7ED
+8FF7EE
+8FF7EF
+8FF7F0
+8FF7F1
+8FF7F2
+8FF7F3
+8FF7F4
+8FF7F5
+8FF7F6
+8FF7F7
+8FF7F8
+8FF7F9
+8FF7FA
+8FF7FB
+8FF7FC
+8FF7FD
+8FF7FE
+8FF8A1
+8FF8A2
+8FF8A3
+8FF8A4
+8FF8A5
+8FF8A6
+8FF8A7
+8FF8A8
+8FF8A9
+8FF8AA
+8FF8AB
+8FF8AC
+8FF8AD
+8FF8AE
+8FF8AF
+8FF8B0
+8FF8B1
+8FF8B2
+8FF8B3
+8FF8B4
+8FF8B5
+8FF8B6
+8FF8B7
+8FF8B8
+8FF8B9
+8FF8BA
+8FF8BB
+8FF8BC
+8FF8BD
+8FF8BE
+8FF8BF
+8FF8C0
+8FF8C1
+8FF8C2
+8FF8C3
+8FF8C4
+8FF8C5
+8FF8C6
+8FF8C7
+8FF8C8
+8FF8C9
+8FF8CA
+8FF8CB
+8FF8CC
+8FF8CD
+8FF8CE
+8FF8CF
+8FF8D0
+8FF8D1
+8FF8D2
+8FF8D3
+8FF8D4
+8FF8D5
+8FF8D6
+8FF8D7
+8FF8D8
+8FF8D9
+8FF8DA
+8FF8DB
+8FF8DC
+8FF8DD
+8FF8DE
+8FF8DF
+8FF8E0
+8FF8E1
+8FF8E2
+8FF8E3
+8FF8E4
+8FF8E5
+8FF8E6
+8FF8E7
+8FF8E8
+8FF8E9
+8FF8EA
+8FF8EB
+8FF8EC
+8FF8ED
+8FF8EE
+8FF8EF
+8FF8F0
+8FF8F1
+8FF8F2
+8FF8F3
+8FF8F4
+8FF8F5
+8FF8F6
+8FF8F7
+8FF8F8
+8FF8F9
+8FF8FA
+8FF8FB
+8FF8FC
+8FF8FD
+8FF8FE
+8FF9A1
+8FF9A2
+8FF9A3
+8FF9A4
+8FF9A5
+8FF9A6
+8FF9A7
+8FF9A8
+8FF9A9
+8FF9AA
+8FF9AB
+8FF9AC
+8FF9AD
+8FF9AE
+8FF9AF
+8FF9B0
+8FF9B1
+8FF9B2
+8FF9B3
+8FF9B4
+8FF9B5
+8FF9B6
+8FF9B7
+8FF9B8
+8FF9B9
+8FF9BA
+8FF9BB
+8FF9BC
+8FF9BD
+8FF9BE
+8FF9BF
+8FF9C0
+8FF9C1
+8FF9C2
+8FF9C3
+8FF9C4
+8FF9C5
+8FF9C6
+8FF9C7
+8FF9C8
+8FF9C9
+8FF9CA
+8FF9CB
+8FF9CC
+8FF9CD
+8FF9CE
+8FF9CF
+8FF9D0
+8FF9D1
+8FF9D2
+8FF9D3
+8FF9D4
+8FF9D5
+8FF9D6
+8FF9D7
+8FF9D8
+8FF9D9
+8FF9DA
+8FF9DB
+8FF9DC
+8FF9DD
+8FF9DE
+8FF9DF
+8FF9E0
+8FF9E1
+8FF9E2
+8FF9E3
+8FF9E4
+8FF9E5
+8FF9E6
+8FF9E7
+8FF9E8
+8FF9E9
+8FF9EA
+8FF9EB
+8FF9EC
+8FF9ED
+8FF9EE
+8FF9EF
+8FF9F0
+8FF9F1
+8FF9F2
+8FF9F3
+8FF9F4
+8FF9F5
+8FF9F6
+8FF9F7
+8FF9F8
+8FF9F9
+8FF9FA
+8FF9FB
+8FF9FC
+8FF9FD
+8FF9FE
+8FFAA1
+8FFAA2
+8FFAA3
+8FFAA4
+8FFAA5
+8FFAA6
+8FFAA7
+8FFAA8
+8FFAA9
+8FFAAA
+8FFAAB
+8FFAAC
+8FFAAD
+8FFAAE
+8FFAAF
+8FFAB0
+8FFAB1
+8FFAB2
+8FFAB3
+8FFAB4
+8FFAB5
+8FFAB6
+8FFAB7
+8FFAB8
+8FFAB9
+8FFABA
+8FFABB
+8FFABC
+8FFABD
+8FFABE
+8FFABF
+8FFAC0
+8FFAC1
+8FFAC2
+8FFAC3
+8FFAC4
+8FFAC5
+8FFAC6
+8FFAC7
+8FFAC8
+8FFAC9
+8FFACA
+8FFACB
+8FFACC
+8FFACD
+8FFACE
+8FFACF
+8FFAD0
+8FFAD1
+8FFAD2
+8FFAD3
+8FFAD4
+8FFAD5
+8FFAD6
+8FFAD7
+8FFAD8
+8FFAD9
+8FFADA
+8FFADB
+8FFADC
+8FFADD
+8FFADE
+8FFADF
+8FFAE0
+8FFAE1
+8FFAE2
+8FFAE3
+8FFAE4
+8FFAE5
+8FFAE6
+8FFAE7
+8FFAE8
+8FFAE9
+8FFAEA
+8FFAEB
+8FFAEC
+8FFAED
+8FFAEE
+8FFAEF
+8FFAF0
+8FFAF1
+8FFAF2
+8FFAF3
+8FFAF4
+8FFAF5
+8FFAF6
+8FFAF7
+8FFAF8
+8FFAF9
+8FFAFA
+8FFAFB
+8FFAFC
+8FFAFD
+8FFAFE
+8FFBA1
+8FFBA2
+8FFBA3
+8FFBA4
+8FFBA5
+8FFBA6
+8FFBA7
+8FFBA8
+8FFBA9
+8FFBAA
+8FFBAB
+8FFBAC
+8FFBAD
+8FFBAE
+8FFBAF
+8FFBB0
+8FFBB1
+8FFBB2
+8FFBB3
+8FFBB4
+8FFBB5
+8FFBB6
+8FFBB7
+8FFBB8
+8FFBB9
+8FFBBA
+8FFBBB
+8FFBBC
+8FFBBD
+8FFBBE
+8FFBBF
+8FFBC0
+8FFBC1
+8FFBC2
+8FFBC3
+8FFBC4
+8FFBC5
+8FFBC6
+8FFBC7
+8FFBC8
+8FFBC9
+8FFBCA
+8FFBCB
+8FFBCC
+8FFBCD
+8FFBCE
+8FFBCF
+8FFBD0
+8FFBD1
+8FFBD2
+8FFBD3
+8FFBD4
+8FFBD5
+8FFBD6
+8FFBD7
+8FFBD8
+8FFBD9
+8FFBDA
+8FFBDB
+8FFBDC
+8FFBDD
+8FFBDE
+8FFBDF
+8FFBE0
+8FFBE1
+8FFBE2
+8FFBE3
+8FFBE4
+8FFBE5
+8FFBE6
+8FFBE7
+8FFBE8
+8FFBE9
+8FFBEA
+8FFBEB
+8FFBEC
+8FFBED
+8FFBEE
+8FFBEF
+8FFBF0
+8FFBF1
+8FFBF2
+8FFBF3
+8FFBF4
+8FFBF5
+8FFBF6
+8FFBF7
+8FFBF8
+8FFBF9
+8FFBFA
+8FFBFB
+8FFBFC
+8FFBFD
+8FFBFE
+8FFCA1
+8FFCA2
+8FFCA3
+8FFCA4
+8FFCA5
+8FFCA6
+8FFCA7
+8FFCA8
+8FFCA9
+8FFCAA
+8FFCAB
+8FFCAC
+8FFCAD
+8FFCAE
+8FFCAF
+8FFCB0
+8FFCB1
+8FFCB2
+8FFCB3
+8FFCB4
+8FFCB5
+8FFCB6
+8FFCB7
+8FFCB8
+8FFCB9
+8FFCBA
+8FFCBB
+8FFCBC
+8FFCBD
+8FFCBE
+8FFCBF
+8FFCC0
+8FFCC1
+8FFCC2
+8FFCC3
+8FFCC4
+8FFCC5
+8FFCC6
+8FFCC7
+8FFCC8
+8FFCC9
+8FFCCA
+8FFCCB
+8FFCCC
+8FFCCD
+8FFCCE
+8FFCCF
+8FFCD0
+8FFCD1
+8FFCD2
+8FFCD3
+8FFCD4
+8FFCD5
+8FFCD6
+8FFCD7
+8FFCD8
+8FFCD9
+8FFCDA
+8FFCDB
+8FFCDC
+8FFCDD
+8FFCDE
+8FFCDF
+8FFCE0
+8FFCE1
+8FFCE2
+8FFCE3
+8FFCE4
+8FFCE5
+8FFCE6
+8FFCE7
+8FFCE8
+8FFCE9
+8FFCEA
+8FFCEB
+8FFCEC
+8FFCED
+8FFCEE
+8FFCEF
+8FFCF0
+8FFCF1
+8FFCF2
+8FFCF3
+8FFCF4
+8FFCF5
+8FFCF6
+8FFCF7
+8FFCF8
+8FFCF9
+8FFCFA
+8FFCFB
+8FFCFC
+8FFCFD
+8FFCFE
+8FFDA1
+8FFDA2
+8FFDA3
+8FFDA4
+8FFDA5
+8FFDA6
+8FFDA7
+8FFDA8
+8FFDA9
+8FFDAA
+8FFDAB
+8FFDAC
+8FFDAD
+8FFDAE
+8FFDAF
+8FFDB0
+8FFDB1
+8FFDB2
+8FFDB3
+8FFDB4
+8FFDB5
+8FFDB6
+8FFDB7
+8FFDB8
+8FFDB9
+8FFDBA
+8FFDBB
+8FFDBC
+8FFDBD
+8FFDBE
+8FFDBF
+8FFDC0
+8FFDC1
+8FFDC2
+8FFDC3
+8FFDC4
+8FFDC5
+8FFDC6
+8FFDC7
+8FFDC8
+8FFDC9
+8FFDCA
+8FFDCB
+8FFDCC
+8FFDCD
+8FFDCE
+8FFDCF
+8FFDD0
+8FFDD1
+8FFDD2
+8FFDD3
+8FFDD4
+8FFDD5
+8FFDD6
+8FFDD7
+8FFDD8
+8FFDD9
+8FFDDA
+8FFDDB
+8FFDDC
+8FFDDD
+8FFDDE
+8FFDDF
+8FFDE0
+8FFDE1
+8FFDE2
+8FFDE3
+8FFDE4
+8FFDE5
+8FFDE6
+8FFDE7
+8FFDE8
+8FFDE9
+8FFDEA
+8FFDEB
+8FFDEC
+8FFDED
+8FFDEE
+8FFDEF
+8FFDF0
+8FFDF1
+8FFDF2
+8FFDF3
+8FFDF4
+8FFDF5
+8FFDF6
+8FFDF7
+8FFDF8
+8FFDF9
+8FFDFA
+8FFDFB
+8FFDFC
+8FFDFD
+8FFDFE
+8FFEA1
+8FFEA2
+8FFEA3
+8FFEA4
+8FFEA5
+8FFEA6
+8FFEA7
+8FFEA8
+8FFEA9
+8FFEAA
+8FFEAB
+8FFEAC
+8FFEAD
+8FFEAE
+8FFEAF
+8FFEB0
+8FFEB1
+8FFEB2
+8FFEB3
+8FFEB4
+8FFEB5
+8FFEB6
+8FFEB7
+8FFEB8
+8FFEB9
+8FFEBA
+8FFEBB
+8FFEBC
+8FFEBD
+8FFEBE
+8FFEBF
+8FFEC0
+8FFEC1
+8FFEC2
+8FFEC3
+8FFEC4
+8FFEC5
+8FFEC6
+8FFEC7
+8FFEC8
+8FFEC9
+8FFECA
+8FFECB
+8FFECC
+8FFECD
+8FFECE
+8FFECF
+8FFED0
+8FFED1
+8FFED2
+8FFED3
+8FFED4
+8FFED5
+8FFED6
+8FFED7
+8FFED8
+8FFED9
+8FFEDA
+8FFEDB
+8FFEDC
+8FFEDD
+8FFEDE
+8FFEDF
+8FFEE0
+8FFEE1
+8FFEE2
+8FFEE3
+8FFEE4
+8FFEE5
+8FFEE6
+8FFEE7
+8FFEE8
+8FFEE9
+8FFEEA
+8FFEEB
+8FFEEC
+8FFEED
+8FFEEE
+8FFEEF
+8FFEF0
+8FFEF1
+8FFEF2
+8FFEF3
+8FFEF4
+8FFEF5
+8FFEF6
+8FFEF7
+8FFEF8
+8FFEF9
+8FFEFA
+8FFEFB
+8FFEFC
+8FFEFD
+8FFEFE
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+DROP TABLE t4;
+RESET MASTER;
+CREATE TABLE t1(f1 blob);
+PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
+SET @var1= x'8300';
+EXECUTE stmt1 USING @var1;
+SHOW BINLOG EVENTS FROM 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 189 use `test`; CREATE TABLE t1(f1 blob)
+master-bin.000001 189 Table_map 1 228 test.t1
+master-bin.000001 228 Write_rows 1 262
+SELECT HEX(f1) FROM t1;
+HEX(f1)
+8300
+DROP table t1;
+SET collation_connection='cp932_japanese_ci';
+create table t1 select repeat('a',4000) a;
+delete from t1;
+insert into t1 values ('a'), ('a '), ('a\t');
+select collation(a),hex(a) from t1 order by a;
+collation(a) hex(a)
+cp932_japanese_ci 6109
+cp932_japanese_ci 61
+cp932_japanese_ci 6120
+drop table t1;
+SET collation_connection='cp932_bin';
+create table t1 select repeat('a',4000) a;
+delete from t1;
+insert into t1 values ('a'), ('a '), ('a\t');
+select collation(a),hex(a) from t1 order by a;
+collation(a) hex(a)
+cp932_bin 6109
+cp932_bin 61
+cp932_bin 6120
+drop table t1;
+create table t1 (col1 varchar(1)) character set cp932;
+insert into t1 values ('a');
+insert into t1 values ('ab');
+Warnings:
+Warning 1265 Data truncated for column 'col1' at row 1
+select * from t1;
+col1
+a
+a
+insert into t1 values ('abc');
+Warnings:
+Warning 1265 Data truncated for column 'col1' at row 1
+select * from t1;
+col1
+a
+a
+a
diff --git a/mysql-test/r/binlog_row_ctype_ucs.result b/mysql-test/r/binlog_row_ctype_ucs.result
new file mode 100644
index 00000000000..12f7062d38a
--- /dev/null
+++ b/mysql-test/r/binlog_row_ctype_ucs.result
@@ -0,0 +1,16 @@
+SET TIMESTAMP=10000;
+create table t2 (c char(30)) charset=ucs2;
+set @v=convert('abc' using ucs2);
+reset master;
+insert into t2 values (@v);
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Table_map 1 141 test.t2
+master-bin.000001 141 Write_rows 1 231
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ROLLBACK;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+drop table t2;
diff --git a/mysql-test/r/binlog_row_drop_tmp_tbl.result b/mysql-test/r/binlog_row_drop_tmp_tbl.result
new file mode 100644
index 00000000000..2b09fe069e3
--- /dev/null
+++ b/mysql-test/r/binlog_row_drop_tmp_tbl.result
@@ -0,0 +1,18 @@
+drop database if exists `drop-temp+table-test`;
+reset master;
+create database `drop-temp+table-test`;
+use `drop-temp+table-test`;
+create temporary table shortn1 (a int);
+create temporary table `table:name` (a int);
+create temporary table shortn2 (a int);
+select get_lock("a",10);
+get_lock("a",10)
+1
+select get_lock("a",10);
+get_lock("a",10)
+1
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
+master-bin.000001 # Query 1 # create database `drop-temp+table-test`
+drop database `drop-temp+table-test`;
diff --git a/mysql-test/r/binlog_row_innodb_stat.result b/mysql-test/r/binlog_row_innodb_stat.result
new file mode 100644
index 00000000000..e6813ee2719
--- /dev/null
+++ b/mysql-test/r/binlog_row_innodb_stat.result
@@ -0,0 +1,39 @@
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 0
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 0
+drop table if exists t1;
+create table t1 (a int) engine=innodb;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 1
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 1
+begin;
+delete from t1;
+commit;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 2
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 1
+drop table t1;
+show status like "Innodb_buffer_pool_pages_total";
+Variable_name Value
+Innodb_buffer_pool_pages_total 512
+show status like "Innodb_page_size";
+Variable_name Value
+Innodb_page_size 16384
+show status like "Innodb_rows_deleted";
+Variable_name Value
+Innodb_rows_deleted 2000
+show status like "Innodb_rows_inserted";
+Variable_name Value
+Innodb_rows_inserted 2000
+show status like "Innodb_rows_updated";
+Variable_name Value
+Innodb_rows_updated 0
diff --git a/mysql-test/r/binlog_row_insert_select.result b/mysql-test/r/binlog_row_insert_select.result
new file mode 100644
index 00000000000..27c515e5781
--- /dev/null
+++ b/mysql-test/r/binlog_row_insert_select.result
@@ -0,0 +1,26 @@
+create table t1(a int, unique(a));
+insert into t1 values(2);
+create table t2(a int);
+insert into t2 values(1),(2);
+reset master;
+insert into t1 select * from t2;
+ERROR 23000: Duplicate entry '2' for key 1
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 4 Format_desc 1 102 Server ver: VERSION, Binlog ver: 4
+master-bin.000001 102 Table_map 1 141 test.t1
+master-bin.000001 141 Write_rows 1 175
+select * from t1;
+a
+1
+2
+drop table t1, t2;
+create table t1(a int);
+insert into t1 values(1),(1);
+reset master;
+create table t2(unique(a)) select a from t1;
+ERROR 23000: Duplicate entry '1' for key 1
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 4 Format_desc 1 102 Server ver: VERSION, Binlog ver: 4
+drop table t1;
diff --git a/mysql-test/r/binlog_row_mix_innodb_myisam.result b/mysql-test/r/binlog_row_mix_innodb_myisam.result
new file mode 100644
index 00000000000..3a26d84d575
--- /dev/null
+++ b/mysql-test/r/binlog_row_mix_innodb_myisam.result
@@ -0,0 +1,282 @@
+drop table if exists t1, t2;
+create table t1 (a int) engine=innodb;
+create table t2 (a int) engine=myisam;
+reset master;
+begin;
+insert into t1 values(1);
+insert into t2 select * from t1;
+commit;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Table_map 1 # test.t1
+master-bin.000001 209 Write_rows 1 #
+master-bin.000001 243 Table_map 1 # test.t2
+master-bin.000001 282 Write_rows 1 #
+master-bin.000001 316 Xid 1 # COMMIT /* xid= */
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(2);
+insert into t2 select * from t1;
+rollback;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Table_map 1 # test.t1
+master-bin.000001 209 Write_rows 1 #
+master-bin.000001 243 Table_map 1 # test.t2
+master-bin.000001 282 Write_rows 1 #
+master-bin.000001 316 Query 1 # use `test`; ROLLBACK
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(3);
+savepoint my_savepoint;
+insert into t1 values(4);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+commit;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Table_map 1 # test.t1
+master-bin.000001 209 Write_rows 1 #
+master-bin.000001 243 Query 1 # use `test`; savepoint my_savepoint
+master-bin.000001 328 Table_map 1 # test.t1
+master-bin.000001 367 Write_rows 1 #
+master-bin.000001 401 Table_map 1 # test.t2
+master-bin.000001 440 Write_rows 1 #
+master-bin.000001 479 Query 1 # use `test`; rollback to savepoint my_savepoint
+master-bin.000001 576 Xid 1 # COMMIT /* xid= */
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(5);
+savepoint my_savepoint;
+insert into t1 values(6);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+insert into t1 values(7);
+commit;
+select a from t1 order by a;
+a
+5
+7
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Table_map 1 # test.t1
+master-bin.000001 209 Write_rows 1 #
+master-bin.000001 243 Query 1 # use `test`; savepoint my_savepoint
+master-bin.000001 328 Table_map 1 # test.t1
+master-bin.000001 367 Write_rows 1 #
+master-bin.000001 401 Table_map 1 # test.t2
+master-bin.000001 440 Write_rows 1 #
+master-bin.000001 479 Query 1 # use `test`; rollback to savepoint my_savepoint
+master-bin.000001 576 Table_map 1 # test.t1
+master-bin.000001 615 Write_rows 1 #
+master-bin.000001 649 Xid 1 # COMMIT /* xid= */
+delete from t1;
+delete from t2;
+reset master;
+select get_lock("a",10);
+get_lock("a",10)
+1
+begin;
+insert into t1 values(8);
+insert into t2 select * from t1;
+select get_lock("a",10);
+get_lock("a",10)
+1
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Table_map 1 # test.t1
+master-bin.000001 209 Write_rows 1 #
+master-bin.000001 243 Table_map 1 # test.t2
+master-bin.000001 282 Write_rows 1 #
+master-bin.000001 316 Query 1 # use `test`; ROLLBACK
+delete from t1;
+delete from t2;
+reset master;
+insert into t1 values(9);
+insert into t2 select * from t1;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Table_map 1 # test.t1
+master-bin.000001 141 Write_rows 1 #
+master-bin.000001 175 Xid 1 # COMMIT /* xid= */
+master-bin.000001 202 Table_map 1 # test.t2
+master-bin.000001 241 Write_rows 1 #
+delete from t1;
+delete from t2;
+reset master;
+insert into t1 values(10);
+begin;
+insert into t2 select * from t1;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Table_map 1 # test.t1
+master-bin.000001 141 Write_rows 1 #
+master-bin.000001 175 Xid 1 # COMMIT /* xid= */
+master-bin.000001 202 Table_map 1 # test.t2
+master-bin.000001 241 Write_rows 1 #
+insert into t1 values(11);
+commit;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Table_map 1 # test.t1
+master-bin.000001 141 Write_rows 1 #
+master-bin.000001 175 Xid 1 # COMMIT /* xid= */
+master-bin.000001 202 Table_map 1 # test.t2
+master-bin.000001 241 Write_rows 1 #
+master-bin.000001 275 Query 1 # use `test`; BEGIN
+master-bin.000001 343 Table_map 1 # test.t1
+master-bin.000001 382 Write_rows 1 #
+master-bin.000001 416 Xid 1 # COMMIT /* xid= */
+alter table t2 engine=INNODB;
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(12);
+insert into t2 select * from t1;
+commit;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Table_map 1 # test.t1
+master-bin.000001 209 Write_rows 1 #
+master-bin.000001 243 Table_map 1 # test.t2
+master-bin.000001 282 Write_rows 1 #
+master-bin.000001 316 Xid 1 # COMMIT /* xid= */
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(13);
+insert into t2 select * from t1;
+rollback;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(14);
+savepoint my_savepoint;
+insert into t1 values(15);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+commit;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Table_map 1 # test.t1
+master-bin.000001 209 Write_rows 1 #
+master-bin.000001 243 Xid 1 # COMMIT /* xid= */
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(16);
+savepoint my_savepoint;
+insert into t1 values(17);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+insert into t1 values(18);
+commit;
+select a from t1 order by a;
+a
+16
+18
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Table_map 1 # test.t1
+master-bin.000001 209 Write_rows 1 #
+master-bin.000001 243 Table_map 1 # test.t1
+master-bin.000001 282 Write_rows 1 #
+master-bin.000001 316 Xid 1 # COMMIT /* xid= */
+delete from t1;
+delete from t2;
+alter table t2 type=MyISAM;
+insert into t1 values (1);
+begin;
+select * from t1 for update;
+a
+1
+select (@before:=unix_timestamp())*0;
+(@before:=unix_timestamp())*0
+0
+begin;
+ select * from t1 for update;
+insert into t2 values (20);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+select (@after:=unix_timestamp())*0;
+(@after:=unix_timestamp())*0
+0
+select (@after-@before) >= 2;
+(@after-@before) >= 2
+1
+drop table t1,t2;
+commit;
+begin;
+create temporary table ti (a int) engine=innodb;
+rollback;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+insert into ti values(1);
+set autocommit=0;
+create temporary table t1 (a int) engine=myisam;
+commit;
+insert t1 values (1);
+rollback;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+create table t0 (n int);
+insert t0 select * from t1;
+set autocommit=1;
+insert into t0 select GET_LOCK("lock1",null);
+set autocommit=0;
+create table t2 (n int) engine=innodb;
+insert into t2 values (3);
+select get_lock("lock1",60);
+get_lock("lock1",60)
+1
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Table_map 1 # test.t1
+master-bin.000001 209 Write_rows 1 #
+master-bin.000001 243 Table_map 1 # test.t1
+master-bin.000001 282 Write_rows 1 #
+master-bin.000001 316 Xid 1 # COMMIT /* xid= */
+master-bin.000001 343 Table_map 1 # test.t1
+master-bin.000001 382 Delete_rows 1 #
+master-bin.000001 421 Xid 1 # COMMIT /* xid= */
+master-bin.000001 448 Query 1 # use `test`; alter table t2 type=MyISAM
+master-bin.000001 537 Table_map 1 # test.t1
+master-bin.000001 576 Write_rows 1 #
+master-bin.000001 610 Xid 1 # COMMIT /* xid= */
+master-bin.000001 637 Table_map 1 # test.t2
+master-bin.000001 676 Write_rows 1 #
+master-bin.000001 710 Query 1 # use `test`; drop table t1,t2
+master-bin.000001 789 Query 1 # use `test`; create table t0 (n int)
+master-bin.000001 875 Table_map 1 # test.t0
+master-bin.000001 914 Write_rows 1 #
+master-bin.000001 948 Table_map 1 # test.t0
+master-bin.000001 987 Write_rows 1 #
+master-bin.000001 1021 Query 1 # use `test`; create table t2 (n int) engine=innodb
+do release_lock("lock1");
+drop table t0,t2;
diff --git a/mysql-test/r/binlog.result b/mysql-test/r/binlog_stm_binlog.result
index 5d5b78abe29..80de6b6eaa9 100644
--- a/mysql-test/r/binlog.result
+++ b/mysql-test/r/binlog_stm_binlog.result
@@ -8,7 +8,7 @@ commit;
begin;
insert t2 values (5);
commit;
-show binlog events from 98;
+show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t1 (a int) engine=bdb
master-bin.000001 # Query 1 # use `test`; create table t2 (a int) engine=innodb
@@ -17,14 +17,14 @@ master-bin.000001 # Query 1 # use `test`; insert t1 values (5)
master-bin.000001 # Query 1 # use `test`; COMMIT
master-bin.000001 # Query 1 # use `test`; BEGIN
master-bin.000001 # Query 1 # use `test`; insert t2 values (5)
-master-bin.000001 # Xid 1 # COMMIT /* xid=11 */
+master-bin.000001 # Xid 1 # COMMIT /* xid= */
drop table t1,t2;
reset master;
create table t1 (n int) engine=innodb;
begin;
commit;
drop table t1;
-show binlog events in 'master-bin.000001' from 98;
+show binlog events in 'master-bin.000001' from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t1 (n int) engine=innodb
master-bin.000001 # Query 1 # use `test`; BEGIN
@@ -128,8 +128,8 @@ master-bin.000001 # Query 1 # use `test`; insert into t1 values(4 + 4)
master-bin.000001 # Query 1 # use `test`; insert into t1 values(3 + 4)
master-bin.000001 # Query 1 # use `test`; insert into t1 values(2 + 4)
master-bin.000001 # Query 1 # use `test`; insert into t1 values(1 + 4)
-master-bin.000001 # Xid 1 # COMMIT /* xid=18 */
+master-bin.000001 # Xid 1 # COMMIT /* xid= */
master-bin.000001 # Rotate 1 # master-bin.000002;pos=4
-show binlog events in 'master-bin.000002' from 98;
+show binlog events in 'master-bin.000002' from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000002 # Query 1 # use `test`; drop table t1
diff --git a/mysql-test/r/blackhole.result b/mysql-test/r/binlog_stm_blackhole.result
index 7b6e61984ec..7b6e61984ec 100644
--- a/mysql-test/r/blackhole.result
+++ b/mysql-test/r/binlog_stm_blackhole.result
diff --git a/mysql-test/r/ctype_cp932.result b/mysql-test/r/binlog_stm_ctype_cp932.result
index 1afceb86381..146fb2ca2d5 100755
--- a/mysql-test/r/ctype_cp932.result
+++ b/mysql-test/r/binlog_stm_ctype_cp932.result
@@ -11320,11 +11320,11 @@ CREATE TABLE t1(f1 blob);
PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
SET @var1= x'8300';
EXECUTE stmt1 USING @var1;
-SHOW BINLOG EVENTS FROM 98;
+SHOW BINLOG EVENTS FROM 102;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 185 use `test`; CREATE TABLE t1(f1 blob)
-master-bin.000001 185 User var 1 224 @`var1`=_binary 0x8300 COLLATE binary
-master-bin.000001 224 Query 1 317 use `test`; INSERT INTO t1 VALUES(@'var1')
+master-bin.000001 102 Query 1 189 use `test`; CREATE TABLE t1(f1 blob)
+master-bin.000001 189 User var 1 228 @`var1`=_binary 0x8300 COLLATE binary
+master-bin.000001 228 Query 1 321 use `test`; INSERT INTO t1 VALUES(@'var1')
SELECT HEX(f1) FROM t1;
HEX(f1)
8300
diff --git a/mysql-test/r/ctype_ucs_binlog.result b/mysql-test/r/binlog_stm_ctype_ucs.result
index 14220a7df13..e4448efa7ab 100644
--- a/mysql-test/r/ctype_ucs_binlog.result
+++ b/mysql-test/r/binlog_stm_ctype_ucs.result
@@ -3,10 +3,10 @@ create table t2 (c char(30)) charset=ucs2;
set @v=convert('abc' using ucs2);
reset master;
insert into t2 values (@v);
-show binlog events from 98;
+show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 User var 1 138 @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ci
-master-bin.000001 138 Query 1 227 use `test`; insert into t2 values (@v)
+master-bin.000001 102 User var 1 142 @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ci
+master-bin.000001 142 Query 1 231 use `test`; insert into t2 values (@v)
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
ROLLBACK;
diff --git a/mysql-test/r/drop_temp_table.result b/mysql-test/r/binlog_stm_drop_tmp_tbl.result
index 96481341bd6..96481341bd6 100644
--- a/mysql-test/r/drop_temp_table.result
+++ b/mysql-test/r/binlog_stm_drop_tmp_tbl.result
diff --git a/mysql-test/r/binlog_stm_innodb_stat.result b/mysql-test/r/binlog_stm_innodb_stat.result
new file mode 100644
index 00000000000..e6813ee2719
--- /dev/null
+++ b/mysql-test/r/binlog_stm_innodb_stat.result
@@ -0,0 +1,39 @@
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 0
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 0
+drop table if exists t1;
+create table t1 (a int) engine=innodb;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 1
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 1
+begin;
+delete from t1;
+commit;
+show status like "binlog_cache_use";
+Variable_name Value
+Binlog_cache_use 2
+show status like "binlog_cache_disk_use";
+Variable_name Value
+Binlog_cache_disk_use 1
+drop table t1;
+show status like "Innodb_buffer_pool_pages_total";
+Variable_name Value
+Innodb_buffer_pool_pages_total 512
+show status like "Innodb_page_size";
+Variable_name Value
+Innodb_page_size 16384
+show status like "Innodb_rows_deleted";
+Variable_name Value
+Innodb_rows_deleted 2000
+show status like "Innodb_rows_inserted";
+Variable_name Value
+Innodb_rows_inserted 2000
+show status like "Innodb_rows_updated";
+Variable_name Value
+Innodb_rows_updated 0
diff --git a/mysql-test/r/insert_select-binlog.result b/mysql-test/r/binlog_stm_insert_select.result
index 76f460b1de2..42bba580f47 100644
--- a/mysql-test/r/insert_select-binlog.result
+++ b/mysql-test/r/binlog_stm_insert_select.result
@@ -7,8 +7,8 @@ insert into t1 select * from t2;
ERROR 23000: Duplicate entry '2' for key 1
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 4 Format_desc 1 98 Server ver: VERSION, Binlog ver: 4
-master-bin.000001 98 Query 1 192 use `test`; insert into t1 select * from t2
+master-bin.000001 4 Format_desc 1 102 Server ver: VERSION, Binlog ver: 4
+master-bin.000001 102 Query 1 196 use `test`; insert into t1 select * from t2
select * from t1;
a
1
@@ -21,5 +21,5 @@ create table t2(unique(a)) select a from t1;
ERROR 23000: Duplicate entry '1' for key 1
show binlog events;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 4 Format_desc 1 98 Server ver: VERSION, Binlog ver: 4
+master-bin.000001 4 Format_desc 1 102 Server ver: VERSION, Binlog ver: 4
drop table t1;
diff --git a/mysql-test/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/r/binlog_stm_mix_innodb_myisam.result
new file mode 100644
index 00000000000..5d75bf79990
--- /dev/null
+++ b/mysql-test/r/binlog_stm_mix_innodb_myisam.result
@@ -0,0 +1,258 @@
+drop table if exists t1, t2;
+create table t1 (a int) engine=innodb;
+create table t2 (a int) engine=myisam;
+reset master;
+begin;
+insert into t1 values(1);
+insert into t2 select * from t1;
+commit;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Query 1 # use `test`; insert into t1 values(1)
+master-bin.000001 257 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 351 Xid 1 # COMMIT /* xid= */
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(2);
+insert into t2 select * from t1;
+rollback;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Query 1 # use `test`; insert into t1 values(2)
+master-bin.000001 257 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 351 Query 1 # use `test`; ROLLBACK
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(3);
+savepoint my_savepoint;
+insert into t1 values(4);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+commit;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Query 1 # use `test`; insert into t1 values(3)
+master-bin.000001 257 Query 1 # use `test`; savepoint my_savepoint
+master-bin.000001 342 Query 1 # use `test`; insert into t1 values(4)
+master-bin.000001 429 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 523 Query 1 # use `test`; rollback to savepoint my_savepoint
+master-bin.000001 620 Xid 1 # COMMIT /* xid= */
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(5);
+savepoint my_savepoint;
+insert into t1 values(6);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+insert into t1 values(7);
+commit;
+select a from t1 order by a;
+a
+5
+7
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Query 1 # use `test`; insert into t1 values(5)
+master-bin.000001 257 Query 1 # use `test`; savepoint my_savepoint
+master-bin.000001 342 Query 1 # use `test`; insert into t1 values(6)
+master-bin.000001 429 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 523 Query 1 # use `test`; rollback to savepoint my_savepoint
+master-bin.000001 620 Query 1 # use `test`; insert into t1 values(7)
+master-bin.000001 707 Xid 1 # COMMIT /* xid= */
+delete from t1;
+delete from t2;
+reset master;
+select get_lock("a",10);
+get_lock("a",10)
+1
+begin;
+insert into t1 values(8);
+insert into t2 select * from t1;
+select get_lock("a",10);
+get_lock("a",10)
+1
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Query 1 # use `test`; insert into t1 values(8)
+master-bin.000001 257 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 351 Query 1 # use `test`; ROLLBACK
+delete from t1;
+delete from t2;
+reset master;
+insert into t1 values(9);
+insert into t2 select * from t1;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; insert into t1 values(9)
+master-bin.000001 189 Xid 1 # COMMIT /* xid= */
+master-bin.000001 216 Query 1 # use `test`; insert into t2 select * from t1
+delete from t1;
+delete from t2;
+reset master;
+insert into t1 values(10);
+begin;
+insert into t2 select * from t1;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; insert into t1 values(10)
+master-bin.000001 190 Xid 1 # COMMIT /* xid= */
+master-bin.000001 217 Query 1 # use `test`; insert into t2 select * from t1
+insert into t1 values(11);
+commit;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; insert into t1 values(10)
+master-bin.000001 190 Xid 1 # COMMIT /* xid= */
+master-bin.000001 217 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 311 Query 1 # use `test`; BEGIN
+master-bin.000001 379 Query 1 # use `test`; insert into t1 values(11)
+master-bin.000001 467 Xid 1 # COMMIT /* xid= */
+alter table t2 engine=INNODB;
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(12);
+insert into t2 select * from t1;
+commit;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Query 1 # use `test`; insert into t1 values(12)
+master-bin.000001 258 Query 1 # use `test`; insert into t2 select * from t1
+master-bin.000001 352 Xid 1 # COMMIT /* xid= */
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(13);
+insert into t2 select * from t1;
+rollback;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(14);
+savepoint my_savepoint;
+insert into t1 values(15);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+commit;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Query 1 # use `test`; insert into t1 values(14)
+master-bin.000001 258 Xid 1 # COMMIT /* xid= */
+delete from t1;
+delete from t2;
+reset master;
+begin;
+insert into t1 values(16);
+savepoint my_savepoint;
+insert into t1 values(17);
+insert into t2 select * from t1;
+rollback to savepoint my_savepoint;
+insert into t1 values(18);
+commit;
+select a from t1 order by a;
+a
+16
+18
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Query 1 # use `test`; insert into t1 values(16)
+master-bin.000001 258 Query 1 # use `test`; insert into t1 values(18)
+master-bin.000001 346 Xid 1 # COMMIT /* xid= */
+delete from t1;
+delete from t2;
+alter table t2 type=MyISAM;
+insert into t1 values (1);
+begin;
+select * from t1 for update;
+a
+1
+select (@before:=unix_timestamp())*0;
+(@before:=unix_timestamp())*0
+0
+begin;
+ select * from t1 for update;
+insert into t2 values (20);
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+select (@after:=unix_timestamp())*0;
+(@after:=unix_timestamp())*0
+0
+select (@after-@before) >= 2;
+(@after-@before) >= 2
+1
+drop table t1,t2;
+commit;
+begin;
+create temporary table ti (a int) engine=innodb;
+rollback;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+insert into ti values(1);
+set autocommit=0;
+create temporary table t1 (a int) engine=myisam;
+commit;
+insert t1 values (1);
+rollback;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+create table t0 (n int);
+insert t0 select * from t1;
+set autocommit=1;
+insert into t0 select GET_LOCK("lock1",null);
+set autocommit=0;
+create table t2 (n int) engine=innodb;
+insert into t2 values (3);
+select get_lock("lock1",60);
+get_lock("lock1",60)
+1
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 102 Query 1 # use `test`; BEGIN
+master-bin.000001 170 Query 1 # use `test`; insert into t1 values(16)
+master-bin.000001 258 Query 1 # use `test`; insert into t1 values(18)
+master-bin.000001 346 Xid 1 # COMMIT /* xid= */
+master-bin.000001 373 Query 1 # use `test`; delete from t1
+master-bin.000001 450 Xid 1 # COMMIT /* xid= */
+master-bin.000001 477 Query 1 # use `test`; delete from t2
+master-bin.000001 554 Xid 1 # COMMIT /* xid= */
+master-bin.000001 581 Query 1 # use `test`; alter table t2 type=MyISAM
+master-bin.000001 670 Query 1 # use `test`; insert into t1 values (1)
+master-bin.000001 758 Xid 1 # COMMIT /* xid= */
+master-bin.000001 785 Query 1 # use `test`; insert into t2 values (20)
+master-bin.000001 874 Query 1 # use `test`; drop table t1,t2
+master-bin.000001 953 Query 1 # use `test`; create temporary table ti (a int) engine=innodb
+master-bin.000001 1063 Query 1 # use `test`; insert into ti values(1)
+master-bin.000001 1150 Xid 1 # COMMIT /* xid= */
+master-bin.000001 1177 Query 1 # use `test`; create temporary table t1 (a int) engine=myisam
+master-bin.000001 1287 Query 1 # use `test`; insert t1 values (1)
+master-bin.000001 1370 Query 1 # use `test`; create table t0 (n int)
+master-bin.000001 1456 Query 1 # use `test`; insert t0 select * from t1
+master-bin.000001 1545 Query 1 # use `test`; insert into t0 select GET_LOCK("lock1",null)
+master-bin.000001 1652 Query 1 # use `test`; create table t2 (n int) engine=innodb
+master-bin.000001 1752 Query 1 # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `test`.`t1`,`test`.`ti`
+do release_lock("lock1");
+drop table t0,t2;
diff --git a/mysql-test/r/ctype_cp932_binlog.result b/mysql-test/r/ctype_cp932_binlog_row.result
index d04fce7738c..913e8125619 100644
--- a/mysql-test/r/ctype_cp932_binlog.result
+++ b/mysql-test/r/ctype_cp932_binlog_row.result
@@ -6,11 +6,11 @@ CREATE TABLE t1(f1 blob);
PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
SET @var1= x'8300';
EXECUTE stmt1 USING @var1;
-SHOW BINLOG EVENTS FROM 98;
+SHOW BINLOG EVENTS FROM 102;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 185 use `test`; CREATE TABLE t1(f1 blob)
-master-bin.000001 185 User var 1 224 @`var1`=_binary 0x8300 COLLATE binary
-master-bin.000001 224 Query 1 317 use `test`; INSERT INTO t1 VALUES(@'var1')
+master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1(f1 blob)
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
SELECT HEX(f1) FROM t1;
HEX(f1)
8300
diff --git a/mysql-test/r/ctype_cp932_binlog_stm.result b/mysql-test/r/ctype_cp932_binlog_stm.result
new file mode 100644
index 00000000000..4ea1ecb6999
--- /dev/null
+++ b/mysql-test/r/ctype_cp932_binlog_stm.result
@@ -0,0 +1,17 @@
+drop table if exists t1;
+set names cp932;
+set character_set_database = cp932;
+RESET MASTER;
+CREATE TABLE t1(f1 blob);
+PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
+SET @var1= x'8300';
+EXECUTE stmt1 USING @var1;
+SHOW BINLOG EVENTS FROM 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1(f1 blob)
+master-bin.000001 # User var 1 # @`var1`=_binary 0x8300 COLLATE binary
+master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES(@'var1')
+SELECT HEX(f1) FROM t1;
+HEX(f1)
+8300
+DROP table t1;
diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result
index bc289f18169..434a5df1e17 100644
--- a/mysql-test/r/date_formats.result
+++ b/mysql-test/r/date_formats.result
@@ -1,12 +1,14 @@
drop table if exists t1;
SHOW GLOBAL VARIABLES LIKE "%_format%";
Variable_name Value
+binlog_format <format>
date_format %d.%m.%Y
datetime_format %Y-%m-%d %H:%i:%s
default_week_format 0
time_format %H.%i.%s
SHOW SESSION VARIABLES LIKE "%_format%";
Variable_name Value
+binlog_format <format>
date_format %d.%m.%Y
datetime_format %Y-%m-%d %H:%i:%s
default_week_format 0
@@ -30,6 +32,7 @@ set datetime_format= '%h:%i:%s %p %Y-%m-%d';
set datetime_format= '%h:%i:%s.%f %p %Y-%m-%d';
SHOW SESSION VARIABLES LIKE "%format";
Variable_name Value
+binlog_format <format>
date_format %m-%d-%Y
datetime_format %h:%i:%s.%f %p %Y-%m-%d
default_week_format 0
diff --git a/mysql-test/r/flush_block_commit.result b/mysql-test/r/flush_block_commit.result
index 2f6aca7e24a..e4a9dfcfff1 100644
--- a/mysql-test/r/flush_block_commit.result
+++ b/mysql-test/r/flush_block_commit.result
@@ -44,11 +44,11 @@ insert t1 values (1);
flush tables with read lock;
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 98
+master-bin.000001 102
commit;
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 98
+master-bin.000001 102
unlock tables;
drop table t1;
set autocommit=1;
diff --git a/mysql-test/r/have_binlog_format_row.require b/mysql-test/r/have_binlog_format_row.require
new file mode 100644
index 00000000000..09ad32dbb9a
--- /dev/null
+++ b/mysql-test/r/have_binlog_format_row.require
@@ -0,0 +1,2 @@
+Variable_name Value
+binlog_format ROW
diff --git a/mysql-test/r/have_binlog_format_statement.require b/mysql-test/r/have_binlog_format_statement.require
new file mode 100644
index 00000000000..81e2e31cd6c
--- /dev/null
+++ b/mysql-test/r/have_binlog_format_statement.require
@@ -0,0 +1,2 @@
+Variable_name Value
+binlog_format STATEMENT
diff --git a/mysql-test/r/have_row_based.require b/mysql-test/r/have_row_based.require
new file mode 100644
index 00000000000..c71451a95c3
--- /dev/null
+++ b/mysql-test/r/have_row_based.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_row_based_replication YES
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 3c08d2bccfa..ed4c14388ab 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1640,29 +1640,6 @@ t2 CREATE TABLE `t2` (
CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`b`) REFERENCES `t1` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t2, t1;
-show status like "binlog_cache_use";
-Variable_name Value
-Binlog_cache_use 155
-show status like "binlog_cache_disk_use";
-Variable_name Value
-Binlog_cache_disk_use 0
-create table t1 (a int) engine=innodb;
-show status like "binlog_cache_use";
-Variable_name Value
-Binlog_cache_use 156
-show status like "binlog_cache_disk_use";
-Variable_name Value
-Binlog_cache_disk_use 1
-begin;
-delete from t1;
-commit;
-show status like "binlog_cache_use";
-Variable_name Value
-Binlog_cache_use 157
-show status like "binlog_cache_disk_use";
-Variable_name Value
-Binlog_cache_disk_use 1
-drop table t1;
create table t1 (c char(10), index (c,c)) engine=innodb;
ERROR 42S21: Duplicate column name 'c'
create table t1 (c1 char(10), c2 char(10), index (c1,c2,c1)) engine=innodb;
@@ -1774,21 +1751,6 @@ select count(*) from t1 where x = 18446744073709551601;
count(*)
1
drop table t1;
-show status like "Innodb_buffer_pool_pages_total";
-Variable_name Value
-Innodb_buffer_pool_pages_total 512
-show status like "Innodb_page_size";
-Variable_name Value
-Innodb_page_size 16384
-show status like "Innodb_rows_deleted";
-Variable_name Value
-Innodb_rows_deleted 2070
-show status like "Innodb_rows_inserted";
-Variable_name Value
-Innodb_rows_inserted 31727
-show status like "Innodb_rows_updated";
-Variable_name Value
-Innodb_rows_updated 29530
show status like "Innodb_row_lock_waits";
Variable_name Value
Innodb_row_lock_waits 0
diff --git a/mysql-test/r/innodb_concurrent.result b/mysql-test/r/innodb_concurrent.result
new file mode 100644
index 00000000000..8e9d2e2ffe6
--- /dev/null
+++ b/mysql-test/r/innodb_concurrent.result
@@ -0,0 +1,621 @@
+drop table if exists t1;
+Warnings:
+Note 1051 Unknown table 't1'
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+Warnings:
+Warning 1287 'TYPE=storage_engine' is deprecated; use 'ENGINE=storage_engine' instead
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",1);
+get_lock("hello",1)
+1
+begin;
+ update t1 set eta=1+get_lock("hello",1)*0 where tipo=11;
+begin;
+update t1 set eta=2 where tipo=22;
+select release_lock("hello");
+release_lock("hello")
+1
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+2 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+1 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+ commit;
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+2 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+commit;
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+2 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+1 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+2 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+1 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+2 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+1 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+drop table t1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+Warnings:
+Warning 1287 'TYPE=storage_engine' is deprecated; use 'ENGINE=storage_engine' instead
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",10);
+get_lock("hello",10)
+0
+begin;
+ update t1 set eta=1+get_lock("hello",10)*0 where tipo=1;
+begin;
+update t1 set tipo=1 where tipo=2;
+select release_lock("hello");
+release_lock("hello")
+0
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 1 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 1 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 1 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+1 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+1 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+1 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+1 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+ commit;
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 1 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 1 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 1 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+commit;
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 1 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 1 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 1 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+1 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 1 ddddddddddddddddddddddddddddddddddddddddddd
+1 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 1 fffffffffffffffffffffffffffffffffffffffffff
+1 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 1 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+1 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+1 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 1 ddddddddddddddddddddddddddddddddddddddddddd
+1 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 1 fffffffffffffffffffffffffffffffffffffffffff
+1 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 1 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+1 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+drop table t1;
+create table t1 (a int not null, b int not null) engine=innodb;
+insert into t1 values (1,1),(2,1),(3,1),(4,1);
+select get_lock("hello2",1000);
+get_lock("hello2",1000)
+1
+begin;
+ update t1 set b=10+get_lock(concat("hello",a),1000)*0 where
+a=2;
+insert into t1 values (1,1);
+select release_lock("hello2");
+release_lock("hello2")
+1
+select * from t1;
+a b
+1 1
+2 1
+3 1
+4 1
+1 1
+select * from t1;
+a b
+1 1
+2 10
+3 1
+4 1
+1 1
+ commit;
+drop table t1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+Warnings:
+Warning 1287 'TYPE=storage_engine' is deprecated; use 'ENGINE=storage_engine' instead
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",10);
+get_lock("hello",10)
+1
+begin;
+ select * from t1 where tipo=2 FOR UPDATE;
+begin;
+select release_lock("hello");
+release_lock("hello")
+1
+update t1 set tipo=1+get_lock("hello",10)*0 where tipo=2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+eta tipo c
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+ commit;
+commit;
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+drop table t1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+Warnings:
+Warning 1287 'TYPE=storage_engine' is deprecated; use 'ENGINE=storage_engine' instead
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",10);
+get_lock("hello",10)
+1
+begin;
+ select * from t1 where tipo=2 FOR UPDATE;
+begin;
+select release_lock("hello");
+release_lock("hello")
+1
+update t1 set tipo=11+get_lock("hello",10)*0 where tipo=22;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+eta tipo c
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+ commit;
+commit;
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+drop table t1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+Warnings:
+Warning 1287 'TYPE=storage_engine' is deprecated; use 'ENGINE=storage_engine' instead
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",10);
+get_lock("hello",10)
+1
+begin;
+ select * from t1 where tipo=2 FOR UPDATE;
+begin;
+select release_lock("hello");
+release_lock("hello")
+1
+select * from t1 where tipo=1 FOR UPDATE;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+eta tipo c
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+ commit;
+commit;
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+drop table t1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+Warnings:
+Warning 1287 'TYPE=storage_engine' is deprecated; use 'ENGINE=storage_engine' instead
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",10);
+get_lock("hello",10)
+1
+begin;
+ delete from t1 where tipo=2;
+begin;
+select release_lock("hello");
+release_lock("hello")
+1
+update t1 set tipo=1+get_lock("hello",10)*0 where tipo=2;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+ commit;
+commit;
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+drop table t1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+Warnings:
+Warning 1287 'TYPE=storage_engine' is deprecated; use 'ENGINE=storage_engine' instead
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",10);
+get_lock("hello",10)
+1
+begin;
+ delete from t1 where tipo=2;
+begin;
+select release_lock("hello");
+release_lock("hello")
+1
+update t1 set tipo=1+get_lock("hello",10)*0 where tipo=22;
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+20 2 ddddddddddddddddddddddddddddddddddddddddddd
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+40 2 fffffffffffffffffffffffffffffffffffffffffff
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 1 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+ commit;
+commit;
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 1 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+select * from t1;
+eta tipo c
+7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+10 1 ccccccccccccccccccccccccccccccccccccccccccc
+30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
+50 1 ggggggggggggggggggggggggggggggggggggggggggg
+70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
+80 1 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
+90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
+drop table t1;
diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result
deleted file mode 100644
index c84bd65e748..00000000000
--- a/mysql-test/r/mix_innodb_myisam_binlog.result
+++ /dev/null
@@ -1,258 +0,0 @@
-drop table if exists t1, t2;
-create table t1 (a int) engine=innodb;
-create table t2 (a int) engine=myisam;
-reset master;
-begin;
-insert into t1 values(1);
-insert into t2 select * from t1;
-commit;
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; BEGIN
-master-bin.000001 166 Query 1 # use `test`; insert into t1 values(1)
-master-bin.000001 253 Query 1 # use `test`; insert into t2 select * from t1
-master-bin.000001 347 Xid 1 # COMMIT /* xid=8 */
-delete from t1;
-delete from t2;
-reset master;
-begin;
-insert into t1 values(2);
-insert into t2 select * from t1;
-rollback;
-Warnings:
-Warning 1196 Some non-transactional changed tables couldn't be rolled back
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; BEGIN
-master-bin.000001 166 Query 1 # use `test`; insert into t1 values(2)
-master-bin.000001 253 Query 1 # use `test`; insert into t2 select * from t1
-master-bin.000001 347 Query 1 # use `test`; ROLLBACK
-delete from t1;
-delete from t2;
-reset master;
-begin;
-insert into t1 values(3);
-savepoint my_savepoint;
-insert into t1 values(4);
-insert into t2 select * from t1;
-rollback to savepoint my_savepoint;
-Warnings:
-Warning 1196 Some non-transactional changed tables couldn't be rolled back
-commit;
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; BEGIN
-master-bin.000001 166 Query 1 # use `test`; insert into t1 values(3)
-master-bin.000001 253 Query 1 # use `test`; savepoint my_savepoint
-master-bin.000001 338 Query 1 # use `test`; insert into t1 values(4)
-master-bin.000001 425 Query 1 # use `test`; insert into t2 select * from t1
-master-bin.000001 519 Query 1 # use `test`; rollback to savepoint my_savepoint
-master-bin.000001 616 Xid 1 # COMMIT /* xid=25 */
-delete from t1;
-delete from t2;
-reset master;
-begin;
-insert into t1 values(5);
-savepoint my_savepoint;
-insert into t1 values(6);
-insert into t2 select * from t1;
-rollback to savepoint my_savepoint;
-Warnings:
-Warning 1196 Some non-transactional changed tables couldn't be rolled back
-insert into t1 values(7);
-commit;
-select a from t1 order by a;
-a
-5
-7
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; BEGIN
-master-bin.000001 166 Query 1 # use `test`; insert into t1 values(5)
-master-bin.000001 253 Query 1 # use `test`; savepoint my_savepoint
-master-bin.000001 338 Query 1 # use `test`; insert into t1 values(6)
-master-bin.000001 425 Query 1 # use `test`; insert into t2 select * from t1
-master-bin.000001 519 Query 1 # use `test`; rollback to savepoint my_savepoint
-master-bin.000001 616 Query 1 # use `test`; insert into t1 values(7)
-master-bin.000001 703 Xid 1 # COMMIT /* xid=37 */
-delete from t1;
-delete from t2;
-reset master;
-select get_lock("a",10);
-get_lock("a",10)
-1
-begin;
-insert into t1 values(8);
-insert into t2 select * from t1;
-select get_lock("a",10);
-get_lock("a",10)
-1
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; BEGIN
-master-bin.000001 166 Query 1 # use `test`; insert into t1 values(8)
-master-bin.000001 253 Query 1 # use `test`; insert into t2 select * from t1
-master-bin.000001 347 Query 1 # use `test`; ROLLBACK
-delete from t1;
-delete from t2;
-reset master;
-insert into t1 values(9);
-insert into t2 select * from t1;
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; insert into t1 values(9)
-master-bin.000001 185 Xid 1 # COMMIT /* xid=60 */
-master-bin.000001 212 Query 1 # use `test`; insert into t2 select * from t1
-delete from t1;
-delete from t2;
-reset master;
-insert into t1 values(10);
-begin;
-insert into t2 select * from t1;
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; insert into t1 values(10)
-master-bin.000001 186 Xid 1 # COMMIT /* xid=66 */
-master-bin.000001 213 Query 1 # use `test`; insert into t2 select * from t1
-insert into t1 values(11);
-commit;
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; insert into t1 values(10)
-master-bin.000001 186 Xid 1 # COMMIT /* xid=66 */
-master-bin.000001 213 Query 1 # use `test`; insert into t2 select * from t1
-master-bin.000001 307 Query 1 # use `test`; BEGIN
-master-bin.000001 375 Query 1 # use `test`; insert into t1 values(11)
-master-bin.000001 463 Xid 1 # COMMIT /* xid=68 */
-alter table t2 engine=INNODB;
-delete from t1;
-delete from t2;
-reset master;
-begin;
-insert into t1 values(12);
-insert into t2 select * from t1;
-commit;
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; BEGIN
-master-bin.000001 166 Query 1 # use `test`; insert into t1 values(12)
-master-bin.000001 254 Query 1 # use `test`; insert into t2 select * from t1
-master-bin.000001 348 Xid 1 # COMMIT /* xid=78 */
-delete from t1;
-delete from t2;
-reset master;
-begin;
-insert into t1 values(13);
-insert into t2 select * from t1;
-rollback;
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-delete from t1;
-delete from t2;
-reset master;
-begin;
-insert into t1 values(14);
-savepoint my_savepoint;
-insert into t1 values(15);
-insert into t2 select * from t1;
-rollback to savepoint my_savepoint;
-commit;
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; BEGIN
-master-bin.000001 166 Query 1 # use `test`; insert into t1 values(14)
-master-bin.000001 254 Xid 1 # COMMIT /* xid=94 */
-delete from t1;
-delete from t2;
-reset master;
-begin;
-insert into t1 values(16);
-savepoint my_savepoint;
-insert into t1 values(17);
-insert into t2 select * from t1;
-rollback to savepoint my_savepoint;
-insert into t1 values(18);
-commit;
-select a from t1 order by a;
-a
-16
-18
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; BEGIN
-master-bin.000001 166 Query 1 # use `test`; insert into t1 values(16)
-master-bin.000001 254 Query 1 # use `test`; insert into t1 values(18)
-master-bin.000001 342 Xid 1 # COMMIT /* xid=105 */
-delete from t1;
-delete from t2;
-alter table t2 type=MyISAM;
-insert into t1 values (1);
-begin;
-select * from t1 for update;
-a
-1
-select (@before:=unix_timestamp())*0;
-(@before:=unix_timestamp())*0
-0
-begin;
- select * from t1 for update;
-insert into t2 values (20);
-ERROR HY000: Lock wait timeout exceeded; try restarting transaction
-select (@after:=unix_timestamp())*0;
-(@after:=unix_timestamp())*0
-0
-select (@after-@before) >= 2;
-(@after-@before) >= 2
-1
-drop table t1,t2;
-commit;
-begin;
-create temporary table ti (a int) engine=innodb;
-rollback;
-Warnings:
-Warning 1196 Some non-transactional changed tables couldn't be rolled back
-insert into ti values(1);
-set autocommit=0;
-create temporary table t1 (a int) engine=myisam;
-commit;
-insert t1 values (1);
-rollback;
-Warnings:
-Warning 1196 Some non-transactional changed tables couldn't be rolled back
-create table t0 (n int);
-insert t0 select * from t1;
-set autocommit=1;
-insert into t0 select GET_LOCK("lock1",null);
-set autocommit=0;
-create table t2 (n int) engine=innodb;
-insert into t2 values (3);
-select get_lock("lock1",60);
-get_lock("lock1",60)
-1
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 # use `test`; BEGIN
-master-bin.000001 166 Query 1 # use `test`; insert into t1 values(16)
-master-bin.000001 254 Query 1 # use `test`; insert into t1 values(18)
-master-bin.000001 342 Xid 1 # COMMIT /* xid=105 */
-master-bin.000001 369 Query 1 # use `test`; delete from t1
-master-bin.000001 446 Xid 1 # COMMIT /* xid=114 */
-master-bin.000001 473 Query 1 # use `test`; delete from t2
-master-bin.000001 550 Xid 1 # COMMIT /* xid=115 */
-master-bin.000001 577 Query 1 # use `test`; alter table t2 type=MyISAM
-master-bin.000001 666 Query 1 # use `test`; insert into t1 values (1)
-master-bin.000001 754 Xid 1 # COMMIT /* xid=117 */
-master-bin.000001 781 Query 1 # use `test`; insert into t2 values (20)
-master-bin.000001 870 Query 1 # use `test`; drop table t1,t2
-master-bin.000001 949 Query 1 # use `test`; create temporary table ti (a int) engine=innodb
-master-bin.000001 1059 Query 1 # use `test`; insert into ti values(1)
-master-bin.000001 1146 Xid 1 # COMMIT /* xid=132 */
-master-bin.000001 1173 Query 1 # use `test`; create temporary table t1 (a int) engine=myisam
-master-bin.000001 1283 Query 1 # use `test`; insert t1 values (1)
-master-bin.000001 1366 Query 1 # use `test`; create table t0 (n int)
-master-bin.000001 1452 Query 1 # use `test`; insert t0 select * from t1
-master-bin.000001 1541 Query 1 # use `test`; insert into t0 select GET_LOCK("lock1",null)
-master-bin.000001 1648 Query 1 # use `test`; create table t2 (n int) engine=innodb
-master-bin.000001 1748 Query 1 # use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `test`.`t1`,`test`.`ti`
-do release_lock("lock1");
-drop table t0,t2;
diff --git a/mysql-test/r/mysqlbinlog_base64.result b/mysql-test/r/mysqlbinlog_base64.result
new file mode 100644
index 00000000000..499587cb465
--- /dev/null
+++ b/mysql-test/r/mysqlbinlog_base64.result
@@ -0,0 +1,89 @@
+create table t1 (a int);
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+update t1 set a=a+2 where a=2;
+update t1 set a=a+2 where a=3;
+create table t2 (word varchar(20));
+load data infile '../../std_data/words.dat' into table t2;
+drop table t1;
+drop table t2;
+select * from t1;
+a
+1
+4
+5
+select * from t2;
+word
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
+Aberdeen
+Abernathy
+aberrant
+aberration
+drop table t1;
+drop table t2;
diff --git a/mysql-test/r/not_row_based.require b/mysql-test/r/not_row_based.require
new file mode 100644
index 00000000000..e30e73320fb
--- /dev/null
+++ b/mysql-test/r/not_row_based.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_row_based_replication NO
diff --git a/mysql-test/r/rpl000017.result b/mysql-test/r/rpl000017.result
index 64e13042e9c..245848a07e4 100644
--- a/mysql-test/r/rpl000017.result
+++ b/mysql-test/r/rpl000017.result
@@ -1,4 +1,10 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+stop slave;
grant replication slave on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab';
grant replication slave on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab';
start slave;
diff --git a/mysql-test/r/rpl000012.result b/mysql-test/r/rpl_000012.result
index 17fb53010ab..e4ca31d8908 100644
--- a/mysql-test/r/rpl000012.result
+++ b/mysql-test/r/rpl_000012.result
@@ -4,31 +4,42 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
-create table t2 (n int);
+create table t2 (n int, PRIMARY KEY(n));
create temporary table t1 (n int);
-insert into t1 values(1),(2),(3);
-insert into t2 select * from t1;
create temporary table t3 (n int not null);
+insert into t1 values(1),(2),(3),(100),(25),(26),(200),(300);
+insert into t2 select * from t1;
alter table t3 add primary key(n);
flush logs;
-insert into t3 values (100);
+insert into t3 values (1010);
insert into t2 select * from t3;
drop table if exists t3;
-insert into t2 values (101);
+insert into t2 values (1012);
create temporary table t1 (n int);
insert into t1 values (4),(5);
insert into t2 select * from t1;
-insert into t2 values(6);
+insert into t2 values(61);
select * from t2;
n
1
2
3
-100
-101
4
5
-6
+25
+26
+61
+100
+200
+300
+1010
+1012
+select count(*) from t2;
+count(*)
+13
+select sum(n) from t2;
+sum(n)
+2749
show status like 'Slave_open_temp_tables';
Variable_name Value
Slave_open_temp_tables 0
diff --git a/mysql-test/r/rpl000015.result b/mysql-test/r/rpl_000015.result
index e33201ced93..d965df347ab 100644
--- a/mysql-test/r/rpl000015.result
+++ b/mysql-test/r/rpl_000015.result
@@ -1,7 +1,7 @@
reset master;
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 98
+master-bin.000001 102
reset slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
@@ -17,13 +17,18 @@ Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File
start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 7 master-bin.000001 98 # # master-bin.000001 Yes Yes 0 0 98 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 7 master-bin.000001 102 # # master-bin.000001 Yes Yes 0 0 102 # None 0 No #
drop table if exists t1;
-create table t1 (n int);
+create table t1 (n int, PRIMARY KEY(n));
insert into t1 values (10),(45),(90);
select * from t1;
n
10
45
90
+select * from t1;
+n
+10
+45
+90
drop table t1;
diff --git a/mysql-test/r/rpl_LD_INFILE.result b/mysql-test/r/rpl_LD_INFILE.result
new file mode 100644
index 00000000000..a2e4ef7b83b
--- /dev/null
+++ b/mysql-test/r/rpl_LD_INFILE.result
@@ -0,0 +1,121 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
+CREATE TABLE test.t1 (a VARCHAR(255), PRIMARY KEY(a));
+LOAD DATA INFILE '../../std_data/words2.dat' INTO TABLE test.t1;
+DELETE FROM test.t1 WHERE a = 'abashed';
+DELETE FROM test.t1;
+LOAD DATA INFILE '../../std_data/words2.dat' INTO TABLE test.t1;
+SELECT * FROM test.t1;
+a
+abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
+Aberdeen
+Abernathy
+aberrant
+aberration
+SELECT * FROM test.t1;
+a
+abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
+Aberdeen
+Abernathy
+aberrant
+aberration
+DROP PROCEDURE IF EXISTS test.p1;
+Warnings:
+Note 1305 PROCEDURE p1 does not exist
+DROP TABLE test.t1;
diff --git a/mysql-test/r/rpl_bit.result b/mysql-test/r/rpl_bit.result
new file mode 100644
index 00000000000..a1b57f1c183
--- /dev/null
+++ b/mysql-test/r/rpl_bit.result
@@ -0,0 +1,138 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP TABLE IF EXISTS test.t1;
+CREATE TABLE test.t1 (
+dummyKey INTEGER NOT NULL,
+f01 TINYINT,
+f10 TINYINT,
+f12 TINYINT,
+f15 TINYINT,
+f16 TINYINT,
+f7 TINYINT,
+f9 TINYINT,
+f29 TINYINT,
+f0 TINYINT,
+fA1 TINYINT,
+C32 TINYINT,
+A42 TINYINT,
+CA3 TINYINT,
+A044 TINYINT,
+f001 TINYINT,
+A3002 TINYINT,
+fC003 TINYINT,
+CA300 TINYINT,
+A305 TINYINT,
+CA321 TINYINT,
+r001 TINYINT,
+bit1 BIT(6),
+bit2 BIT(6),
+bit3 BIT(6),
+State1 TINYINT,
+State2 TINYINT,
+State3 TINYINT,
+State4 TINYINT,
+SubState TINYINT,
+gState TINYINT,
+oSupp TINYINT,
+tSupp TINYINT,
+sSuppD TINYINT,
+mSuppf TINYINT,
+GSuppDf TINYINT,
+VNotSupp TINYINT,
+x034 TINYINT,
+PRIMARY KEY USING HASH (dummyKey) );
+LOCK TABLES test.t1 WRITE;
+INSERT INTO test.t1 VALUES (6,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'111110',b'110101',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'000000',b'100100',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (2,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'000000',b'101010',b'010101',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (3,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'101010',b'111111',b'000000',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (4,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (5,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (7,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (8,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+UNLOCK TABLES;
+SELECT oSupp, sSuppD, GSuppDf, VNotSupp, x034 FROM test.t1;
+oSupp sSuppD GSuppDf VNotSupp x034
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+SELECT hex(bit1) from test.t1;
+hex(bit1)
+3F
+3F
+0
+2A
+0
+0
+0
+0
+SELECT hex(bit2) from test.t1;
+hex(bit2)
+3E
+0
+2A
+3F
+1
+1
+1
+1
+SELECT hex(bit3) from test.t1;
+hex(bit3)
+35
+24
+15
+0
+1
+1
+1
+1
+SELECT oSupp, sSuppD, GSuppDf, VNotSupp, x034 FROM test.t1;
+oSupp sSuppD GSuppDf VNotSupp x034
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+SELECT hex(bit1) from test.t1;
+hex(bit1)
+3F
+3F
+0
+2A
+0
+0
+0
+0
+SELECT hex(bit2) from test.t1;
+hex(bit2)
+3E
+0
+2A
+3F
+1
+1
+1
+1
+SELECT hex(bit3) from test.t1;
+hex(bit3)
+35
+24
+15
+0
+1
+1
+1
+1
+DROP TABLE IF EXISTS test.t1;
diff --git a/mysql-test/r/rpl_bit_npk.result b/mysql-test/r/rpl_bit_npk.result
new file mode 100644
index 00000000000..aeefc77d69b
--- /dev/null
+++ b/mysql-test/r/rpl_bit_npk.result
@@ -0,0 +1,137 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP TABLE IF EXISTS test.t1;
+CREATE TABLE test.t1 (
+dummyKey INTEGER NOT NULL,
+f01 TINYINT,
+f10 TINYINT,
+f12 TINYINT,
+f15 TINYINT,
+f16 TINYINT,
+f7 TINYINT,
+f9 TINYINT,
+f29 TINYINT,
+f0 TINYINT,
+fA1 TINYINT,
+C32 TINYINT,
+A42 TINYINT,
+CA3 TINYINT,
+A044 TINYINT,
+f001 TINYINT,
+A3002 TINYINT,
+fC003 TINYINT,
+CA300 TINYINT,
+A305 TINYINT,
+CA321 TINYINT,
+r001 TINYINT,
+bit1 BIT(6),
+bit2 BIT(6),
+bit3 BIT(6),
+State1 TINYINT,
+State2 TINYINT,
+State3 TINYINT,
+State4 TINYINT,
+SubState TINYINT,
+gState TINYINT,
+oSupp TINYINT,
+tSupp TINYINT,
+sSuppD TINYINT,
+mSuppf TINYINT,
+GSuppDf TINYINT,
+VNotSupp TINYINT,
+x034 TINYINT);
+LOCK TABLES test.t1 WRITE;
+INSERT INTO test.t1 VALUES (6,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'111110',b'110101',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'000000',b'100100',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (2,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'000000',b'101010',b'010101',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (3,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'101010',b'111111',b'000000',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (4,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (5,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (7,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (8,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+UNLOCK TABLES;
+SELECT oSupp, sSuppD, GSuppDf, VNotSupp, x034 FROM test.t1;
+oSupp sSuppD GSuppDf VNotSupp x034
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+SELECT hex(bit1) from test.t1;
+hex(bit1)
+3F
+3F
+0
+2A
+0
+0
+0
+0
+SELECT hex(bit2) from test.t1;
+hex(bit2)
+3E
+0
+2A
+3F
+1
+1
+1
+1
+SELECT hex(bit3) from test.t1;
+hex(bit3)
+35
+24
+15
+0
+1
+1
+1
+1
+SELECT oSupp, sSuppD, GSuppDf, VNotSupp, x034 FROM test.t1;
+oSupp sSuppD GSuppDf VNotSupp x034
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+5 5 3 2 1
+SELECT hex(bit1) from test.t1;
+hex(bit1)
+3F
+3F
+0
+2A
+0
+0
+0
+0
+SELECT hex(bit2) from test.t1;
+hex(bit2)
+3E
+0
+2A
+3F
+1
+1
+1
+1
+SELECT hex(bit3) from test.t1;
+hex(bit3)
+35
+24
+15
+0
+1
+1
+1
+1
+DROP TABLE IF EXISTS test.t1;
diff --git a/mysql-test/r/rpl_change_master.result b/mysql-test/r/rpl_change_master.result
index 7f2ba568fb3..513de9494ba 100644
--- a/mysql-test/r/rpl_change_master.result
+++ b/mysql-test/r/rpl_change_master.result
@@ -13,11 +13,11 @@ insert into t1 values(2);
stop slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 357 # # master-bin.000001 No No 0 0 183 # None 0 No #
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 # # # master-bin.000001 No No 0 0 187 # None 0 No #
change master to master_user='root';
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 183 # # master-bin.000001 No No 0 0 183 # None 0 No #
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 # # # master-bin.000001 No No 0 0 187 # None 0 No #
start slave;
select * from t1;
n
diff --git a/mysql-test/r/rpl_commit_after_flush.result b/mysql-test/r/rpl_commit_after_flush.result
index d3aba779219..eaddda63b6a 100644
--- a/mysql-test/r/rpl_commit_after_flush.result
+++ b/mysql-test/r/rpl_commit_after_flush.result
@@ -4,7 +4,7 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
-create table t1 (a int) engine=innodb;
+CREATE TABLE t1 (a INT) ENGINE=innodb;
begin;
insert into t1 values(1);
flush tables with read lock;
diff --git a/mysql-test/r/rpl_create_database.result b/mysql-test/r/rpl_create_database.result
index ca4585d0d8d..82ab8c6f434 100644
--- a/mysql-test/r/rpl_create_database.result
+++ b/mysql-test/r/rpl_create_database.result
@@ -42,21 +42,6 @@ INSERT INTO t1 VALUES (1);
CREATE DATABASE mysqltest_sisyfos;
USE mysqltest_sisyfos;
CREATE TABLE t2 (a INT);
-SHOW BINLOG EVENTS;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
-master-bin.000001 # Query 1 # DROP DATABASE IF EXISTS mysqltest_prometheus
-master-bin.000001 # Query 1 # DROP DATABASE IF EXISTS mysqltest_sisyfos
-master-bin.000001 # Query 1 # CREATE DATABASE mysqltest_prometheus
-master-bin.000001 # Query 1 # CREATE DATABASE mysqltest_sisyfos
-master-bin.000001 # Query 1 # use `mysqltest_sisyfos`; CREATE TABLE t1 (b int)
-master-bin.000001 # Query 1 # use `mysqltest_sisyfos`; INSERT INTO t1 VALUES(1)
-master-bin.000001 # Query 1 # ALTER DATABASE mysqltest_sisyfos CHARACTER SET latin1
-master-bin.000001 # Query 1 # DROP DATABASE IF EXISTS mysqltest_sisyfos
-master-bin.000001 # Query 1 # use `mysqltest_prometheus`; CREATE TABLE t1 (a INT)
-master-bin.000001 # Query 1 # use `mysqltest_prometheus`; INSERT INTO t1 VALUES (1)
-master-bin.000001 # Query 1 # CREATE DATABASE mysqltest_sisyfos
-master-bin.000001 # Query 1 # use `mysqltest_sisyfos`; CREATE TABLE t2 (a INT)
SHOW DATABASES;
Database
information_schema
diff --git a/mysql-test/r/rpl_deadlock.result b/mysql-test/r/rpl_deadlock_innodb.result
index c25cb1e6a53..7d592c2d0cd 100644
--- a/mysql-test/r/rpl_deadlock.result
+++ b/mysql-test/r/rpl_deadlock_innodb.result
@@ -4,10 +4,10 @@ reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
-create table t1 (a int not null, key(a)) engine=innodb;
-create table t2 (a int not null, key(a)) engine=innodb;
-create table t3 (a int) engine=innodb;
-create table t4 (a int) engine=innodb;
+CREATE TABLE t1 (a INT NOT NULL, KEY(a)) ENGINE=innodb;
+CREATE TABLE t2 (a INT NOT NULL, KEY(a)) ENGINE=innodb;
+CREATE TABLE t3 (a INT) ENGINE=innodb;
+CREATE TABLE t4 (a INT) ENGINE=innodb;
show variables like 'slave_transaction_retries';
Variable_name Value
slave_transaction_retries 10
@@ -45,9 +45,9 @@ a
22
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 18911 # # master-bin.000001 Yes Yes 0 0 18911 # None 0 No #
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 # # # master-bin.000001 Yes Yes # 0 0 # # None 0 No #
stop slave;
-change master to master_log_pos=532;
+change master to master_log_pos=536;
begin;
select * from t2 for update;
a
@@ -63,10 +63,10 @@ a
22
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 18911 # # master-bin.000001 Yes Yes 0 0 18911 # None 0 No #
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 # # # master-bin.000001 Yes Yes # 0 0 # # None 0 No #
set global max_relay_log_size=0;
stop slave;
-change master to master_log_pos=532;
+change master to master_log_pos=536;
begin;
select * from t2 for update;
a
@@ -83,5 +83,5 @@ a
22
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 18911 # # master-bin.000001 # Yes 0 0 18911 # None 0 No #
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 # # # master-bin.000001 # Yes # 0 0 # # None 0 No #
drop table t1,t2,t3,t4;
diff --git a/mysql-test/r/rpl_delete_no_where.result b/mysql-test/r/rpl_delete_no_where.result
new file mode 100644
index 00000000000..78edf4bf3fa
--- /dev/null
+++ b/mysql-test/r/rpl_delete_no_where.result
@@ -0,0 +1,15 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1 (a int, b int) engine=myisam;
+insert into t1 values(1,1);
+select * from t1;
+a b
+1 1
+delete from t1;
+select * from t1;
+a b
+drop table t1;
diff --git a/mysql-test/r/rpl_do_grant.result b/mysql-test/r/rpl_do_grant.result
index ff3e059503c..8bf8e615448 100644
--- a/mysql-test/r/rpl_do_grant.result
+++ b/mysql-test/r/rpl_do_grant.result
@@ -24,3 +24,55 @@ delete from mysql.user where user=_binary'rpl_do_grant';
delete from mysql.db where user=_binary'rpl_do_grant';
flush privileges;
flush privileges;
+show grants for rpl_do_grant@localhost;
+ERROR 42000: There is no such grant defined for user 'rpl_do_grant' on host 'localhost'
+show grants for rpl_do_grant@localhost;
+ERROR 42000: There is no such grant defined for user 'rpl_do_grant' on host 'localhost'
+create user rpl_do_grant@localhost;
+show grants for rpl_do_grant@localhost;
+Grants for rpl_do_grant@localhost
+GRANT USAGE ON *.* TO 'rpl_do_grant'@'localhost'
+show grants for rpl_do_grant2@localhost;
+ERROR 42000: There is no such grant defined for user 'rpl_do_grant2' on host 'localhost'
+show grants for rpl_do_grant@localhost;
+Grants for rpl_do_grant@localhost
+GRANT USAGE ON *.* TO 'rpl_do_grant'@'localhost'
+show grants for rpl_do_grant2@localhost;
+ERROR 42000: There is no such grant defined for user 'rpl_do_grant2' on host 'localhost'
+rename user rpl_do_grant@localhost to rpl_do_grant2@localhost;
+show grants for rpl_do_grant2@localhost;
+Grants for rpl_do_grant2@localhost
+GRANT USAGE ON *.* TO 'rpl_do_grant2'@'localhost'
+show grants for rpl_do_grant2@localhost;
+Grants for rpl_do_grant2@localhost
+GRANT USAGE ON *.* TO 'rpl_do_grant2'@'localhost'
+grant DELETE,INSERT on mysqltest1.* to rpl_do_grant2@localhost;
+show grants for rpl_do_grant2@localhost;
+Grants for rpl_do_grant2@localhost
+GRANT USAGE ON *.* TO 'rpl_do_grant2'@'localhost'
+GRANT INSERT, DELETE ON `mysqltest1`.* TO 'rpl_do_grant2'@'localhost'
+show grants for rpl_do_grant2@localhost;
+Grants for rpl_do_grant2@localhost
+GRANT USAGE ON *.* TO 'rpl_do_grant2'@'localhost'
+GRANT INSERT, DELETE ON `mysqltest1`.* TO 'rpl_do_grant2'@'localhost'
+revoke DELETE on mysqltest1.* from rpl_do_grant2@localhost;
+show grants for rpl_do_grant2@localhost;
+Grants for rpl_do_grant2@localhost
+GRANT USAGE ON *.* TO 'rpl_do_grant2'@'localhost'
+GRANT INSERT ON `mysqltest1`.* TO 'rpl_do_grant2'@'localhost'
+show grants for rpl_do_grant2@localhost;
+Grants for rpl_do_grant2@localhost
+GRANT USAGE ON *.* TO 'rpl_do_grant2'@'localhost'
+GRANT INSERT ON `mysqltest1`.* TO 'rpl_do_grant2'@'localhost'
+revoke all privileges, grant option from rpl_do_grant2@localhost;
+show grants for rpl_do_grant2@localhost;
+Grants for rpl_do_grant2@localhost
+GRANT USAGE ON *.* TO 'rpl_do_grant2'@'localhost'
+show grants for rpl_do_grant2@localhost;
+Grants for rpl_do_grant2@localhost
+GRANT USAGE ON *.* TO 'rpl_do_grant2'@'localhost'
+drop user rpl_do_grant2@localhost;
+show grants for rpl_do_grant2@localhost;
+ERROR 42000: There is no such grant defined for user 'rpl_do_grant2' on host 'localhost'
+show grants for rpl_do_grant2@localhost;
+ERROR 42000: There is no such grant defined for user 'rpl_do_grant2' on host 'localhost'
diff --git a/mysql-test/r/rpl_flush_tables.result b/mysql-test/r/rpl_flush_tables.result
deleted file mode 100644
index 667530c4071..00000000000
--- a/mysql-test/r/rpl_flush_tables.result
+++ /dev/null
@@ -1,46 +0,0 @@
-stop slave;
-drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
-reset master;
-reset slave;
-drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
-start slave;
-create table t1 (a int);
-insert into t1 values (10);
-create table t2 (a int);
-create table t3 (a int) engine=merge union(t1);
-create table t4 (a int);
-insert into t4 select * from t3;
-rename table t1 to t5, t2 to t1;
-flush no_write_to_binlog tables;
-show binlog events;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Format_desc 1 # Server ver: SERVER_VERSION, Binlog ver: 4
-master-bin.000001 # Query 1 # use `test`; create table t1 (a int)
-master-bin.000001 # Query 1 # use `test`; insert into t1 values (10)
-master-bin.000001 # Query 1 # use `test`; create table t2 (a int)
-master-bin.000001 # Query 1 # use `test`; create table t3 (a int) engine=merge union(t1)
-master-bin.000001 # Query 1 # use `test`; create table t4 (a int)
-master-bin.000001 # Query 1 # use `test`; insert into t4 select * from t3
-master-bin.000001 # Query 1 # use `test`; rename table t1 to t5, t2 to t1
-select * from t3;
-a
-flush tables;
-show binlog events;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Format_desc 1 # Server ver: SERVER_VERSION, Binlog ver: 4
-master-bin.000001 # Query 1 # use `test`; create table t1 (a int)
-master-bin.000001 # Query 1 # use `test`; insert into t1 values (10)
-master-bin.000001 # Query 1 # use `test`; create table t2 (a int)
-master-bin.000001 # Query 1 # use `test`; create table t3 (a int) engine=merge union(t1)
-master-bin.000001 # Query 1 # use `test`; create table t4 (a int)
-master-bin.000001 # Query 1 # use `test`; insert into t4 select * from t3
-master-bin.000001 # Query 1 # use `test`; rename table t1 to t5, t2 to t1
-master-bin.000001 # Query 1 # use `test`; flush tables
-select * from t3;
-a
-stop slave;
-drop table t1;
-flush tables with read lock;
-start slave;
-stop slave;
-ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
diff --git a/mysql-test/r/rpl_flush_log_loop.result b/mysql-test/r/rpl_flushlog_loop.result
index f9bd42ec26c..61d3949ac50 100644
--- a/mysql-test/r/rpl_flush_log_loop.result
+++ b/mysql-test/r/rpl_flushlog_loop.result
@@ -8,10 +8,11 @@ stop slave;
change master to master_host='127.0.0.1',master_user='root',
master_password='',master_port=MASTER_PORT;
start slave;
+stop slave;
change master to master_host='127.0.0.1',master_user='root',
master_password='',master_port=SLAVE_PORT;
start slave;
flush logs;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root SLAVE_PORT 60 slave-bin.000001 208 # # slave-bin.000001 Yes Yes 0 0 208 # None 0 No #
+# 127.0.0.1 root SLAVE_PORT 60 slave-bin.000001 212 # # slave-bin.000001 Yes Yes # 0 0 212 # None 0 No #
diff --git a/mysql-test/r/rpl_foreign_key_innodb.result b/mysql-test/r/rpl_foreign_key_innodb.result
new file mode 100644
index 00000000000..5c7d21a5b1d
--- /dev/null
+++ b/mysql-test/r/rpl_foreign_key_innodb.result
@@ -0,0 +1,42 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (a INT AUTO_INCREMENT KEY) ENGINE=INNODB;
+CREATE TABLE t2 (b INT AUTO_INCREMENT KEY, c INT, FOREIGN KEY(b) REFERENCES t1(a)) ENGINE=INNODB;
+SET FOREIGN_KEY_CHECKS=0;
+INSERT INTO t1 VALUES (10);
+INSERT INTO t1 VALUES (NULL),(NULL),(NULL);
+INSERT INTO t2 VALUES (5,0);
+INSERT INTO t2 VALUES (NULL,LAST_INSERT_ID());
+SET FOREIGN_KEY_CHECKS=1;
+SELECT * FROM t1;
+a
+10
+11
+12
+13
+SELECT * FROM t2;
+b c
+5 0
+6 11
+SELECT * FROM t1;
+a
+10
+11
+12
+13
+SELECT * FROM t2;
+b c
+5 0
+6 11
+SET TIMESTAMP=1000000000;
+CREATE TABLE t3 ( a INT UNIQUE );
+SET FOREIGN_KEY_CHECKS=0;
+INSERT INTO t3 VALUES (1),(1);
+ERROR 23000: Duplicate entry '1' for key 1
+SET FOREIGN_KEY_CHECKS=0;
+DROP TABLE IF EXISTS t1,t2,t3;
+SET FOREIGN_KEY_CHECKS=1;
diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result
index dc11d10fab8..0b2e108843b 100644
--- a/mysql-test/r/rpl_loaddata.result
+++ b/mysql-test/r/rpl_loaddata.result
@@ -22,7 +22,7 @@ day id category name
2003-03-22 2416 a bbbbb
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
-slave-bin.000001 1286
+slave-bin.000001 1290
drop table t1;
drop table t2;
drop table t3;
@@ -33,7 +33,7 @@ set global sql_slave_skip_counter=1;
start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1789 # # master-bin.000001 Yes Yes 0 0 1789 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1793 # # master-bin.000001 Yes Yes # 0 0 1793 # None 0 No #
set sql_log_bin=0;
delete from t1;
set sql_log_bin=1;
@@ -43,7 +43,7 @@ change master to master_user='test';
change master to master_user='root';
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1824 # # master-bin.000001 No No 0 0 1824 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1828 # # master-bin.000001 No No # 0 0 1828 # None 0 No #
set global sql_slave_skip_counter=1;
start slave;
set sql_log_bin=0;
@@ -54,7 +54,7 @@ stop slave;
reset slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 4 # # No No 0 0 0 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 4 # # No No # 0 0 0 # None 0 No #
reset master;
create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60),
unique(day)) engine=MyISAM;
diff --git a/mysql-test/r/rpl_loaddata2.result b/mysql-test/r/rpl_loaddata2.result
new file mode 100644
index 00000000000..e8a0fd0f51a
--- /dev/null
+++ b/mysql-test/r/rpl_loaddata2.result
@@ -0,0 +1,152 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (word CHAR(20) NOT NULL);
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
+SELECT * FROM t1;
+word
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
+Aberdeen
+Abernathy
+aberrant
+aberration
+SELECT * FROM t1;
+word
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
+Aberdeen
+Abernathy
+aberrant
+aberration
diff --git a/mysql-test/r/rpl_loaddata_rule_s.result b/mysql-test/r/rpl_loaddata_s.result
index 16720c81374..8d50d9cc0d9 100644
--- a/mysql-test/r/rpl_loaddata_rule_s.result
+++ b/mysql-test/r/rpl_loaddata_s.result
@@ -5,10 +5,10 @@ reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
reset master;
-create table t1(a int, b int, unique(b));
+create table test.t1(a int, b int, unique(b));
load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
-select count(*) from t1;
+select count(*) from test.t1;
count(*)
2
-show binlog events from 98;
+show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
diff --git a/mysql-test/r/rpl_loadfile.result b/mysql-test/r/rpl_loadfile.result
new file mode 100644
index 00000000000..f1455958ff2
--- /dev/null
+++ b/mysql-test/r/rpl_loadfile.result
@@ -0,0 +1,234 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
+CREATE TABLE test.t1 (a INT, blob_column LONGBLOB, PRIMARY KEY(a));
+INSERT INTO test.t1 VALUES(1,'test');
+UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=1;
+create procedure test.p1()
+begin
+INSERT INTO test.t1 VALUES(2,'test');
+UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=2;
+end|
+CALL test.p1();
+SELECT * FROM test.t1;
+a blob_column
+1 abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
+Aberdeen
+Abernathy
+aberrant
+aberration
+
+2 abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
+Aberdeen
+Abernathy
+aberrant
+aberration
+
+SHOW CREATE TABLE test.t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0',
+ `blob_column` longblob,
+ PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM test.t1;
+a blob_column
+1 abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
+Aberdeen
+Abernathy
+aberrant
+aberration
+
+2 abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
+Aberdeen
+Abernathy
+aberrant
+aberration
+
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE test.t1;
diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result
deleted file mode 100644
index be8d5291ad9..00000000000
--- a/mysql-test/r/rpl_log.result
+++ /dev/null
@@ -1,103 +0,0 @@
-stop slave;
-drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
-reset master;
-reset slave;
-drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
-start slave;
-stop slave;
-reset master;
-reset slave;
-reset master;
-create table t1(n int not null auto_increment primary key);
-insert into t1 values (NULL);
-drop table t1;
-create table t1 (word char(20) not null);
-load data infile '../../std_data/words.dat' into table t1 ignore 1 lines;
-select count(*) from t1;
-count(*)
-69
-drop table t1;
-show binlog events;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 4 Format_desc 1 98 Server ver: VERSION, Binlog ver: 4
-master-bin.000001 98 Query 1 219 use `test`; create table t1(n int not null auto_increment primary key)
-master-bin.000001 219 Intvar 1 247 INSERT_ID=1
-master-bin.000001 247 Query 1 338 use `test`; insert into t1 values (NULL)
-master-bin.000001 338 Query 1 414 use `test`; drop table t1
-master-bin.000001 414 Query 1 517 use `test`; create table t1 (word char(20) not null)
-master-bin.000001 517 Begin_load_query 1 1121 ;file_id=1;block_len=581
-master-bin.000001 1121 Execute_load_query 1 1269 use `test`; load data infile '../../std_data/words.dat' into table t1 ignore 1 lines ;file_id=1
-master-bin.000001 1269 Query 1 1345 use `test`; drop table t1
-show binlog events from 98 limit 1;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 219 use `test`; create table t1(n int not null auto_increment primary key)
-show binlog events from 98 limit 2;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 219 use `test`; create table t1(n int not null auto_increment primary key)
-master-bin.000001 219 Intvar 1 247 INSERT_ID=1
-show binlog events from 98 limit 2,1;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 247 Query 1 338 use `test`; insert into t1 values (NULL)
-flush logs;
-create table t5 (a int);
-drop table t5;
-start slave;
-flush logs;
-stop slave;
-create table t1 (n int);
-insert into t1 values (1);
-drop table t1;
-show binlog events;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 4 Format_desc 1 98 Server ver: VERSION, Binlog ver: 4
-master-bin.000001 98 Query 1 219 use `test`; create table t1(n int not null auto_increment primary key)
-master-bin.000001 219 Intvar 1 247 INSERT_ID=1
-master-bin.000001 247 Query 1 338 use `test`; insert into t1 values (NULL)
-master-bin.000001 338 Query 1 414 use `test`; drop table t1
-master-bin.000001 414 Query 1 517 use `test`; create table t1 (word char(20) not null)
-master-bin.000001 517 Begin_load_query 1 1121 ;file_id=1;block_len=581
-master-bin.000001 1121 Execute_load_query 1 1269 use `test`; load data infile '../../std_data/words.dat' into table t1 ignore 1 lines ;file_id=1
-master-bin.000001 1269 Query 1 1345 use `test`; drop table t1
-master-bin.000001 1345 Rotate 1 1389 master-bin.000002;pos=4
-show binlog events in 'master-bin.000002';
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 4 Format_desc 1 98 Server ver: VERSION, Binlog ver: 4
-master-bin.000002 98 Query 1 184 use `test`; create table t5 (a int)
-master-bin.000002 184 Query 1 260 use `test`; drop table t5
-master-bin.000002 260 Query 1 346 use `test`; create table t1 (n int)
-master-bin.000002 346 Query 1 434 use `test`; insert into t1 values (1)
-master-bin.000002 434 Query 1 510 use `test`; drop table t1
-show binary logs;
-Log_name File_size
-master-bin.000001 1389
-master-bin.000002 510
-start slave;
-show binary logs;
-Log_name File_size
-slave-bin.000001 1559
-slave-bin.000002 348
-show binlog events in 'slave-bin.000001' from 4;
-Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000001 4 Format_desc 2 98 Server ver: VERSION, Binlog ver: 4
-slave-bin.000001 98 Query 1 219 use `test`; create table t1(n int not null auto_increment primary key)
-slave-bin.000001 219 Intvar 1 247 INSERT_ID=1
-slave-bin.000001 247 Query 1 338 use `test`; insert into t1 values (NULL)
-slave-bin.000001 338 Query 1 414 use `test`; drop table t1
-slave-bin.000001 414 Query 1 517 use `test`; create table t1 (word char(20) not null)
-slave-bin.000001 517 Begin_load_query 1 1121 ;file_id=1;block_len=581
-slave-bin.000001 1121 Execute_load_query 1 1278 use `test`; load data INFILE '../../var/tmp/SQL_LOAD-2-1-1.data' INTO table t1 ignore 1 lines ;file_id=1
-slave-bin.000001 1278 Query 1 1354 use `test`; drop table t1
-slave-bin.000001 1354 Query 1 1440 use `test`; create table t5 (a int)
-slave-bin.000001 1440 Query 1 1516 use `test`; drop table t5
-slave-bin.000001 1516 Rotate 2 1559 slave-bin.000002;pos=4
-show binlog events in 'slave-bin.000002' from 4;
-Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000002 4 Format_desc 2 98 Server ver: VERSION, Binlog ver: 4
-slave-bin.000002 98 Query 1 184 use `test`; create table t1 (n int)
-slave-bin.000002 184 Query 1 272 use `test`; insert into t1 values (1)
-slave-bin.000002 272 Query 1 348 use `test`; drop table t1
-show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 510 # # master-bin.000002 Yes Yes 0 0 510 # None 0 No #
-show binlog events in 'slave-bin.000005' from 4;
-ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log
diff --git a/mysql-test/r/rpl_log_pos.result b/mysql-test/r/rpl_log_pos.result
index cf13756966e..d0545f27d99 100644
--- a/mysql-test/r/rpl_log_pos.result
+++ b/mysql-test/r/rpl_log_pos.result
@@ -6,37 +6,37 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 98
+master-bin.000001 102 <Binlog_Ignore_DB>
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 98 # # master-bin.000001 Yes Yes 0 0 98 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 102 # # master-bin.000001 Yes Yes 0 0 102 # None 0 No #
stop slave;
-change master to master_log_pos=73;
+change master to master_log_pos=74;
start slave;
stop slave;
-change master to master_log_pos=73;
+change master to master_log_pos=74;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 # # master-bin.000001 No No 0 0 73 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 74 # # master-bin.000001 No No 0 0 74 # None 0 No #
start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 # # master-bin.000001 No Yes 0 0 73 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 74 # # master-bin.000001 No Yes 0 0 74 # None 0 No #
stop slave;
-change master to master_log_pos=173;
+change master to master_log_pos=177;
start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 173 # # master-bin.000001 No Yes 0 0 173 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 177 # # master-bin.000001 No Yes 0 0 177 # None 0 No #
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000001 98
+master-bin.000001 102 <Binlog_Ignore_DB>
create table if not exists t1 (n int);
drop table if exists t1;
create table t1 (n int);
insert into t1 values (1),(2),(3);
stop slave;
-change master to master_log_pos=98;
+change master to master_log_pos=102;
start slave;
select * from t1;
n
diff --git a/mysql-test/r/rpl_multi_delete.result b/mysql-test/r/rpl_multi_delete.result
index d2c68eee62e..e94a4e7947e 100644
--- a/mysql-test/r/rpl_multi_delete.result
+++ b/mysql-test/r/rpl_multi_delete.result
@@ -19,13 +19,4 @@ a
select * from t2;
a
1
-delete from t1;
-delete from t2;
-insert into t1 values(1);
-insert into t2 values(1);
-DELETE t1.*, t2.* from t1, t2;
-select * from t1;
-a
-select * from t2;
-a
drop table t1,t2;
diff --git a/mysql-test/r/rpl_multi_engine.result b/mysql-test/r/rpl_multi_engine.result
new file mode 100644
index 00000000000..27482eae6d9
--- /dev/null
+++ b/mysql-test/r/rpl_multi_engine.result
@@ -0,0 +1,365 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create database if not exists mysqltest1;
+use mysqltest1;
+drop table if exists t1;
+CREATE TABLE t1 (id MEDIUMINT NOT NULL, b1 BIT(8), vc
+VARCHAR(255), bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, f FLOAT DEFAULT
+0, total BIGINT UNSIGNED, y YEAR, t TIMESTAMP,PRIMARY KEY(id));
+use mysqltest1;
+alter table t1 engine=myisam;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL,
+ `b1` bit(8) default NULL,
+ `vc` varchar(255) default NULL,
+ `bc` char(255) default NULL,
+ `d` decimal(10,4) default '0.0000',
+ `f` float default '0',
+ `total` bigint(20) unsigned default NULL,
+ `y` year(4) default NULL,
+ `t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t1 engine=myisam;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL,
+ `b1` bit(8) default NULL,
+ `vc` varchar(255) default NULL,
+ `bc` char(255) default NULL,
+ `d` decimal(10,4) default '0.0000',
+ `f` float default '0',
+ `total` bigint(20) unsigned default NULL,
+ `y` year(4) default NULL,
+ `t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES(42,1,'Testing MySQL databases is a cool ', 'Must make it bug free for the customer',654321.4321,15.21,0,1965,"2005-11-14");
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+UPDATE t1 SET b1 = 0, t="2005-09-09" WHERE b1 = 1;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+DELETE FROM mysqltest1.t1 WHERE id = 42;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+alter table t1 engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL,
+ `b1` bit(8) default NULL,
+ `vc` varchar(255) default NULL,
+ `bc` char(255) default NULL,
+ `d` decimal(10,4) default '0.0000',
+ `f` float default '0',
+ `total` bigint(20) unsigned default NULL,
+ `y` year(4) default NULL,
+ `t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES(42,1,'Testing MySQL databases is a cool ', 'Must make it bug free for the customer',654321.4321,15.21,0,1965,"2005-11-14");
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+UPDATE t1 SET b1 = 0, t="2005-09-09" WHERE b1 = 1;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+DELETE FROM mysqltest1.t1 WHERE id = 42;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+alter table t1 engine=memory;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL,
+ `b1` bit(8) default NULL,
+ `vc` varchar(255) default NULL,
+ `bc` char(255) default NULL,
+ `d` decimal(10,4) default '0.0000',
+ `f` float default '0',
+ `total` bigint(20) unsigned default NULL,
+ `y` year(4) default NULL,
+ `t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES(42,1,'Testing MySQL databases is a cool ', 'Must make it bug free for the customer',654321.4321,15.21,0,1965,"2005-11-14");
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+UPDATE t1 SET b1 = 0, t="2005-09-09" WHERE b1 = 1;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+DELETE FROM mysqltest1.t1 WHERE id = 42;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+alter table t1 engine=memory;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL,
+ `b1` bit(8) default NULL,
+ `vc` varchar(255) default NULL,
+ `bc` char(255) default NULL,
+ `d` decimal(10,4) default '0.0000',
+ `f` float default '0',
+ `total` bigint(20) unsigned default NULL,
+ `y` year(4) default NULL,
+ `t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
+alter table t1 engine=myisam;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL,
+ `b1` bit(8) default NULL,
+ `vc` varchar(255) default NULL,
+ `bc` char(255) default NULL,
+ `d` decimal(10,4) default '0.0000',
+ `f` float default '0',
+ `total` bigint(20) unsigned default NULL,
+ `y` year(4) default NULL,
+ `t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES(42,1,'Testing MySQL databases is a cool ', 'Must make it bug free for the customer',654321.4321,15.21,0,1965,"2005-11-14");
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+UPDATE t1 SET b1 = 0, t="2005-09-09" WHERE b1 = 1;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+DELETE FROM mysqltest1.t1 WHERE id = 42;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+alter table t1 engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL,
+ `b1` bit(8) default NULL,
+ `vc` varchar(255) default NULL,
+ `bc` char(255) default NULL,
+ `d` decimal(10,4) default '0.0000',
+ `f` float default '0',
+ `total` bigint(20) unsigned default NULL,
+ `y` year(4) default NULL,
+ `t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES(42,1,'Testing MySQL databases is a cool ', 'Must make it bug free for the customer',654321.4321,15.21,0,1965,"2005-11-14");
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+UPDATE t1 SET b1 = 0, t="2005-09-09" WHERE b1 = 1;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+DELETE FROM mysqltest1.t1 WHERE id = 42;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+alter table t1 engine=memory;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL,
+ `b1` bit(8) default NULL,
+ `vc` varchar(255) default NULL,
+ `bc` char(255) default NULL,
+ `d` decimal(10,4) default '0.0000',
+ `f` float default '0',
+ `total` bigint(20) unsigned default NULL,
+ `y` year(4) default NULL,
+ `t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES(42,1,'Testing MySQL databases is a cool ', 'Must make it bug free for the customer',654321.4321,15.21,0,1965,"2005-11-14");
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+UPDATE t1 SET b1 = 0, t="2005-09-09" WHERE b1 = 1;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+DELETE FROM mysqltest1.t1 WHERE id = 42;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+alter table t1 engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL,
+ `b1` bit(8) default NULL,
+ `vc` varchar(255) default NULL,
+ `bc` char(255) default NULL,
+ `d` decimal(10,4) default '0.0000',
+ `f` float default '0',
+ `total` bigint(20) unsigned default NULL,
+ `y` year(4) default NULL,
+ `t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+alter table t1 engine=myisam;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL,
+ `b1` bit(8) default NULL,
+ `vc` varchar(255) default NULL,
+ `bc` char(255) default NULL,
+ `d` decimal(10,4) default '0.0000',
+ `f` float default '0',
+ `total` bigint(20) unsigned default NULL,
+ `y` year(4) default NULL,
+ `t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES(42,1,'Testing MySQL databases is a cool ', 'Must make it bug free for the customer',654321.4321,15.21,0,1965,"2005-11-14");
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+UPDATE t1 SET b1 = 0, t="2005-09-09" WHERE b1 = 1;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+DELETE FROM mysqltest1.t1 WHERE id = 42;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+alter table t1 engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL,
+ `b1` bit(8) default NULL,
+ `vc` varchar(255) default NULL,
+ `bc` char(255) default NULL,
+ `d` decimal(10,4) default '0.0000',
+ `f` float default '0',
+ `total` bigint(20) unsigned default NULL,
+ `y` year(4) default NULL,
+ `t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES(42,1,'Testing MySQL databases is a cool ', 'Must make it bug free for the customer',654321.4321,15.21,0,1965,"2005-11-14");
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+UPDATE t1 SET b1 = 0, t="2005-09-09" WHERE b1 = 1;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+DELETE FROM mysqltest1.t1 WHERE id = 42;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+alter table t1 engine=memory;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` mediumint(9) NOT NULL,
+ `b1` bit(8) default NULL,
+ `vc` varchar(255) default NULL,
+ `bc` char(255) default NULL,
+ `d` decimal(10,4) default '0.0000',
+ `f` float default '0',
+ `total` bigint(20) unsigned default NULL,
+ `y` year(4) default NULL,
+ `t` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
+INSERT INTO t1 VALUES(42,1,'Testing MySQL databases is a cool ', 'Must make it bug free for the customer',654321.4321,15.21,0,1965,"2005-11-14");
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 1 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-11-14 00:00:00
+UPDATE t1 SET b1 = 0, t="2005-09-09" WHERE b1 = 1;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+42 0 Testing MySQL databases is a cool Must make it bug free for the customer 654321.4321 15.21 0 1965 2005-09-09 00:00:00
+DELETE FROM mysqltest1.t1 WHERE id = 42;
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id;
+id hex(b1) vc bc d f total y t
+DROP TABLE t1;
diff --git a/mysql-test/r/rpl_multi_update.result b/mysql-test/r/rpl_multi_update.result
index 04cb1bc7460..524278be042 100644
--- a/mysql-test/r/rpl_multi_update.result
+++ b/mysql-test/r/rpl_multi_update.result
@@ -24,16 +24,4 @@ a b
1 0
2 1
UPDATE t1, t2 SET t1.b = t2.b WHERE t1.a = t2.a;
-delete from t1;
-delete from t2;
-insert into t1 values(1,1);
-insert into t2 values(1,1);
-update t1 set a=2;
-UPDATE t1, t2 SET t1.a = t2.a;
-select * from t1;
-a b
-1 1
-select * from t2;
-a b
-1 1
drop table t1, t2;
diff --git a/mysql-test/r/rpl_mystery22.result b/mysql-test/r/rpl_mystery22.result
deleted file mode 100644
index 348b3211cd5..00000000000
--- a/mysql-test/r/rpl_mystery22.result
+++ /dev/null
@@ -1,23 +0,0 @@
-stop slave;
-drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
-reset master;
-reset slave;
-drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
-start slave;
-create table t1(n int auto_increment primary key);
-insert into t1 values (2);
-insert into t1 values(NULL);
-insert into t1 values(NULL);
-delete from t1 where n = 2;
-start slave;
-stop slave;
-create table t2(n int);
-drop table t2;
-insert into t1 values(NULL);
-start slave;
-select * from t1;
-n
-1
-2
-3
-drop table t1;
diff --git a/mysql-test/r/rpl_openssl.result b/mysql-test/r/rpl_openssl.result
index d916e9f2c5c..be9ab29d8b7 100644
--- a/mysql-test/r/rpl_openssl.result
+++ b/mysql-test/r/rpl_openssl.result
@@ -20,11 +20,11 @@ t
1
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 replssl MASTER_MYPORT 1 master-bin.000001 398 # # master-bin.000001 Yes Yes 0 0 398 # None 0 Yes MYSQL_TEST_DIR/std_data/cacert.pem MYSQL_TEST_DIR/std_data/client-cert.pem MYSQL_TEST_DIR/std_data/client-key.pem #
+# 127.0.0.1 replssl MASTER_MYPORT 1 # # # # # # Yes # 0 0 # # None 0 Yes MYSQL_TEST_DIR/std_data/cacert.pem MYSQL_TEST_DIR/std_data/client-cert.pem MYSQL_TEST_DIR/std_data/client-key.pem #
stop slave;
change master to master_user='root',master_password='', master_ssl=0;
start slave;
drop table t1;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 474 # # master-bin.000001 Yes Yes 0 0 474 # None 0 No MYSQL_TEST_DIR/std_data/cacert.pem MYSQL_TEST_DIR/std_data/client-cert.pem MYSQL_TEST_DIR/std_data/client-key.pem #
+# 127.0.0.1 root MASTER_MYPORT 1 # # # # # # Yes # 0 0 # # None 0 No MYSQL_TEST_DIR/std_data/cacert.pem MYSQL_TEST_DIR/std_data/client-cert.pem MYSQL_TEST_DIR/std_data/client-key.pem #
diff --git a/mysql-test/r/rpl_replicate_do.result b/mysql-test/r/rpl_replicate_do.result
index d8666080a71..438671fb103 100644
--- a/mysql-test/r/rpl_replicate_do.result
+++ b/mysql-test/r/rpl_replicate_do.result
@@ -28,7 +28,7 @@ ERROR 42S02: Table 'test.t11' doesn't exist
drop table if exists t1,t2,t11;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1658 # # master-bin.000001 Yes Yes test.t1 0 0 1658 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 # # # master-bin.000001 Yes Yes test.t1 # 0 0 # # None 0 No #
create table t1 (ts timestamp);
set one_shot time_zone='met';
insert into t1 values('2005-08-12 00:00:00');
diff --git a/mysql-test/r/rpl_replicate_ignore_db.result b/mysql-test/r/rpl_replicate_ignore_db.result
new file mode 100644
index 00000000000..0135804c02d
--- /dev/null
+++ b/mysql-test/r/rpl_replicate_ignore_db.result
@@ -0,0 +1,23 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop database if exists mysqltest1;
+drop database if exists mysqltest2;
+create database mysqltest1;
+create database mysqltest2;
+use mysqltest1;
+create table t1 (a int);
+insert into t1 values(1);
+select * from mysqltest1.t1;
+ERROR 42S02: Table 'mysqltest1.t1' doesn't exist
+use mysqltest2;
+create table t1 (a int);
+insert into t1 values(1);
+select * from mysqltest2.t1;
+a
+1
+drop database mysqltest1;
+drop database mysqltest2;
diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result
index bf2ef98c87f..264f5d224bd 100644
--- a/mysql-test/r/rpl_rotate_logs.result
+++ b/mysql-test/r/rpl_rotate_logs.result
@@ -16,7 +16,7 @@ create table t1 (s text);
insert into t1 values('Could not break slave'),('Tried hard');
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 60 master-bin.000001 548 # # master-bin.000001 Yes Yes 0 0 548 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 60 master-bin.000001 552 # # master-bin.000001 Yes Yes # 0 0 552 # None 0 No #
select * from t1;
s
Could not break slave
@@ -27,9 +27,9 @@ insert into t2 values (34),(67),(123);
flush logs;
show binary logs;
Log_name File_size
-master-bin.000001 592
-master-bin.000002 363
-master-bin.000003 98
+master-bin.000001 596
+master-bin.000002 367
+master-bin.000003 102
create table t3 select * from temp_table;
select * from t3;
a
@@ -43,21 +43,21 @@ start slave;
purge master logs to 'master-bin.000002';
show master logs;
Log_name File_size
-master-bin.000002 363
-master-bin.000003 407
+master-bin.000002 367
+master-bin.000003 411
purge binary logs to 'master-bin.000002';
show binary logs;
Log_name File_size
-master-bin.000002 363
-master-bin.000003 407
+master-bin.000002 367
+master-bin.000003 411
purge master logs before now();
show binary logs;
Log_name File_size
-master-bin.000003 407
+master-bin.000003 411
insert into t2 values (65);
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 60 master-bin.000003 496 # # master-bin.000003 Yes Yes 0 0 496 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 60 master-bin.000003 500 # # master-bin.000003 Yes Yes # 0 0 500 # None 0 No #
select * from t2;
m
34
@@ -74,18 +74,18 @@ count(*)
create table t4 select * from temp_table;
show binary logs;
Log_name File_size
-master-bin.000003 4185
-master-bin.000004 4190
-master-bin.000005 2032
+master-bin.000003 4189
+master-bin.000004 4194
+master-bin.000005 2036
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000005 2032
+master-bin.000005 2036
select * from t4;
a
testing temporary tables part 2
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 60 master-bin.000005 2032 # # master-bin.000005 Yes Yes 0 0 2032 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 60 master-bin.000005 2036 # # master-bin.000005 Yes Yes # 0 0 2036 # None 0 No #
lock tables t3 read;
select count(*) from t3 where n >= 4;
count(*)
diff --git a/mysql-test/r/rpl_row_001.result b/mysql-test/r/rpl_row_001.result
new file mode 100644
index 00000000000..990ebbc5d7a
--- /dev/null
+++ b/mysql-test/r/rpl_row_001.result
@@ -0,0 +1,55 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (word CHAR(20) NOT NULL);
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
+LOAD DATA LOCAL INFILE 'MYSQL_TEST_DIR/std_data/words.dat' INTO TABLE t1;
+SELECT * FROM t1 LIMIT 10;
+word
+Aarhus
+Aaron
+Ababa
+aback
+abaft
+abandon
+abandoned
+abandoning
+abandonment
+abandons
+STOP SLAVE;
+SET PASSWORD FOR root@"localhost" = PASSWORD('foo');
+START SLAVE;
+SET PASSWORD FOR root@"localhost" = PASSWORD('');
+CREATE TABLE t3(n INT);
+INSERT INTO t3 VALUES(1),(2);
+SELECT * FROM t3;
+n
+1
+2
+SELECT SUM(LENGTH(word)) FROM t1;
+SUM(LENGTH(word))
+1022
+DROP TABLE t1,t3;
+CREATE TABLE t1 (n INT) ENGINE=MYISAM;
+RESET MASTER;
+STOP SLAVE;
+RESET SLAVE;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+5000
+LOCK TABLES t1 READ;
+START SLAVE;
+UNLOCK TABLES;
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+5000
+DROP TABLE t1;
+CREATE TABLE t1 (n INT);
+INSERT INTO t1 VALUES(3456);
+SELECT n FROM t1;
+n
+3456
+DROP TABLE t1;
diff --git a/mysql-test/r/rpl_row_4_bytes.result b/mysql-test/r/rpl_row_4_bytes.result
new file mode 100644
index 00000000000..b88d5661a90
--- /dev/null
+++ b/mysql-test/r/rpl_row_4_bytes.result
@@ -0,0 +1,27 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop database if exists mysqltest1;
+create database mysqltest1;
+use mysqltest1;
+CREATE TABLE t1 (a char(3));
+CREATE TABLE t2 (a char(3));
+insert into t1 values("ANN");
+insert into t1 values("GUI");
+insert into t2 values("LIL");
+insert into t2 values("ABE");
+insert into t2 values("ANG");
+use mysqltest1;
+select * from t1 order by a;
+a
+ANN
+GUI
+select * from t2 order by a;
+a
+ABE
+ANG
+LIL
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/rpl_row_EE_err.result b/mysql-test/r/rpl_row_EE_err.result
new file mode 100644
index 00000000000..23b0c88f49d
--- /dev/null
+++ b/mysql-test/r/rpl_row_EE_err.result
@@ -0,0 +1,19 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1 (a int) engine=myisam;
+flush tables;
+drop table if exists t1;
+Warnings:
+Error 2 Can't find file: 't1' (errno: 2)
+create table t1 (a int, unique(a)) engine=myisam;
+set sql_log_bin=0;
+insert into t1 values(2);
+set sql_log_bin=1;
+insert into t1 values(1),(2);
+ERROR 23000: Duplicate entry '2' for key 1
+drop table t1;
+stop slave;
diff --git a/mysql-test/r/rpl_row_NOW.result b/mysql-test/r/rpl_row_NOW.result
new file mode 100644
index 00000000000..ed045efa7af
--- /dev/null
+++ b/mysql-test/r/rpl_row_NOW.result
@@ -0,0 +1,28 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create database if not exists mysqltest1;
+DROP TABLE IF EXISTS mysqltest1.t1;
+CREATE TABLE mysqltest1.t1 (n MEDIUMINT NOT NULL AUTO_INCREMENT,
+a TIMESTAMP DEFAULT '2005-05-05 01:01:01',
+b TIMESTAMP DEFAULT '2005-05-05 01:01:01',
+PRIMARY KEY(n));
+CREATE FUNCTION mysqltest1.f1() RETURNS TIMESTAMP
+BEGIN
+DECLARE v1 INT DEFAULT 300;
+WHILE v1 > 0 DO
+SET v1 = v1 - 1;
+END WHILE;
+RETURN NOW();
+END|
+INSERT INTO mysqltest1.t1 VALUES(NULL,NOW(),mysqltest1.f1());
+CREATE TRIGGER mysqltest1.trig1 BEFORE INSERT ON mysqltest1.t1
+FOR EACH ROW BEGIN
+SET new.b = mysqltest1.f1();
+END|
+INSERT INTO mysqltest1.t1 SET n = NULL, a = now();
+DROP TABLE IF EXISTS mysqltest1.t1;
+DROP FUNCTION mysqltest1.f1;
diff --git a/mysql-test/r/rpl_row_USER.result b/mysql-test/r/rpl_row_USER.result
new file mode 100644
index 00000000000..827afb72b10
--- /dev/null
+++ b/mysql-test/r/rpl_row_USER.result
@@ -0,0 +1,36 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP DATABASE IF EXISTS mysqltest1;
+CREATE DATABASE mysqltest1;
+CREATE USER tester IDENTIFIED BY 'test';
+GRANT ALL ON mysqltest1.* TO 'tester'@'%' IDENTIFIED BY 'test';
+GRANT ALL ON mysqltest1.* TO ''@'localhost%';
+FLUSH PRIVILEGES;
+CREATE TABLE mysqltest1.t1 (a INT, users VARCHAR(255), PRIMARY KEY(a));
+INSERT INTO mysqltest1.t1 VALUES(1,USER());
+INSERT INTO mysqltest1.t1 VALUES(2,CURRENT_USER());
+create procedure mysqltest1.p1()
+begin
+INSERT INTO mysqltest1.t1 VALUES(3,USER());
+INSERT INTO mysqltest1.t1 VALUES(4,CURRENT_USER());
+end|
+CALL mysqltest1.p1();
+SELECT * FROM mysqltest1.t1;
+a users
+1 tester@localhost
+2 @localhost
+3 tester@localhost
+4 @localhost
+SELECT * FROM mysqltest1.t1;
+a users
+1 tester@localhost
+2 @localhost
+3 tester@localhost
+4 @localhost
+DROP DATABASE mysqltest1;
+REVOKE ALL ON mysqltest1.* FROM 'tester'@'%';
+REVOKE ALL ON mysqltest1.* FROM ''@'localhost%';
diff --git a/mysql-test/r/rpl_row_UUID.result b/mysql-test/r/rpl_row_UUID.result
new file mode 100644
index 00000000000..06c81e28ef6
--- /dev/null
+++ b/mysql-test/r/rpl_row_UUID.result
@@ -0,0 +1,38 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
+CREATE TABLE test.t1 (a INT, blob_column LONGBLOB, vchar_column VARCHAR(100), PRIMARY KEY(a)) engine=myisam;
+INSERT INTO test.t1 VALUES(1,UUID(),UUID());
+create procedure test.p1()
+begin
+INSERT INTO test.t1 VALUES(2,UUID(),UUID());
+INSERT INTO test.t1 VALUES(3,UUID(),UUID());
+end|
+CALL test.p1();
+create function test.fn1(x int)
+returns int
+begin
+insert into t1 values (4+x,UUID(),UUID());
+insert into t1 values (5+x,UUID(),UUID());
+return 0;
+end|
+select fn1(0);
+fn1(0)
+0
+create table t2 (a int);
+insert into t2 values(fn1(2));
+SHOW CREATE TABLE test.t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) NOT NULL default '0',
+ `blob_column` longblob,
+ `vchar_column` varchar(100) default NULL,
+ PRIMARY KEY (`a`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP PROCEDURE test.p1;
+DROP TABLE test.t1;
diff --git a/mysql-test/r/rpl_row_basic_2myisam.result b/mysql-test/r/rpl_row_basic_2myisam.result
new file mode 100644
index 00000000000..12a8d8282e3
--- /dev/null
+++ b/mysql-test/r/rpl_row_basic_2myisam.result
@@ -0,0 +1,426 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (C1 CHAR(1), C2 CHAR(1), INDEX (C1)) ENGINE = 'MYISAM' ;
+SELECT * FROM t1;
+C1 C2
+SELECT * FROM t1;
+C1 C2
+INSERT INTO t1 VALUES ('A','B'), ('X','Y'), ('X','X');
+INSERT INTO t1 VALUES ('A','C'), ('X','Z'), ('A','A');
+SELECT * FROM t1 ORDER BY C1,C2;
+C1 C2
+A A
+A B
+A C
+X X
+X Y
+X Z
+SELECT * FROM t1 ORDER BY C1,C2;
+C1 C2
+A A
+A B
+A C
+X X
+X Y
+X Z
+DELETE FROM t1 WHERE C1 = C2;
+SELECT * FROM t1 ORDER BY C1,C2;
+C1 C2
+A B
+A C
+X Y
+X Z
+SELECT * FROM t1 ORDER BY C1,C2;
+C1 C2
+A B
+A C
+X Y
+X Z
+UPDATE t1 SET C2 = 'I' WHERE C1 = 'A' AND C2 = 'C';
+SELECT * FROM t1 ORDER BY C1,C2;
+C1 C2
+A B
+A I
+X Y
+X Z
+SELECT * FROM t1 ORDER BY C1,C2;
+C1 C2
+A B
+A I
+X Y
+X Z
+UPDATE t1 SET c2 = 'Q' WHERE c1 = 'A' AND c2 = 'N';
+SELECT * FROM t1 ORDER BY c1,c2;
+C1 C2
+A B
+A I
+X Y
+X Z
+SELECT * FROM t1 ORDER BY c1,c2;
+C1 C2
+A B
+A I
+X Y
+X Z
+CREATE TABLE t2 (c1 INT, c12 char(1), c2 INT, PRIMARY KEY (c1)) ENGINE = 'MYISAM' ;
+INSERT INTO t2
+VALUES (1,'A',2), (2,'A',4), (3,'A',9), (4,'A',15), (5,'A',25),
+(6,'A',35), (7,'A',50), (8,'A',64), (9,'A',81);
+SELECT * FROM t2 ORDER BY c1,c2;
+c1 c12 c2
+1 A 2
+2 A 4
+3 A 9
+4 A 15
+5 A 25
+6 A 35
+7 A 50
+8 A 64
+9 A 81
+SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2;
+c1 c12 c2
+2 A 4
+3 A 9
+5 A 25
+8 A 64
+9 A 81
+SELECT * FROM t2 ORDER BY c1,c2;
+c1 c12 c2
+1 A 2
+2 A 4
+3 A 9
+4 A 15
+5 A 25
+6 A 35
+7 A 50
+8 A 64
+9 A 81
+SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2;
+c1 c12 c2
+2 A 4
+3 A 9
+5 A 25
+8 A 64
+9 A 81
+UPDATE t2 SET c2 = c1*c1 WHERE c2 != c1*c1;
+SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2;
+c1 c12 c2
+1 A 1
+2 A 4
+3 A 9
+4 A 16
+5 A 25
+6 A 36
+7 A 49
+8 A 64
+9 A 81
+SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2;
+c1 c12 c2
+1 A 1
+2 A 4
+3 A 9
+4 A 16
+5 A 25
+6 A 36
+7 A 49
+8 A 64
+9 A 81
+UPDATE t2 SET c12 = 'Q' WHERE c1 = 1 AND c2 = 999;
+SELECT * FROM t2 ORDER BY c1,c2;
+c1 c12 c2
+1 A 1
+2 A 4
+3 A 9
+4 A 16
+5 A 25
+6 A 36
+7 A 49
+8 A 64
+9 A 81
+SELECT * FROM t2 ORDER BY c1,c2;
+c1 c12 c2
+1 A 1
+2 A 4
+3 A 9
+4 A 16
+5 A 25
+6 A 36
+7 A 49
+8 A 64
+9 A 81
+DELETE FROM t2 WHERE c1 % 4 = 0;
+SELECT * FROM t2 ORDER BY c1,c2;
+c1 c12 c2
+1 A 1
+2 A 4
+3 A 9
+5 A 25
+6 A 36
+7 A 49
+9 A 81
+SELECT * FROM t2 ORDER BY c1,c2;
+c1 c12 c2
+1 A 1
+2 A 4
+3 A 9
+5 A 25
+6 A 36
+7 A 49
+9 A 81
+UPDATE t2 SET c12='X';
+CREATE TABLE t3 (C1 CHAR(1), C2 CHAR(1), pk1 INT, C3 CHAR(1), pk2 INT, PRIMARY KEY (pk1,pk2)) ENGINE = 'MYISAM' ;
+INSERT INTO t3 VALUES ('A','B',1,'B',1), ('X','Y',2,'B',1), ('X','X',3,'B',1);
+INSERT INTO t3 VALUES ('A','C',1,'B',2), ('X','Z',2,'B',2), ('A','A',3,'B',2);
+SELECT * FROM t3 ORDER BY C1,C2;
+C1 C2 pk1 C3 pk2
+A A 3 B 2
+A B 1 B 1
+A C 1 B 2
+X X 3 B 1
+X Y 2 B 1
+X Z 2 B 2
+SELECT * FROM t3 ORDER BY C1,C2;
+C1 C2 pk1 C3 pk2
+A A 3 B 2
+A B 1 B 1
+A C 1 B 2
+X X 3 B 1
+X Y 2 B 1
+X Z 2 B 2
+DELETE FROM t3 WHERE C1 = C2;
+SELECT * FROM t3 ORDER BY C1,C2;
+C1 C2 pk1 C3 pk2
+A B 1 B 1
+A C 1 B 2
+X Y 2 B 1
+X Z 2 B 2
+SELECT * FROM t3 ORDER BY C1,C2;
+C1 C2 pk1 C3 pk2
+A B 1 B 1
+A C 1 B 2
+X Y 2 B 1
+X Z 2 B 2
+UPDATE t3 SET C2 = 'I' WHERE C1 = 'A' AND C2 = 'C';
+SELECT * FROM t3 ORDER BY C1,C2;
+C1 C2 pk1 C3 pk2
+A B 1 B 1
+A I 1 B 2
+X Y 2 B 1
+X Z 2 B 2
+SELECT * FROM t3 ORDER BY C1,C2;
+C1 C2 pk1 C3 pk2
+A B 1 B 1
+A I 1 B 2
+X Y 2 B 1
+X Z 2 B 2
+CREATE TABLE t6 (C1 CHAR(1), C2 CHAR(1), C3 INT) ENGINE = 'MYISAM' ;
+INSERT INTO t6 VALUES ('A','B',1), ('X','Y',2), ('X','X',3);
+INSERT INTO t6 VALUES ('A','C',4), ('X','Z',5), ('A','A',6);
+SELECT * FROM t6 ORDER BY C3;
+C1 C2 C3
+A B 1
+X Y 2
+X X 3
+A C 4
+X Z 5
+A A 6
+SELECT * FROM t6 ORDER BY C3;
+C1 C2 C3
+A B 1
+X Y 2
+X X 3
+A C 4
+X Z 5
+A A 6
+DELETE FROM t6 WHERE C1 = C2;
+SELECT * FROM t6 ORDER BY C3;
+C1 C2 C3
+A B 1
+X Y 2
+A C 4
+X Z 5
+SELECT * FROM t6 ORDER BY C3;
+C1 C2 C3
+A B 1
+X Y 2
+A C 4
+X Z 5
+UPDATE t6 SET C2 = 'I' WHERE C1 = 'A' AND C2 = 'C';
+SELECT * FROM t6 ORDER BY C3;
+C1 C2 C3
+A B 1
+X Y 2
+A I 4
+X Z 5
+SELECT * FROM t6 ORDER BY C3;
+C1 C2 C3
+A B 1
+X Y 2
+A I 4
+X Z 5
+CREATE TABLE t5 (C1 CHAR(1), C2 CHAR(1), C3 INT PRIMARY KEY) ENGINE = 'MYISAM' ;
+INSERT INTO t5 VALUES ('A','B',1), ('X','Y',2), ('X','X',3);
+INSERT INTO t5 VALUES ('A','C',4), ('X','Z',5), ('A','A',6);
+UPDATE t5,t2,t3 SET t5.C2='Q', t2.c12='R', t3.C3 ='S' WHERE t5.C1 = t2.c12 AND t5.C1 = t3.C1;
+SELECT * FROM t5,t2,t3 WHERE t5.C2='Q' AND t2.c12='R' AND t3.C3 ='S' ORDER BY t5.C3,t2.c1,t3.pk1,t3.pk2;
+C1 C2 C3 c1 c12 c2 C1 C2 pk1 C3 pk2
+X Q 2 1 R 1 X Y 2 S 1
+X Q 2 1 R 1 X Z 2 S 2
+X Q 2 2 R 4 X Y 2 S 1
+X Q 2 2 R 4 X Z 2 S 2
+X Q 2 3 R 9 X Y 2 S 1
+X Q 2 3 R 9 X Z 2 S 2
+X Q 2 5 R 25 X Y 2 S 1
+X Q 2 5 R 25 X Z 2 S 2
+X Q 2 6 R 36 X Y 2 S 1
+X Q 2 6 R 36 X Z 2 S 2
+X Q 2 7 R 49 X Y 2 S 1
+X Q 2 7 R 49 X Z 2 S 2
+X Q 2 9 R 81 X Y 2 S 1
+X Q 2 9 R 81 X Z 2 S 2
+X Q 3 1 R 1 X Y 2 S 1
+X Q 3 1 R 1 X Z 2 S 2
+X Q 3 2 R 4 X Y 2 S 1
+X Q 3 2 R 4 X Z 2 S 2
+X Q 3 3 R 9 X Y 2 S 1
+X Q 3 3 R 9 X Z 2 S 2
+X Q 3 5 R 25 X Y 2 S 1
+X Q 3 5 R 25 X Z 2 S 2
+X Q 3 6 R 36 X Y 2 S 1
+X Q 3 6 R 36 X Z 2 S 2
+X Q 3 7 R 49 X Y 2 S 1
+X Q 3 7 R 49 X Z 2 S 2
+X Q 3 9 R 81 X Y 2 S 1
+X Q 3 9 R 81 X Z 2 S 2
+X Q 5 1 R 1 X Y 2 S 1
+X Q 5 1 R 1 X Z 2 S 2
+X Q 5 2 R 4 X Y 2 S 1
+X Q 5 2 R 4 X Z 2 S 2
+X Q 5 3 R 9 X Y 2 S 1
+X Q 5 3 R 9 X Z 2 S 2
+X Q 5 5 R 25 X Y 2 S 1
+X Q 5 5 R 25 X Z 2 S 2
+X Q 5 6 R 36 X Y 2 S 1
+X Q 5 6 R 36 X Z 2 S 2
+X Q 5 7 R 49 X Y 2 S 1
+X Q 5 7 R 49 X Z 2 S 2
+X Q 5 9 R 81 X Y 2 S 1
+X Q 5 9 R 81 X Z 2 S 2
+SELECT * FROM t5,t2,t3 WHERE t5.C2='Q' AND t2.c12='R' AND t3.C3 ='S' ORDER BY t5.C3,t2.c1,t3.pk1,t3.pk2;
+C1 C2 C3 c1 c12 c2 C1 C2 pk1 C3 pk2
+X Q 2 1 R 1 X Y 2 S 1
+X Q 2 1 R 1 X Z 2 S 2
+X Q 2 2 R 4 X Y 2 S 1
+X Q 2 2 R 4 X Z 2 S 2
+X Q 2 3 R 9 X Y 2 S 1
+X Q 2 3 R 9 X Z 2 S 2
+X Q 2 5 R 25 X Y 2 S 1
+X Q 2 5 R 25 X Z 2 S 2
+X Q 2 6 R 36 X Y 2 S 1
+X Q 2 6 R 36 X Z 2 S 2
+X Q 2 7 R 49 X Y 2 S 1
+X Q 2 7 R 49 X Z 2 S 2
+X Q 2 9 R 81 X Y 2 S 1
+X Q 2 9 R 81 X Z 2 S 2
+X Q 3 1 R 1 X Y 2 S 1
+X Q 3 1 R 1 X Z 2 S 2
+X Q 3 2 R 4 X Y 2 S 1
+X Q 3 2 R 4 X Z 2 S 2
+X Q 3 3 R 9 X Y 2 S 1
+X Q 3 3 R 9 X Z 2 S 2
+X Q 3 5 R 25 X Y 2 S 1
+X Q 3 5 R 25 X Z 2 S 2
+X Q 3 6 R 36 X Y 2 S 1
+X Q 3 6 R 36 X Z 2 S 2
+X Q 3 7 R 49 X Y 2 S 1
+X Q 3 7 R 49 X Z 2 S 2
+X Q 3 9 R 81 X Y 2 S 1
+X Q 3 9 R 81 X Z 2 S 2
+X Q 5 1 R 1 X Y 2 S 1
+X Q 5 1 R 1 X Z 2 S 2
+X Q 5 2 R 4 X Y 2 S 1
+X Q 5 2 R 4 X Z 2 S 2
+X Q 5 3 R 9 X Y 2 S 1
+X Q 5 3 R 9 X Z 2 S 2
+X Q 5 5 R 25 X Y 2 S 1
+X Q 5 5 R 25 X Z 2 S 2
+X Q 5 6 R 36 X Y 2 S 1
+X Q 5 6 R 36 X Z 2 S 2
+X Q 5 7 R 49 X Y 2 S 1
+X Q 5 7 R 49 X Z 2 S 2
+X Q 5 9 R 81 X Y 2 S 1
+X Q 5 9 R 81 X Z 2 S 2
+CREATE TABLE t4 (C1 CHAR(1) PRIMARY KEY, B1 BIT(1), B2 BIT(1) NOT NULL DEFAULT 0, C2 CHAR(1) NOT NULL DEFAULT 'A') ENGINE = 'MYISAM' ;
+INSERT INTO t4 SET C1 = 1;
+SELECT C1,HEX(B1),HEX(B2) FROM t4 ORDER BY C1;
+C1 HEX(B1) HEX(B2)
+1 NULL 0
+SELECT C1,HEX(B1),HEX(B2) FROM t4 ORDER BY C1;
+C1 HEX(B1) HEX(B2)
+1 NULL 0
+CREATE TABLE t7 (C1 INT PRIMARY KEY, C2 INT) ENGINE = 'MYISAM' ;
+
+--- on slave: original values ---
+INSERT INTO t7 VALUES (1,3), (2,6), (3,9);
+SELECT * FROM t7 ORDER BY C1;
+C1 C2
+1 3
+2 6
+3 9
+
+--- on master: new values inserted ---
+INSERT INTO t7 VALUES (1,2), (2,4), (3,6);
+SELECT * FROM t7 ORDER BY C1;
+C1 C2
+1 2
+2 4
+3 6
+
+--- on slave: old values should be overwritten by replicated values ---
+SELECT * FROM t7 ORDER BY C1;
+C1 C2
+1 2
+2 4
+3 6
+
+--- on master ---
+DROP TABLE t7;
+CREATE TABLE t7 (a INT PRIMARY KEY, b INT UNIQUE, c INT UNIQUE) ENGINE = 'MYISAM' ;
+INSERT INTO t7 VALUES (99,99,99);
+INSERT INTO t7 VALUES (99,22,33);
+ERROR 23000: Duplicate entry '99' for key 1
+INSERT INTO t7 VALUES (11,99,33);
+ERROR 23000: Duplicate entry '99' for key 2
+INSERT INTO t7 VALUES (11,22,99);
+ERROR 23000: Duplicate entry '99' for key 3
+SELECT * FROM t7 ORDER BY a;
+a b c
+99 99 99
+
+--- on slave ---
+SELECT * FROM t7 ORDER BY a;
+a b c
+99 99 99
+INSERT INTO t7 VALUES (1,2,3), (2,4,6), (3,6,9);
+SELECT * FROM t7 ORDER BY a;
+a b c
+1 2 3
+2 4 6
+3 6 9
+99 99 99
+
+--- on master ---
+INSERT INTO t7 VALUES (2,4,8);
+
+--- on slave ---
+SELECT * FROM t7 ORDER BY a;
+a b c
+1 2 3
+2 4 8
+3 6 9
+99 99 99
+DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7;
diff --git a/mysql-test/r/rpl_row_basic_3innodb.result b/mysql-test/r/rpl_row_basic_3innodb.result
new file mode 100644
index 00000000000..ed9b231e1a1
--- /dev/null
+++ b/mysql-test/r/rpl_row_basic_3innodb.result
@@ -0,0 +1,426 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (C1 CHAR(1), C2 CHAR(1), INDEX (C1)) ENGINE = 'INNODB' ;
+SELECT * FROM t1;
+C1 C2
+SELECT * FROM t1;
+C1 C2
+INSERT INTO t1 VALUES ('A','B'), ('X','Y'), ('X','X');
+INSERT INTO t1 VALUES ('A','C'), ('X','Z'), ('A','A');
+SELECT * FROM t1 ORDER BY C1,C2;
+C1 C2
+A A
+A B
+A C
+X X
+X Y
+X Z
+SELECT * FROM t1 ORDER BY C1,C2;
+C1 C2
+A A
+A B
+A C
+X X
+X Y
+X Z
+DELETE FROM t1 WHERE C1 = C2;
+SELECT * FROM t1 ORDER BY C1,C2;
+C1 C2
+A B
+A C
+X Y
+X Z
+SELECT * FROM t1 ORDER BY C1,C2;
+C1 C2
+A B
+A C
+X Y
+X Z
+UPDATE t1 SET C2 = 'I' WHERE C1 = 'A' AND C2 = 'C';
+SELECT * FROM t1 ORDER BY C1,C2;
+C1 C2
+A B
+A I
+X Y
+X Z
+SELECT * FROM t1 ORDER BY C1,C2;
+C1 C2
+A B
+A I
+X Y
+X Z
+UPDATE t1 SET c2 = 'Q' WHERE c1 = 'A' AND c2 = 'N';
+SELECT * FROM t1 ORDER BY c1,c2;
+C1 C2
+A B
+A I
+X Y
+X Z
+SELECT * FROM t1 ORDER BY c1,c2;
+C1 C2
+A B
+A I
+X Y
+X Z
+CREATE TABLE t2 (c1 INT, c12 char(1), c2 INT, PRIMARY KEY (c1)) ENGINE = 'INNODB' ;
+INSERT INTO t2
+VALUES (1,'A',2), (2,'A',4), (3,'A',9), (4,'A',15), (5,'A',25),
+(6,'A',35), (7,'A',50), (8,'A',64), (9,'A',81);
+SELECT * FROM t2 ORDER BY c1,c2;
+c1 c12 c2
+1 A 2
+2 A 4
+3 A 9
+4 A 15
+5 A 25
+6 A 35
+7 A 50
+8 A 64
+9 A 81
+SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2;
+c1 c12 c2
+2 A 4
+3 A 9
+5 A 25
+8 A 64
+9 A 81
+SELECT * FROM t2 ORDER BY c1,c2;
+c1 c12 c2
+1 A 2
+2 A 4
+3 A 9
+4 A 15
+5 A 25
+6 A 35
+7 A 50
+8 A 64
+9 A 81
+SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2;
+c1 c12 c2
+2 A 4
+3 A 9
+5 A 25
+8 A 64
+9 A 81
+UPDATE t2 SET c2 = c1*c1 WHERE c2 != c1*c1;
+SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2;
+c1 c12 c2
+1 A 1
+2 A 4
+3 A 9
+4 A 16
+5 A 25
+6 A 36
+7 A 49
+8 A 64
+9 A 81
+SELECT * FROM t2 WHERE c2 = c1 * c1 ORDER BY c1,c2;
+c1 c12 c2
+1 A 1
+2 A 4
+3 A 9
+4 A 16
+5 A 25
+6 A 36
+7 A 49
+8 A 64
+9 A 81
+UPDATE t2 SET c12 = 'Q' WHERE c1 = 1 AND c2 = 999;
+SELECT * FROM t2 ORDER BY c1,c2;
+c1 c12 c2
+1 A 1
+2 A 4
+3 A 9
+4 A 16
+5 A 25
+6 A 36
+7 A 49
+8 A 64
+9 A 81
+SELECT * FROM t2 ORDER BY c1,c2;
+c1 c12 c2
+1 A 1
+2 A 4
+3 A 9
+4 A 16
+5 A 25
+6 A 36
+7 A 49
+8 A 64
+9 A 81
+DELETE FROM t2 WHERE c1 % 4 = 0;
+SELECT * FROM t2 ORDER BY c1,c2;
+c1 c12 c2
+1 A 1
+2 A 4
+3 A 9
+5 A 25
+6 A 36
+7 A 49
+9 A 81
+SELECT * FROM t2 ORDER BY c1,c2;
+c1 c12 c2
+1 A 1
+2 A 4
+3 A 9
+5 A 25
+6 A 36
+7 A 49
+9 A 81
+UPDATE t2 SET c12='X';
+CREATE TABLE t3 (C1 CHAR(1), C2 CHAR(1), pk1 INT, C3 CHAR(1), pk2 INT, PRIMARY KEY (pk1,pk2)) ENGINE = 'INNODB' ;
+INSERT INTO t3 VALUES ('A','B',1,'B',1), ('X','Y',2,'B',1), ('X','X',3,'B',1);
+INSERT INTO t3 VALUES ('A','C',1,'B',2), ('X','Z',2,'B',2), ('A','A',3,'B',2);
+SELECT * FROM t3 ORDER BY C1,C2;
+C1 C2 pk1 C3 pk2
+A A 3 B 2
+A B 1 B 1
+A C 1 B 2
+X X 3 B 1
+X Y 2 B 1
+X Z 2 B 2
+SELECT * FROM t3 ORDER BY C1,C2;
+C1 C2 pk1 C3 pk2
+A A 3 B 2
+A B 1 B 1
+A C 1 B 2
+X X 3 B 1
+X Y 2 B 1
+X Z 2 B 2
+DELETE FROM t3 WHERE C1 = C2;
+SELECT * FROM t3 ORDER BY C1,C2;
+C1 C2 pk1 C3 pk2
+A B 1 B 1
+A C 1 B 2
+X Y 2 B 1
+X Z 2 B 2
+SELECT * FROM t3 ORDER BY C1,C2;
+C1 C2 pk1 C3 pk2
+A B 1 B 1
+A C 1 B 2
+X Y 2 B 1
+X Z 2 B 2
+UPDATE t3 SET C2 = 'I' WHERE C1 = 'A' AND C2 = 'C';
+SELECT * FROM t3 ORDER BY C1,C2;
+C1 C2 pk1 C3 pk2
+A B 1 B 1
+A I 1 B 2
+X Y 2 B 1
+X Z 2 B 2
+SELECT * FROM t3 ORDER BY C1,C2;
+C1 C2 pk1 C3 pk2
+A B 1 B 1
+A I 1 B 2
+X Y 2 B 1
+X Z 2 B 2
+CREATE TABLE t6 (C1 CHAR(1), C2 CHAR(1), C3 INT) ENGINE = 'INNODB' ;
+INSERT INTO t6 VALUES ('A','B',1), ('X','Y',2), ('X','X',3);
+INSERT INTO t6 VALUES ('A','C',4), ('X','Z',5), ('A','A',6);
+SELECT * FROM t6 ORDER BY C3;
+C1 C2 C3
+A B 1
+X Y 2
+X X 3
+A C 4
+X Z 5
+A A 6
+SELECT * FROM t6 ORDER BY C3;
+C1 C2 C3
+A B 1
+X Y 2
+X X 3
+A C 4
+X Z 5
+A A 6
+DELETE FROM t6 WHERE C1 = C2;
+SELECT * FROM t6 ORDER BY C3;
+C1 C2 C3
+A B 1
+X Y 2
+A C 4
+X Z 5
+SELECT * FROM t6 ORDER BY C3;
+C1 C2 C3
+A B 1
+X Y 2
+A C 4
+X Z 5
+UPDATE t6 SET C2 = 'I' WHERE C1 = 'A' AND C2 = 'C';
+SELECT * FROM t6 ORDER BY C3;
+C1 C2 C3
+A B 1
+X Y 2
+A I 4
+X Z 5
+SELECT * FROM t6 ORDER BY C3;
+C1 C2 C3
+A B 1
+X Y 2
+A I 4
+X Z 5
+CREATE TABLE t5 (C1 CHAR(1), C2 CHAR(1), C3 INT PRIMARY KEY) ENGINE = 'INNODB' ;
+INSERT INTO t5 VALUES ('A','B',1), ('X','Y',2), ('X','X',3);
+INSERT INTO t5 VALUES ('A','C',4), ('X','Z',5), ('A','A',6);
+UPDATE t5,t2,t3 SET t5.C2='Q', t2.c12='R', t3.C3 ='S' WHERE t5.C1 = t2.c12 AND t5.C1 = t3.C1;
+SELECT * FROM t5,t2,t3 WHERE t5.C2='Q' AND t2.c12='R' AND t3.C3 ='S' ORDER BY t5.C3,t2.c1,t3.pk1,t3.pk2;
+C1 C2 C3 c1 c12 c2 C1 C2 pk1 C3 pk2
+X Q 2 1 R 1 X Y 2 S 1
+X Q 2 1 R 1 X Z 2 S 2
+X Q 2 2 R 4 X Y 2 S 1
+X Q 2 2 R 4 X Z 2 S 2
+X Q 2 3 R 9 X Y 2 S 1
+X Q 2 3 R 9 X Z 2 S 2
+X Q 2 5 R 25 X Y 2 S 1
+X Q 2 5 R 25 X Z 2 S 2
+X Q 2 6 R 36 X Y 2 S 1
+X Q 2 6 R 36 X Z 2 S 2
+X Q 2 7 R 49 X Y 2 S 1
+X Q 2 7 R 49 X Z 2 S 2
+X Q 2 9 R 81 X Y 2 S 1
+X Q 2 9 R 81 X Z 2 S 2
+X Q 3 1 R 1 X Y 2 S 1
+X Q 3 1 R 1 X Z 2 S 2
+X Q 3 2 R 4 X Y 2 S 1
+X Q 3 2 R 4 X Z 2 S 2
+X Q 3 3 R 9 X Y 2 S 1
+X Q 3 3 R 9 X Z 2 S 2
+X Q 3 5 R 25 X Y 2 S 1
+X Q 3 5 R 25 X Z 2 S 2
+X Q 3 6 R 36 X Y 2 S 1
+X Q 3 6 R 36 X Z 2 S 2
+X Q 3 7 R 49 X Y 2 S 1
+X Q 3 7 R 49 X Z 2 S 2
+X Q 3 9 R 81 X Y 2 S 1
+X Q 3 9 R 81 X Z 2 S 2
+X Q 5 1 R 1 X Y 2 S 1
+X Q 5 1 R 1 X Z 2 S 2
+X Q 5 2 R 4 X Y 2 S 1
+X Q 5 2 R 4 X Z 2 S 2
+X Q 5 3 R 9 X Y 2 S 1
+X Q 5 3 R 9 X Z 2 S 2
+X Q 5 5 R 25 X Y 2 S 1
+X Q 5 5 R 25 X Z 2 S 2
+X Q 5 6 R 36 X Y 2 S 1
+X Q 5 6 R 36 X Z 2 S 2
+X Q 5 7 R 49 X Y 2 S 1
+X Q 5 7 R 49 X Z 2 S 2
+X Q 5 9 R 81 X Y 2 S 1
+X Q 5 9 R 81 X Z 2 S 2
+SELECT * FROM t5,t2,t3 WHERE t5.C2='Q' AND t2.c12='R' AND t3.C3 ='S' ORDER BY t5.C3,t2.c1,t3.pk1,t3.pk2;
+C1 C2 C3 c1 c12 c2 C1 C2 pk1 C3 pk2
+X Q 2 1 R 1 X Y 2 S 1
+X Q 2 1 R 1 X Z 2 S 2
+X Q 2 2 R 4 X Y 2 S 1
+X Q 2 2 R 4 X Z 2 S 2
+X Q 2 3 R 9 X Y 2 S 1
+X Q 2 3 R 9 X Z 2 S 2
+X Q 2 5 R 25 X Y 2 S 1
+X Q 2 5 R 25 X Z 2 S 2
+X Q 2 6 R 36 X Y 2 S 1
+X Q 2 6 R 36 X Z 2 S 2
+X Q 2 7 R 49 X Y 2 S 1
+X Q 2 7 R 49 X Z 2 S 2
+X Q 2 9 R 81 X Y 2 S 1
+X Q 2 9 R 81 X Z 2 S 2
+X Q 3 1 R 1 X Y 2 S 1
+X Q 3 1 R 1 X Z 2 S 2
+X Q 3 2 R 4 X Y 2 S 1
+X Q 3 2 R 4 X Z 2 S 2
+X Q 3 3 R 9 X Y 2 S 1
+X Q 3 3 R 9 X Z 2 S 2
+X Q 3 5 R 25 X Y 2 S 1
+X Q 3 5 R 25 X Z 2 S 2
+X Q 3 6 R 36 X Y 2 S 1
+X Q 3 6 R 36 X Z 2 S 2
+X Q 3 7 R 49 X Y 2 S 1
+X Q 3 7 R 49 X Z 2 S 2
+X Q 3 9 R 81 X Y 2 S 1
+X Q 3 9 R 81 X Z 2 S 2
+X Q 5 1 R 1 X Y 2 S 1
+X Q 5 1 R 1 X Z 2 S 2
+X Q 5 2 R 4 X Y 2 S 1
+X Q 5 2 R 4 X Z 2 S 2
+X Q 5 3 R 9 X Y 2 S 1
+X Q 5 3 R 9 X Z 2 S 2
+X Q 5 5 R 25 X Y 2 S 1
+X Q 5 5 R 25 X Z 2 S 2
+X Q 5 6 R 36 X Y 2 S 1
+X Q 5 6 R 36 X Z 2 S 2
+X Q 5 7 R 49 X Y 2 S 1
+X Q 5 7 R 49 X Z 2 S 2
+X Q 5 9 R 81 X Y 2 S 1
+X Q 5 9 R 81 X Z 2 S 2
+CREATE TABLE t4 (C1 CHAR(1) PRIMARY KEY, B1 BIT(1), B2 BIT(1) NOT NULL DEFAULT 0, C2 CHAR(1) NOT NULL DEFAULT 'A') ENGINE = 'INNODB' ;
+INSERT INTO t4 SET C1 = 1;
+SELECT C1,HEX(B1),HEX(B2) FROM t4 ORDER BY C1;
+C1 HEX(B1) HEX(B2)
+1 NULL 0
+SELECT C1,HEX(B1),HEX(B2) FROM t4 ORDER BY C1;
+C1 HEX(B1) HEX(B2)
+1 NULL 0
+CREATE TABLE t7 (C1 INT PRIMARY KEY, C2 INT) ENGINE = 'INNODB' ;
+
+--- on slave: original values ---
+INSERT INTO t7 VALUES (1,3), (2,6), (3,9);
+SELECT * FROM t7 ORDER BY C1;
+C1 C2
+1 3
+2 6
+3 9
+
+--- on master: new values inserted ---
+INSERT INTO t7 VALUES (1,2), (2,4), (3,6);
+SELECT * FROM t7 ORDER BY C1;
+C1 C2
+1 2
+2 4
+3 6
+
+--- on slave: old values should be overwritten by replicated values ---
+SELECT * FROM t7 ORDER BY C1;
+C1 C2
+1 2
+2 4
+3 6
+
+--- on master ---
+DROP TABLE t7;
+CREATE TABLE t7 (a INT PRIMARY KEY, b INT UNIQUE, c INT UNIQUE) ENGINE = 'INNODB' ;
+INSERT INTO t7 VALUES (99,99,99);
+INSERT INTO t7 VALUES (99,22,33);
+ERROR 23000: Duplicate entry '99' for key 1
+INSERT INTO t7 VALUES (11,99,33);
+ERROR 23000: Duplicate entry '99' for key 2
+INSERT INTO t7 VALUES (11,22,99);
+ERROR 23000: Duplicate entry '99' for key 3
+SELECT * FROM t7 ORDER BY a;
+a b c
+99 99 99
+
+--- on slave ---
+SELECT * FROM t7 ORDER BY a;
+a b c
+99 99 99
+INSERT INTO t7 VALUES (1,2,3), (2,4,6), (3,6,9);
+SELECT * FROM t7 ORDER BY a;
+a b c
+1 2 3
+2 4 6
+3 6 9
+99 99 99
+
+--- on master ---
+INSERT INTO t7 VALUES (2,4,8);
+
+--- on slave ---
+SELECT * FROM t7 ORDER BY a;
+a b c
+1 2 3
+2 4 8
+3 6 9
+99 99 99
+DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7;
diff --git a/mysql-test/r/rpl_row_charset.result b/mysql-test/r/rpl_row_charset.result
new file mode 100644
index 00000000000..3b065a06826
--- /dev/null
+++ b/mysql-test/r/rpl_row_charset.result
@@ -0,0 +1,201 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+set timestamp=1000000000;
+drop database if exists mysqltest2;
+drop database if exists mysqltest3;
+create database mysqltest2 character set latin2;
+set @@character_set_server=latin5;
+create database mysqltest3;
+
+--- --master--
+show create database mysqltest2;
+Database Create Database
+mysqltest2 CREATE DATABASE `mysqltest2` /*!40100 DEFAULT CHARACTER SET latin2 */
+show create database mysqltest3;
+Database Create Database
+mysqltest3 CREATE DATABASE `mysqltest3` /*!40100 DEFAULT CHARACTER SET latin5 */
+
+--- --slave--
+show create database mysqltest2;
+Database Create Database
+mysqltest2 CREATE DATABASE `mysqltest2` /*!40100 DEFAULT CHARACTER SET latin2 */
+show create database mysqltest3;
+Database Create Database
+mysqltest3 CREATE DATABASE `mysqltest3` /*!40100 DEFAULT CHARACTER SET latin5 */
+set @@collation_server=armscii8_bin;
+drop database mysqltest3;
+create database mysqltest3;
+
+--- --master--
+show create database mysqltest3;
+Database Create Database
+mysqltest3 CREATE DATABASE `mysqltest3` /*!40100 DEFAULT CHARACTER SET armscii8 COLLATE armscii8_bin */
+
+--- --slave--
+show create database mysqltest3;
+Database Create Database
+mysqltest3 CREATE DATABASE `mysqltest3` /*!40100 DEFAULT CHARACTER SET armscii8 COLLATE armscii8_bin */
+use mysqltest2;
+create table t1 (a int auto_increment primary key, b varchar(100));
+set character_set_client=cp850, collation_connection=latin2_croatian_ci;
+insert into t1 (b) values(@@character_set_server);
+insert into t1 (b) values(@@collation_server);
+insert into t1 (b) values(@@character_set_client);
+insert into t1 (b) values(@@character_set_connection);
+insert into t1 (b) values(@@collation_connection);
+
+--- --master--
+select * from t1 order by a;
+a b
+1 armscii8
+2 armscii8_bin
+3 cp850
+4 latin2
+5 latin2_croatian_ci
+
+--- --slave--
+select * from mysqltest2.t1 order by a;
+a b
+1 armscii8
+2 armscii8_bin
+3 cp850
+4 latin2
+5 latin2_croatian_ci
+select "--- --muller--" as "";
+
+--- --muller--
+set character_set_client=latin1, collation_connection=latin1_german1_ci;
+truncate table t1;
+insert into t1 (b) values(@@collation_connection);
+insert into t1 (b) values(LEAST("Müller","Muffler"));
+set collation_connection=latin1_german2_ci;
+insert into t1 (b) values(@@collation_connection);
+insert into t1 (b) values(LEAST("Müller","Muffler"));
+
+--- --master--
+select * from t1 order by a;
+a b
+1 latin1_german1_ci
+2 Muffler
+3 latin1_german2_ci
+4 Müller
+
+--- --slave--
+select * from mysqltest2.t1 order by a;
+a b
+1 latin1_german1_ci
+2 Muffler
+3 latin1_german2_ci
+4 Müller
+select "--- --INSERT--" as "";
+
+--- --INSERT--
+set @a= _cp850 'Müller' collate cp850_general_ci;
+truncate table t1;
+insert into t1 (b) values(collation(@a));
+
+--- --master--
+select * from t1 order by a;
+a b
+1 cp850_general_ci
+
+--- --slave--
+select * from mysqltest2.t1 order by a;
+a b
+1 cp850_general_ci
+drop database mysqltest2;
+drop database mysqltest3;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # drop database if exists mysqltest2
+master-bin.000001 # Query 1 # drop database if exists mysqltest3
+master-bin.000001 # Query 1 # create database mysqltest2 character set latin2
+master-bin.000001 # Query 1 # create database mysqltest3
+master-bin.000001 # Query 1 # drop database mysqltest3
+master-bin.000001 # Query 1 # create database mysqltest3
+master-bin.000001 # Query 1 # use `mysqltest2`; create table t1 (a int auto_increment primary key, b varchar(100))
+master-bin.000001 # Table_map 1 # mysqltest2.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest2.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest2.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest2.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest2.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `mysqltest2`; truncate table t1
+master-bin.000001 # Table_map 1 # mysqltest2.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest2.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest2.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest2.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `mysqltest2`; truncate table t1
+master-bin.000001 # Table_map 1 # mysqltest2.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # drop database mysqltest2
+master-bin.000001 # Query 1 # drop database mysqltest3
+select "--- --global--" as "";
+
+--- --global--
+set global character_set_server=latin2;
+set global character_set_server=latin1;
+set global character_set_server=latin2;
+set global character_set_server=latin1;
+select "--- --oneshot--" as "";
+
+--- --oneshot--
+set one_shot @@character_set_server=latin5;
+set @@max_join_size=1000;
+select @@character_set_server;
+@@character_set_server
+latin5
+select @@character_set_server;
+@@character_set_server
+latin1
+set @@character_set_server=latin5;
+select @@character_set_server;
+@@character_set_server
+latin5
+select @@character_set_server;
+@@character_set_server
+latin5
+set one_shot max_join_size=10;
+ERROR HY000: The 'SET ONE_SHOT' syntax is reserved for purposes internal to the MySQL server
+set character_set_client=9999999;
+ERROR 42000: Unknown character set: '9999999'
+set collation_server=9999998;
+ERROR HY000: Unknown collation: '9999998'
+select "--- --3943--" as "";
+
+--- --3943--
+use test;
+CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255));
+SET CHARACTER_SET_CLIENT=koi8r,
+CHARACTER_SET_CONNECTION=cp1251,
+CHARACTER_SET_RESULTS=koi8r;
+INSERT INTO t1 (c1, c2) VALUES ('îÕ, ÚÁ ÒÙÂÁÌËÕ','îÕ, ÚÁ ÒÙÂÁÌËÕ');
+select hex(c1), hex(c2) from t1;
+hex(c1) hex(c2)
+CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3
+select hex(c1), hex(c2) from t1;
+hex(c1) hex(c2)
+CDF32C20E7E020F0FBE1E0EBEAF3 CDF32C20E7E020F0FBE1E0EBEAF3
+drop table t1;
+select "--- --6676--" as "";
+
+--- --6676--
+create table `t1` (
+`pk` varchar(10) not null default '',
+primary key (`pk`)
+) engine=myisam default charset=latin1;
+set @p=_latin1 'test';
+update t1 set pk='test' where pk=@p;
+drop table t1;
diff --git a/mysql-test/r/rpl_row_create_table.result b/mysql-test/r/rpl_row_create_table.result
new file mode 100644
index 00000000000..9182a1d6d89
--- /dev/null
+++ b/mysql-test/r/rpl_row_create_table.result
@@ -0,0 +1,213 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT, b INT) ENGINE=Merge;
+CREATE TABLE t3 (a INT, b INT) CHARSET=utf8;
+CREATE TABLE t4 (a INT, b INT) ENGINE=Merge CHARSET=utf8;
+SHOW BINLOG EVENTS FROM 212;
+Log_name #
+Pos 212
+Event_type Query
+Server_id #
+End_log_pos #
+Info use `test`; CREATE TABLE t1 (a INT, b INT)
+Log_name #
+Pos 305
+Event_type Query
+Server_id #
+End_log_pos #
+Info use `test`; CREATE TABLE t2 (a INT, b INT) ENGINE=Merge
+Log_name #
+Pos 411
+Event_type Query
+Server_id #
+End_log_pos #
+Info use `test`; CREATE TABLE t3 (a INT, b INT) CHARSET=utf8
+Log_name #
+Pos 517
+Event_type Query
+Server_id #
+End_log_pos #
+Info use `test`; CREATE TABLE t4 (a INT, b INT) ENGINE=Merge CHARSET=utf8
+**** On Master ****
+SHOW CREATE TABLE t1;
+Table t1
+Create Table CREATE TABLE `t1` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SHOW CREATE TABLE t2;
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=()
+SHOW CREATE TABLE t3;
+Table t3
+Create Table CREATE TABLE `t3` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=utf8
+**** On Slave ****
+SHOW CREATE TABLE t1;
+Table t1
+Create Table CREATE TABLE `t1` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
+SHOW CREATE TABLE t2;
+Table t2
+Create Table CREATE TABLE `t2` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=()
+SHOW CREATE TABLE t3;
+Table t3
+Create Table CREATE TABLE `t3` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MEMORY DEFAULT CHARSET=utf8
+CREATE TABLE t5 (b INT, c INT) SELECT * FROM t3;
+CREATE TEMPORARY TABLE tt3 (a INT, b INT);
+INSERT INTO tt3 VALUES (1,2), (2,4), (3,6), (4,2), (5,10), (6,12);
+CREATE TABLE t6 (b INT, c INT) SELECT * FROM tt3;
+**** On Master ****
+SHOW CREATE TABLE t5;
+Table t5
+Create Table CREATE TABLE `t5` (
+ `c` int(11) default NULL,
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t5 ORDER BY a,b,c;
+c a b
+SHOW CREATE TABLE t6;
+Table t6
+Create Table CREATE TABLE `t6` (
+ `c` int(11) default NULL,
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t6 ORDER BY a,b,c;
+c a b
+NULL 1 2
+NULL 2 4
+NULL 3 6
+NULL 4 2
+NULL 5 10
+NULL 6 12
+**** On Slave ****
+SHOW CREATE TABLE t5;
+Table t5
+Create Table CREATE TABLE `t5` (
+ `c` int(11) default NULL,
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
+SELECT * FROM t5 ORDER BY a,b,c;
+c a b
+SHOW CREATE TABLE t6;
+Table t6
+Create Table CREATE TABLE `t6` (
+ `c` int(11) default NULL,
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
+SELECT * FROM t6 ORDER BY a,b,c;
+c a b
+NULL 1 2
+NULL 2 4
+NULL 3 6
+NULL 4 2
+NULL 5 10
+NULL 6 12
+CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3;
+ERROR 23000: Duplicate entry '2' for key 1
+SHOW BINLOG EVENTS FROM 1256;
+Log_name Pos Event_type Server_id End_log_pos Info
+CREATE TABLE t7 (a INT, b INT UNIQUE);
+INSERT INTO t7 SELECT a,b FROM tt3;
+ERROR 23000: Duplicate entry '2' for key 1
+SELECT * FROM t7 ORDER BY a,b;
+a b
+1 2
+2 4
+3 6
+SHOW BINLOG EVENTS FROM 1256;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 1256 Query 1 1356 use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE)
+master-bin.000001 1356 Table_map 1 1396 test.t7
+master-bin.000001 1396 Write_rows 1 1452
+SELECT * FROM t7 ORDER BY a,b;
+a b
+1 2
+2 4
+3 6
+CREATE TEMPORARY TABLE tt4 (a INT, b INT);
+INSERT INTO tt4 VALUES (4,8), (5,10), (6,12);
+BEGIN;
+INSERT INTO t7 SELECT a,b FROM tt4;
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+SHOW BINLOG EVENTS FROM 1452;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 1452 Table_map 1 1492 test.t7
+master-bin.000001 1492 Write_rows 1 1548
+SELECT * FROM t7 ORDER BY a,b;
+a b
+1 2
+2 4
+3 6
+4 8
+5 10
+6 12
+SELECT * FROM t7 ORDER BY a,b;
+a b
+1 2
+2 4
+3 6
+4 8
+5 10
+6 12
+CREATE TABLE t8 LIKE t4;
+CREATE TABLE t9 LIKE tt4;
+CREATE TEMPORARY TABLE tt5 LIKE t4;
+CREATE TEMPORARY TABLE tt6 LIKE tt4;
+**** On Master ****
+SHOW CREATE TABLE t8;
+Table t8
+Create Table CREATE TABLE `t8` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8 UNION=()
+SHOW CREATE TABLE t9;
+Table t9
+Create Table CREATE TABLE `t9` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SHOW BINLOG EVENTS FROM 1548;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 1548 Query 1 1634 use `test`; CREATE TABLE t8 LIKE t4
+master-bin.000001 1634 Query 1 1773 use `test`; CREATE TABLE `t9` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+)
+**** On Slave ****
+SHOW CREATE TABLE t8;
+Table t8
+Create Table CREATE TABLE `t8` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8 UNION=()
+SHOW CREATE TABLE t9;
+Table t9
+Create Table CREATE TABLE `t9` (
+ `a` int(11) default NULL,
+ `b` int(11) default NULL
+) ENGINE=MEMORY DEFAULT CHARSET=latin1
diff --git a/mysql-test/r/rpl_row_ddl.result b/mysql-test/r/rpl_row_ddl.result
new file mode 100644
index 00000000000..c77f4e2b38f
--- /dev/null
+++ b/mysql-test/r/rpl_row_ddl.result
@@ -0,0 +1,1693 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+SET AUTOCOMMIT = 1;
+DROP DATABASE IF EXISTS mysqltest1;
+DROP DATABASE IF EXISTS mysqltest2;
+DROP DATABASE IF EXISTS mysqltest3;
+CREATE DATABASE mysqltest1;
+CREATE DATABASE mysqltest2;
+CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE="InnoDB";
+INSERT INTO mysqltest1.t1 SET f1= 0;
+CREATE TABLE mysqltest1.t2 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t3 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t4 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t5 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t6 (f1 BIGINT) ENGINE="InnoDB";
+CREATE INDEX my_idx6 ON mysqltest1.t6(f1);
+CREATE TABLE mysqltest1.t7 (f1 BIGINT) ENGINE="InnoDB";
+INSERT INTO mysqltest1.t7 SET f1= 0;
+CREATE TABLE mysqltest1.t8 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t9 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t10 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t11 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t12 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t13 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t14 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t15 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t16 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t17 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t18 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t19 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TEMPORARY TABLE mysqltest1.t23 (f1 BIGINT);
+SET AUTOCOMMIT = 0;
+use mysqltest1;
+
+-------- switch to slave --------
+SET AUTOCOMMIT = 0;
+use mysqltest1;
+
+-------- switch to master -------
+
+######## COMMIT ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 0 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+1
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+0
+
+-------- switch to master -------
+COMMIT;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+1
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+1
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+1
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+1
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+
+######## ROLLBACK ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 1 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+2
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+1
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+1
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+1
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+1
+
+TEST-INFO: MASTER: The INSERT is not committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+1
+
+TEST-INFO: SLAVE: The INSERT is not committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+
+######## SET AUTOCOMMIT=1 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 1 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+2
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+1
+
+-------- switch to master -------
+SET AUTOCOMMIT=1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+2
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+2
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+2
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+2
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SET AUTOCOMMIT=0;
+
+######## START TRANSACTION ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 2 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+3
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+2
+
+-------- switch to master -------
+START TRANSACTION;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+3
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+3
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+3
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+3
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+
+######## BEGIN ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 3 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+4
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+3
+
+-------- switch to master -------
+BEGIN;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+4
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+4
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+4
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+4
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+
+######## DROP TABLE mysqltest1.t2 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 4 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+5
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+4
+
+-------- switch to master -------
+DROP TABLE mysqltest1.t2;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+5
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+5
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+5
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+5
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW TABLES LIKE 't2';
+Tables_in_mysqltest1 (t2)
+
+-------- switch to slave --------
+SHOW TABLES LIKE 't2';
+Tables_in_mysqltest1 (t2)
+
+-------- switch to master -------
+
+######## DROP TEMPORARY TABLE mysqltest1.t23 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 5 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+6
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+5
+
+-------- switch to master -------
+DROP TEMPORARY TABLE mysqltest1.t23;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+6
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+5
+
+-------- switch to master -------
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+5
+
+TEST-INFO: MASTER: The INSERT is not committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+6
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW TABLES LIKE 't23';
+Tables_in_mysqltest1 (t23)
+
+-------- switch to slave --------
+SHOW TABLES LIKE 't23';
+Tables_in_mysqltest1 (t23)
+
+-------- switch to master -------
+
+######## RENAME TABLE mysqltest1.t3 to mysqltest1.t20 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 5 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+6
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+6
+
+-------- switch to master -------
+RENAME TABLE mysqltest1.t3 to mysqltest1.t20;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+6
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+6
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+6
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+6
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW TABLES LIKE 't20';
+Tables_in_mysqltest1 (t20)
+t20
+
+-------- switch to slave --------
+SHOW TABLES LIKE 't20';
+Tables_in_mysqltest1 (t20)
+t20
+
+-------- switch to master -------
+
+######## ALTER TABLE mysqltest1.t4 ADD column f2 BIGINT ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 6 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+7
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+6
+
+-------- switch to master -------
+ALTER TABLE mysqltest1.t4 ADD column f2 BIGINT;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+7
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+7
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+7
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+7
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+describe mysqltest1.t4;
+Field Type Null Key Default Extra
+f1 bigint(20) YES NULL
+f2 bigint(20) YES NULL
+
+-------- switch to slave --------
+describe mysqltest1.t4;
+Field Type Null Key Default Extra
+f1 bigint(20) YES NULL
+f2 bigint(20) YES NULL
+
+-------- switch to master -------
+
+######## CREATE TABLE mysqltest1.t21 (f1 BIGINT) ENGINE= "InnoDB" ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 7 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+8
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+7
+
+-------- switch to master -------
+CREATE TABLE mysqltest1.t21 (f1 BIGINT) ENGINE= "InnoDB";
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+8
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+8
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+8
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+8
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+
+######## CREATE TEMPORARY TABLE mysqltest1.t22 (f1 BIGINT) ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 8 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+9
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+8
+
+-------- switch to master -------
+CREATE TEMPORARY TABLE mysqltest1.t22 (f1 BIGINT);
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+9
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+8
+
+-------- switch to master -------
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+8
+
+TEST-INFO: MASTER: The INSERT is not committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+9
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+
+######## TRUNCATE TABLE mysqltest1.t7 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 8 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+9
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+9
+
+-------- switch to master -------
+TRUNCATE TABLE mysqltest1.t7;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+9
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+9
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+9
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+9
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SELECT * FROM mysqltest1.t7;
+f1
+
+-------- switch to slave --------
+SELECT * FROM mysqltest1.t7;
+f1
+
+-------- switch to master -------
+
+######## LOCK TABLES mysqltest1.t1 WRITE, mysqltest1.t8 READ ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 9 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+9
+
+-------- switch to master -------
+LOCK TABLES mysqltest1.t1 WRITE, mysqltest1.t8 READ;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+UNLOCK TABLES;
+
+######## UNLOCK TABLES ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 10 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+11
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+-------- switch to master -------
+UNLOCK TABLES;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+11
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+TEST-INFO: MASTER: The INSERT is not committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+TEST-INFO: SLAVE: The INSERT is not committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+LOCK TABLES mysqltest1.t1 READ;
+
+######## UNLOCK TABLES ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 10 + 1;
+ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+-------- switch to master -------
+UNLOCK TABLES;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+TEST-INFO: MASTER: The INSERT is not committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+TEST-INFO: SLAVE: The INSERT is not committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+LOCK TABLES mysqltest1.t1 WRITE, mysqltest1.t8 READ;
+
+######## UNLOCK TABLES ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 10 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+11
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+10
+
+-------- switch to master -------
+UNLOCK TABLES;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+11
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+11
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+11
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+11
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+
+######## DROP INDEX my_idx6 ON mysqltest1.t6 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 11 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+12
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+11
+
+-------- switch to master -------
+DROP INDEX my_idx6 ON mysqltest1.t6;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+12
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+12
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+12
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+12
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW INDEX FROM mysqltest1.t6;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+
+-------- switch to slave --------
+SHOW INDEX FROM mysqltest1.t6;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+
+-------- switch to master -------
+
+######## CREATE INDEX my_idx5 ON mysqltest1.t5(f1) ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 12 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+13
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+12
+
+-------- switch to master -------
+CREATE INDEX my_idx5 ON mysqltest1.t5(f1);
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+13
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+13
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+13
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+13
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW INDEX FROM mysqltest1.t5;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t5 1 my_idx5 1 f1 A 0 NULL NULL YES BTREE
+
+-------- switch to slave --------
+SHOW INDEX FROM mysqltest1.t5;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t5 1 my_idx5 1 f1 A NULL NULL NULL YES BTREE
+
+-------- switch to master -------
+
+######## DROP DATABASE mysqltest2 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 13 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+14
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+13
+
+-------- switch to master -------
+DROP DATABASE mysqltest2;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+14
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+14
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+14
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+14
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW DATABASES LIKE "mysqltest2";
+Database (mysqltest2)
+
+-------- switch to slave --------
+SHOW DATABASES LIKE "mysqltest2";
+Database (mysqltest2)
+
+-------- switch to master -------
+
+######## CREATE DATABASE mysqltest3 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 14 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+15
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+14
+
+-------- switch to master -------
+CREATE DATABASE mysqltest3;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+15
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+15
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+15
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+15
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW DATABASES LIKE "mysqltest3";
+Database (mysqltest3)
+mysqltest3
+
+-------- switch to slave --------
+SHOW DATABASES LIKE "mysqltest3";
+Database (mysqltest3)
+mysqltest3
+
+-------- switch to master -------
+
+######## CREATE PROCEDURE p1() READS SQL DATA SELECT "this is p1" ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 15 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+16
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+15
+
+-------- switch to master -------
+CREATE PROCEDURE p1() READS SQL DATA SELECT "this is p1";
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+16
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+16
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+16
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+16
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW PROCEDURE STATUS LIKE 'p1';
+Db mysqltest1
+Name p1
+Type PROCEDURE
+Definer root@localhost
+Modified #
+Created #
+Security_type DEFINER
+Comment
+ -------- switch to slave -------
+SHOW PROCEDURE STATUS LIKE 'p1';
+Db mysqltest1
+Name p1
+Type PROCEDURE
+Definer root@localhost
+Modified #
+Created #
+Security_type DEFINER
+Comment
+
+######## ALTER PROCEDURE p1 COMMENT "I have been altered" ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 16 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+17
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+16
+
+-------- switch to master -------
+ALTER PROCEDURE p1 COMMENT "I have been altered";
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+17
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+17
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+17
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+17
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW PROCEDURE STATUS LIKE 'p1';
+Db mysqltest1
+Name p1
+Type PROCEDURE
+Definer root@localhost
+Modified #
+Created #
+Security_type DEFINER
+Comment I have been altered
+ -------- switch to slave -------
+SHOW PROCEDURE STATUS LIKE 'p1';
+Db mysqltest1
+Name p1
+Type PROCEDURE
+Definer root@localhost
+Modified #
+Created #
+Security_type DEFINER
+Comment I have been altered
+
+######## DROP PROCEDURE p1 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 17 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+18
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+17
+
+-------- switch to master -------
+DROP PROCEDURE p1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+18
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+18
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+18
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+18
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW PROCEDURE STATUS LIKE 'p1';
+ -------- switch to slave -------
+SHOW PROCEDURE STATUS LIKE 'p1';
+
+######## CREATE OR REPLACE VIEW v1 as select * from t1 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 18 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+19
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+18
+
+-------- switch to master -------
+CREATE OR REPLACE VIEW v1 as select * from t1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+19
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+19
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+19
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+19
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW CREATE VIEW v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`
+
+-------- switch to slave -------
+SHOW CREATE VIEW v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`
+
+######## ALTER VIEW v1 AS select f1 from t1 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 19 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+20
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+19
+
+-------- switch to master -------
+ALTER VIEW v1 AS select f1 from t1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+20
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+20
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+20
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+20
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW CREATE VIEW v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`
+
+-------- switch to slave -------
+SHOW CREATE VIEW v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`
+
+######## DROP VIEW IF EXISTS v1 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 20 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+21
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+20
+
+-------- switch to master -------
+DROP VIEW IF EXISTS v1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+21
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+21
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+21
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+21
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW CREATE VIEW v1;
+ERROR 42S02: Table 'mysqltest1.v1' doesn't exist
+
+-------- switch to slave -------
+SHOW CREATE VIEW v1;
+ERROR 42S02: Table 'mysqltest1.v1' doesn't exist
+
+######## CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 21 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+22
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+21
+
+-------- switch to master -------
+CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW SET @a:=1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+22
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+22
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+22
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+22
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW TRIGGERS;
+Trigger Event Table Statement Timing Created sql_mode Definer
+trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost
+
+-------- switch to slave -------
+SHOW TRIGGERS;
+Trigger Event Table Statement Timing Created sql_mode Definer
+trg1 INSERT t1 SET @a:=1 BEFORE NULL root@localhost
+
+######## DROP TRIGGER trg1 ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 22 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+23
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+22
+
+-------- switch to master -------
+DROP TRIGGER trg1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+23
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+23
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+23
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+23
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SHOW TRIGGERS;
+Trigger Event Table Statement Timing Created sql_mode Definer
+
+-------- switch to slave -------
+SHOW TRIGGERS;
+Trigger Event Table Statement Timing Created sql_mode Definer
+
+######## CREATE USER user1@localhost ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 23 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+24
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+23
+
+-------- switch to master -------
+CREATE USER user1@localhost;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+24
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+24
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+24
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+24
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SELECT user FROM mysql.user WHERE user = 'user1';
+user
+user1
+
+-------- switch to slave -------
+SELECT user FROM mysql.user WHERE user = 'user1';
+user
+user1
+
+######## RENAME USER user1@localhost TO rename1@localhost ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 24 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+25
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+24
+
+-------- switch to master -------
+RENAME USER user1@localhost TO rename1@localhost;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+25
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+25
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+25
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+25
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SELECT user FROM mysql.user WHERE user = 'rename1';
+user
+rename1
+
+-------- switch to slave -------
+SELECT user FROM mysql.user WHERE user = 'rename1';
+user
+rename1
+
+######## DROP USER rename1@localhost ########
+
+-------- switch to master -------
+INSERT INTO t1 SET f1= 25 + 1;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+26
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+25
+
+-------- switch to master -------
+DROP USER rename1@localhost;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+26
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+26
+
+-------- switch to master -------
+ROLLBACK;
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+26
+
+TEST-INFO: MASTER: The INSERT is committed (Succeeded)
+
+-------- switch to slave --------
+SELECT MAX(f1) FROM t1;
+MAX(f1)
+26
+
+TEST-INFO: SLAVE: The INSERT is committed (Succeeded)
+
+-------- switch to master -------
+flush logs;
+
+-------- switch to slave --------
+flush logs;
+
+-------- switch to master -------
+SELECT user FROM mysql.user WHERE user = 'rename1';
+user
+
+-------- switch to slave -------
+SELECT user FROM mysql.user WHERE user = 'rename1';
+user
+DROP DATABASE IF EXISTS mysqltest1;
+DROP DATABASE IF EXISTS mysqltest2;
+DROP DATABASE IF EXISTS mysqltest3;
diff --git a/mysql-test/r/rpl_row_delayed_ins.result b/mysql-test/r/rpl_row_delayed_ins.result
new file mode 100644
index 00000000000..7ed817b5780
--- /dev/null
+++ b/mysql-test/r/rpl_row_delayed_ins.result
@@ -0,0 +1,27 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1(a int not null primary key) engine=myisam;
+insert delayed into t1 values (1),(2),(3);
+flush tables;
+select * from t1;
+a
+1
+2
+3
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 4 Format_desc 1 102 Server ver: VERSION, Binlog ver: 4
+master-bin.000001 102 Query 1 222 use `test`; create table t1(a int not null primary key) engine=myisam
+master-bin.000001 222 Table_map 1 261 test.t1
+master-bin.000001 261 Write_rows 1 305
+master-bin.000001 305 Query 1 380 use `test`; flush tables
+select * from t1;
+a
+1
+2
+3
+drop table t1;
diff --git a/mysql-test/r/rpl_row_drop.result b/mysql-test/r/rpl_row_drop.result
new file mode 100644
index 00000000000..4ef21884fda
--- /dev/null
+++ b/mysql-test/r/rpl_row_drop.result
@@ -0,0 +1,56 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+**** On Master ****
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TEMPORARY TABLE t2 (a int, b int);
+SHOW TABLES;
+Tables_in_test
+t1
+t2
+**** On Slave ****
+SHOW TABLES;
+Tables_in_test
+t1
+t2
+**** On Master ****
+DROP TABLE t2;
+SHOW TABLES;
+Tables_in_test
+t1
+t2
+**** On Slave ****
+SHOW TABLES;
+Tables_in_test
+t1
+t2
+**** On Master ****
+CREATE TEMPORARY TABLE t2 (a int, b int);
+SHOW TABLES;
+Tables_in_test
+t1
+t2
+**** On Slave ****
+SHOW TABLES;
+Tables_in_test
+t1
+t2
+**** On Master ****
+DROP TABLE t1,t2;
+SHOW BINLOG EVENTS;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 4 Format_desc 1 102 Server ver: VERSION, Binlog ver: 4
+master-bin.000001 102 Query 1 188 use `test`; CREATE TABLE t1 (a int)
+master-bin.000001 188 Query 1 274 use `test`; CREATE TABLE t2 (a int)
+master-bin.000001 274 Query 1 378 use `test`; DROP TABLE `t1` /* generated by server */
+SHOW TABLES;
+Tables_in_test
+t2
+**** On Slave ****
+SHOW TABLES;
+Tables_in_test
+t2
diff --git a/mysql-test/r/rpl_row_err_ignoredtable.result b/mysql-test/r/rpl_row_err_ignoredtable.result
new file mode 100644
index 00000000000..b696baa57db
--- /dev/null
+++ b/mysql-test/r/rpl_row_err_ignoredtable.result
@@ -0,0 +1,44 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1 (a int primary key);
+insert into t1 values (1),(1);
+ERROR 23000: Duplicate entry '1' for key 1
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 269 # # master-bin.000001 Yes Yes 0 0 269 # None 0 No #
+show tables like 't1';
+Tables_in_test (t1)
+t1
+drop table t1;
+select get_lock('crash_lock%20C', 10);
+get_lock('crash_lock%20C', 10)
+1
+create table t2 (a int primary key);
+insert into t2 values(1);
+create table t3 (id int);
+insert into t3 values(connection_id());
+ update t2 set a = a + 1 + get_lock('crash_lock%20C', 10);
+select (@id := id) - id from t3;
+(@id := id) - id
+0
+kill @id;
+drop table t2,t3;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # #
+master-bin.000001 # Table_map 1 # #
+master-bin.000001 # Write_rows 1 # #
+master-bin.000001 # Query 1 # #
+master-bin.000001 # Query 1 # #
+master-bin.000001 # Table_map 1 # #
+master-bin.000001 # Write_rows 1 # #
+master-bin.000001 # Query 1 # #
+master-bin.000001 # Table_map 1 # #
+master-bin.000001 # Write_rows 1 # #
+master-bin.000001 # Table_map 1 # #
+master-bin.000001 # Update_rows 1 # #
+master-bin.000001 # Query 1 # #
diff --git a/mysql-test/r/rpl_row_flsh_tbls.result b/mysql-test/r/rpl_row_flsh_tbls.result
new file mode 100644
index 00000000000..503fcc7a368
--- /dev/null
+++ b/mysql-test/r/rpl_row_flsh_tbls.result
@@ -0,0 +1,32 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1 (a int);
+insert into t1 values (10);
+create table t2 (a int);
+create table t3 (a int) engine=merge union(t1);
+create table t4 (a int);
+insert into t4 select * from t3;
+rename table t1 to t5, t2 to t1;
+flush no_write_to_binlog tables;
+SHOW BINLOG EVENTS FROM 615 ;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; rename table t1 to t5, t2 to t1
+select * from t3;
+a
+flush tables;
+SHOW BINLOG EVENTS FROM 615 ;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; rename table t1 to t5, t2 to t1
+master-bin.000001 # Query 1 # use `test`; flush tables
+select * from t3;
+a
+stop slave;
+drop table t1;
+flush tables with read lock;
+start slave;
+stop slave;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
diff --git a/mysql-test/r/rpl_row_func001.result b/mysql-test/r/rpl_row_func001.result
new file mode 100644
index 00000000000..b20f3f724d0
--- /dev/null
+++ b/mysql-test/r/rpl_row_func001.result
@@ -0,0 +1,30 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP FUNCTION test.f1;
+DROP TABLE IF EXISTS test.t1;
+create table test.t1 (a int, PRIMARY KEY(a));
+create function test.f1(i int) returns int
+begin
+insert into test.t1 values(i);
+return 0;
+end//
+select test.f1(1);
+test.f1(1)
+0
+select test.f1(2);
+test.f1(2)
+0
+select * from test.t1;
+a
+1
+2
+select * from test.t1;
+a
+1
+2
+DROP FUNCTION test.f1;
+DROP TABLE test.t1;
diff --git a/mysql-test/r/rpl_row_func002.result b/mysql-test/r/rpl_row_func002.result
new file mode 100644
index 00000000000..e65c0a35180
--- /dev/null
+++ b/mysql-test/r/rpl_row_func002.result
@@ -0,0 +1,25 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP FUNCTION test.f1;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+CREATE TABLE test.t1 (a INT NOT NULL AUTO_INCREMENT, t TIMESTAMP, t2 TIMESTAMP, PRIMARY KEY(a));
+CREATE TABLE test.t2 (a INT NOT NULL AUTO_INCREMENT, t TIMESTAMP, t2 TIMESTAMP, PRIMARY KEY(a));
+create function test.f1() RETURNS TIMESTAMP
+BEGIN
+UPDATE test.t1 SET t = CURRENT_TIMESTAMP;
+RETURN CURRENT_TIMESTAMP;
+END//
+INSERT INTO test.t2 VALUES (null,f1(),CURRENT_TIMESTAMP);
+SET TIMESTAMP=2;
+INSERT INTO test.t2 VALUES (null,f1(),CURRENT_TIMESTAMP);
+SET TIMESTAMP=1;
+INSERT INTO test.t2 VALUES (null,f1(),CURRENT_TIMESTAMP);
+SET TIMESTAMP=333300000;
+INSERT INTO test.t2 VALUES (null,f1(),CURRENT_TIMESTAMP);
+DROP FUNCTION test.f1;
+DROP TABLE test.t1;
diff --git a/mysql-test/r/rpl_row_func003.result b/mysql-test/r/rpl_row_func003.result
new file mode 100644
index 00000000000..a5fd46a2ce3
--- /dev/null
+++ b/mysql-test/r/rpl_row_func003.result
@@ -0,0 +1,29 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP FUNCTION IF EXISTS test.f1;
+DROP TABLE IF EXISTS test.t1;
+CREATE TABLE test.t1 (a INT NOT NULL AUTO_INCREMENT, c CHAR(16),PRIMARY KEY(a))ENGINE=INNODB;
+create function test.f1() RETURNS CHAR(16)
+BEGIN
+DECLARE tmp CHAR(16);
+DECLARE var_name FLOAT;
+SET var_name = RAND();
+IF var_name > .6
+THEN SET tmp = 'Texas';
+ELSE SET tmp = 'MySQL';
+END IF;
+RETURN tmp;
+END|
+INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1());
+INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1());
+SET AUTOCOMMIT=0;
+START TRANSACTION;
+INSERT INTO test.t1 VALUES (null,test.f1());
+ROLLBACK;
+SET AUTOCOMMIT=1;
+DROP FUNCTION test.f1;
+DROP TABLE test.t1;
diff --git a/mysql-test/r/rpl_row_inexist_tbl.result b/mysql-test/r/rpl_row_inexist_tbl.result
new file mode 100644
index 00000000000..1d18819fdd6
--- /dev/null
+++ b/mysql-test/r/rpl_row_inexist_tbl.result
@@ -0,0 +1,45 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1 (a int not null primary key);
+drop table t1;
+insert into t1 values (1);
+insert into t1 values (2);
+show slave status;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos #
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running Yes
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 1146
+Last_Error Error 'Table 'test.t1' doesn't exist' on opening table `test`.`t1`
+Skip_Counter 0
+Exec_Master_Log_Pos 209
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
+drop table t1;
diff --git a/mysql-test/r/rpl_row_loaddata_m.result b/mysql-test/r/rpl_row_loaddata_m.result
new file mode 100644
index 00000000000..198e55c71d0
--- /dev/null
+++ b/mysql-test/r/rpl_row_loaddata_m.result
@@ -0,0 +1,20 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop database if exists mysqltest;
+stop slave;
+create database mysqltest;
+use mysqltest;
+create table t1(a int, b int, unique(b));
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # #
+master-bin.000001 # Query 1 # #
+master-bin.000001 # Query 1 # #
+master-bin.000001 # Table_map 1 # #
+master-bin.000001 # Write_rows 1 # #
+drop database mysqltest;
diff --git a/mysql-test/r/rpl_row_log.result b/mysql-test/r/rpl_row_log.result
new file mode 100644
index 00000000000..8784d9d16e2
--- /dev/null
+++ b/mysql-test/r/rpl_row_log.result
@@ -0,0 +1,105 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+stop slave;
+reset master;
+reset slave;
+reset master;
+create table t1(n int not null auto_increment primary key);
+insert into t1 values (NULL);
+drop table t1;
+create table t1 (word char(20) not null);
+load data infile '../../std_data/words.dat' into table t1 ignore 1 lines;
+select count(*) from t1;
+count(*)
+69
+drop table t1;
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
+master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `test`; drop table t1
+master-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `test`; drop table t1
+show binlog events from 102 limit 1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)
+show binlog events from 102 limit 2;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)
+master-bin.000001 # Table_map 1 # test.t1
+show binlog events from 102 limit 2,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Write_rows 1 #
+flush logs;
+create table t5 (a int);
+drop table t5;
+start slave;
+flush logs;
+stop slave;
+create table t1 (n int);
+insert into t1 values (1);
+drop table t1;
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
+master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `test`; drop table t1
+master-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)
+master-bin.000001 # Table_map 1 # test.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `test`; drop table t1
+master-bin.000001 # Rotate 1 # master-bin.000002;pos=4
+show binlog events in 'master-bin.000002';
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000002 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
+master-bin.000002 # Query 1 # use `test`; create table t5 (a int)
+master-bin.000002 # Query 1 # use `test`; drop table t5
+master-bin.000002 # Query 1 # use `test`; create table t1 (n int)
+master-bin.000002 # Table_map 1 # test.t1
+master-bin.000002 # Write_rows 1 #
+master-bin.000002 # Query 1 # use `test`; drop table t1
+show binary logs;
+Log_name File_size
+master-bin.000001 1306
+master-bin.000002 499
+start slave;
+show binary logs;
+Log_name File_size
+slave-bin.000001 1467
+slave-bin.000002 337
+show binlog events in 'slave-bin.000001' from 4;
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4
+slave-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)
+slave-bin.000001 # Table_map 1 # test.t1
+slave-bin.000001 # Write_rows 1 #
+slave-bin.000001 # Query 1 # use `test`; drop table t1
+slave-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)
+slave-bin.000001 # Table_map 1 # test.t1
+slave-bin.000001 # Write_rows 1 #
+slave-bin.000001 # Query 1 # use `test`; drop table t1
+slave-bin.000001 # Query 1 # use `test`; create table t5 (a int)
+slave-bin.000001 # Query 1 # use `test`; drop table t5
+slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4
+show binlog events in 'slave-bin.000002' from 4;
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000002 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4
+slave-bin.000002 # Query 1 # use `test`; create table t1 (n int)
+slave-bin.000002 # Table_map 1 # test.t1
+slave-bin.000002 # Write_rows 1 #
+slave-bin.000002 # Query 1 # use `test`; drop table t1
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 499 # # master-bin.000002 Yes Yes # 0 0 499 # None 0 No #
+show binlog events in 'slave-bin.000005' from 4;
+ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log
diff --git a/mysql-test/r/rpl_max_relay_size.result b/mysql-test/r/rpl_row_max_relay_size.result
index fbe3b89828a..6146d623ec5 100644
--- a/mysql-test/r/rpl_max_relay_size.result
+++ b/mysql-test/r/rpl_row_max_relay_size.result
@@ -16,7 +16,7 @@ select @@global.max_relay_log_size;
start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 72952 # # master-bin.000001 Yes Yes 0 0 72952 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 58664 # # master-bin.000001 Yes Yes # 0 0 58664 # None 0 No #
stop slave;
reset slave;
set global max_relay_log_size=(5*4096);
@@ -26,7 +26,7 @@ select @@global.max_relay_log_size;
start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 72952 # # master-bin.000001 Yes Yes 0 0 72952 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 58664 # # master-bin.000001 Yes Yes # 0 0 58664 # None 0 No #
stop slave;
reset slave;
set global max_relay_log_size=0;
@@ -36,26 +36,26 @@ select @@global.max_relay_log_size;
start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 72952 # # master-bin.000001 Yes Yes 0 0 72952 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 58664 # # master-bin.000001 Yes Yes # 0 0 58664 # None 0 No #
stop slave;
reset slave;
flush logs;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 4 # # No No 0 0 0 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 4 # # No No # 0 0 0 # None 0 No #
reset slave;
start slave;
flush logs;
create table t1 (a int);
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73038 # # master-bin.000001 Yes Yes 0 0 73038 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 58750 # # master-bin.000001 Yes Yes # 0 0 58750 # None 0 No #
flush logs;
drop table t1;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73114 # # master-bin.000001 Yes Yes 0 0 73114 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 58826 # # master-bin.000001 Yes Yes # 0 0 58826 # None 0 No #
flush logs;
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB
-master-bin.000002 98
+master-bin.000002 102 <Binlog_Ignore_DB>
diff --git a/mysql-test/r/rpl_row_multi_query.result b/mysql-test/r/rpl_row_multi_query.result
new file mode 100644
index 00000000000..8cb1aec522b
--- /dev/null
+++ b/mysql-test/r/rpl_row_multi_query.result
@@ -0,0 +1,37 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop database if exists mysqltest;
+create database mysqltest;
+create table mysqltest.t1 ( n int);
+insert into mysqltest.t1 values(1)/
+insert into mysqltest.t1 values(2);
+insert into mysqltest.t1 values(3);
+insert into mysqltest.t1 values(4);
+insert into mysqltest.t1 values(5)/
+select * from mysqltest.t1;
+n
+1
+2
+3
+4
+5
+show binlog events from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # #
+master-bin.000001 # Query 1 # #
+master-bin.000001 # Query 1 # #
+master-bin.000001 # Table_map 1 # #
+master-bin.000001 # Write_rows 1 # #
+master-bin.000001 # Table_map 1 # #
+master-bin.000001 # Write_rows 1 # #
+master-bin.000001 # Table_map 1 # #
+master-bin.000001 # Write_rows 1 # #
+master-bin.000001 # Table_map 1 # #
+master-bin.000001 # Write_rows 1 # #
+master-bin.000001 # Table_map 1 # #
+master-bin.000001 # Write_rows 1 # #
+drop database mysqltest;
diff --git a/mysql-test/r/rpl_row_multi_update3.result b/mysql-test/r/rpl_row_multi_update3.result
new file mode 100644
index 00000000000..1b757b1400c
--- /dev/null
+++ b/mysql-test/r/rpl_row_multi_update3.result
@@ -0,0 +1,124 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+
+-------- Test for BUG#9361 --------
+CREATE TABLE t1 (
+a int unsigned not null auto_increment primary key,
+b int unsigned
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+a int unsigned not null auto_increment primary key,
+b int unsigned
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (NULL, 0);
+INSERT INTO t1 SELECT NULL, 0 FROM t1;
+INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
+SELECT * FROM t1 ORDER BY a;
+a b
+1 0
+2 0
+SELECT * FROM t2 ORDER BY a;
+a b
+1 0
+2 1
+UPDATE t2, (SELECT a FROM t1) AS t SET t2.b = t.a+5 ;
+SELECT * FROM t1 ORDER BY a;
+a b
+1 0
+2 0
+SELECT * FROM t2 ORDER BY a;
+a b
+1 6
+2 6
+SELECT * FROM t1 ORDER BY a;
+a b
+1 0
+2 0
+SELECT * FROM t2 ORDER BY a;
+a b
+1 6
+2 6
+drop table t1,t2;
+
+-------- Test 1 for BUG#9361 --------
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1 (
+a1 char(30),
+a2 int,
+a3 int,
+a4 char(30),
+a5 char(30)
+);
+CREATE TABLE t2 (
+b1 int,
+b2 char(30)
+);
+INSERT INTO t1 VALUES ('Yes', 1, NULL, 'foo', 'bar');
+INSERT INTO t2 VALUES (1, 'baz');
+UPDATE t1 a, t2
+SET a.a1 = 'No'
+WHERE a.a2 =
+(SELECT b1
+FROM t2
+WHERE b2 = 'baz')
+AND a.a3 IS NULL
+AND a.a4 = 'foo'
+AND a.a5 = 'bar';
+SELECT * FROM t1;
+a1 a2 a3 a4 a5
+No 1 NULL foo bar
+SELECT * FROM t2;
+b1 b2
+1 baz
+DROP TABLE t1, t2;
+
+-------- Test 2 for BUG#9361 --------
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+CREATE TABLE t1 (
+i INT,
+j INT,
+x INT,
+y INT,
+z INT
+);
+CREATE TABLE t2 (
+i INT,
+k INT,
+x INT,
+y INT,
+z INT
+);
+CREATE TABLE t3 (
+j INT,
+k INT,
+x INT,
+y INT,
+z INT
+);
+INSERT INTO t1 VALUES ( 1, 2,13,14,15);
+INSERT INTO t2 VALUES ( 1, 3,23,24,25);
+INSERT INTO t3 VALUES ( 2, 3, 1,34,35), ( 2, 3, 1,34,36);
+UPDATE t1 AS a
+INNER JOIN t2 AS b
+ON a.i = b.i
+INNER JOIN t3 AS c
+ON a.j = c.j AND b.k = c.k
+SET a.x = b.x,
+a.y = b.y,
+a.z = (
+SELECT sum(z)
+FROM t3
+WHERE y = 34
+)
+WHERE b.x = 23;
+SELECT * FROM t1;
+i j x y z
+1 2 23 24 71
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/r/rpl_row_mystery22.result b/mysql-test/r/rpl_row_mystery22.result
new file mode 100644
index 00000000000..bcf65e4ede3
--- /dev/null
+++ b/mysql-test/r/rpl_row_mystery22.result
@@ -0,0 +1,30 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1(n int auto_increment primary key, s char(10));
+insert into t1 values (2,'old');
+insert into t1 values(NULL,'new');
+insert into t1 values(NULL,'new');
+select * from t1 order by n;
+n s
+1 new
+2 new
+delete from t1 where n = 2;
+start slave;
+stop slave;
+create table t2(n int);
+drop table t2;
+insert into t1 values(NULL,'new');
+set sql_log_bin=0;
+insert into t1 values(NULL,'new');
+set sql_log_bin=1;
+delete from t1 where n=4;
+start slave;
+select * from t1 order by n;
+n s
+1 new
+3 new
+drop table t1;
diff --git a/mysql-test/r/rpl_row_reset_slave.result b/mysql-test/r/rpl_row_reset_slave.result
new file mode 100644
index 00000000000..57fc95708e5
--- /dev/null
+++ b/mysql-test/r/rpl_row_reset_slave.result
@@ -0,0 +1,32 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 102 # # master-bin.000001 Yes Yes # 0 0 102 # None 0 No #
+stop slave;
+change master to master_user='test';
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 test MASTER_PORT 1 master-bin.000001 102 # # master-bin.000001 No No # 0 0 102 # None 0 No #
+reset slave;
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 4 # # No No # 0 0 0 # None 0 No #
+start slave;
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 102 # # master-bin.000001 Yes Yes # 0 0 102 # None 0 No #
+stop slave;
+reset slave;
+start slave;
+create temporary table t1 (a int);
+stop slave;
+reset slave;
+start slave;
+show status like 'slave_open_temp_tables';
+Variable_name Value
+Slave_open_temp_tables 0
diff --git a/mysql-test/r/rpl_rewrite_db.result b/mysql-test/r/rpl_row_rewrt_db.result
index 6c72e982e3e..6c72e982e3e 100644
--- a/mysql-test/r/rpl_rewrite_db.result
+++ b/mysql-test/r/rpl_row_rewrt_db.result
diff --git a/mysql-test/r/rpl_row_sp000.result b/mysql-test/r/rpl_row_sp000.result
new file mode 100644
index 00000000000..a7f72193842
--- /dev/null
+++ b/mysql-test/r/rpl_row_sp000.result
@@ -0,0 +1,362 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop database if exists mysqltest1;
+create database mysqltest1;
+use mysqltest1;
+create table t1 (a varchar(100));
+use mysqltest1;
+create procedure foo()
+begin
+declare b int;
+set b = 8;
+insert into t1 values (b);
+insert into t1 values (unix_timestamp());
+end|
+select * from mysql.proc where name='foo' and db='mysqltest1';
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
+mysqltest1 foo PROCEDURE foo SQL CONTAINS_SQL NO DEFINER begin
+declare b int;
+set b = 8;
+insert into t1 values (b);
+insert into t1 values (unix_timestamp());
+end root@localhost # #
+select * from mysql.proc where name='foo' and db='mysqltest1';
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
+mysqltest1 foo PROCEDURE foo SQL CONTAINS_SQL NO DEFINER begin
+declare b int;
+set b = 8;
+insert into t1 values (b);
+insert into t1 values (unix_timestamp());
+end root@localhost # #
+set timestamp=1000000000;
+call foo();
+select * from t1;
+a
+8
+1000000000
+select * from t1;
+a
+8
+1000000000
+delete from t1;
+create procedure foo2()
+not deterministic
+select * from mysqltest1.t1;
+call foo2();
+a
+alter procedure foo2 contains sql;
+drop table t1;
+create table t1 (a int);
+create table t2 (a int);
+create procedure foo3()
+deterministic
+insert into t1 values (15);
+grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1;
+grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1;
+grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1;
+create procedure foo4()
+deterministic
+begin
+insert into t2 values(3);
+insert into t1 values (5);
+end|
+call foo4();
+Got one of the listed errors
+call foo3();
+show warnings;
+Level Code Message
+call foo4();
+Got one of the listed errors
+alter procedure foo4 sql security invoker;
+call foo4();
+show warnings;
+Level Code Message
+select * from t1;
+a
+15
+5
+select * from t2;
+a
+3
+3
+3
+select * from t1;
+a
+15
+5
+select * from t2;
+a
+3
+3
+3
+delete from t2;
+alter table t2 add unique (a);
+drop procedure foo4;
+create procedure foo4()
+deterministic
+begin
+insert into t2 values(20),(20);
+end|
+call foo4();
+ERROR 23000: Duplicate entry '20' for key 1
+show warnings;
+Level Code Message
+Error 1062 Duplicate entry '20' for key 1
+select * from t2;
+a
+20
+select * from t2;
+a
+20
+select * from mysql.proc where name="foo4" and db='mysqltest1';
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
+mysqltest1 foo4 PROCEDURE foo4 SQL CONTAINS_SQL YES DEFINER begin
+insert into t2 values(20),(20);
+end root@localhost # #
+drop procedure foo4;
+select * from mysql.proc where name="foo4" and db='mysqltest1';
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
+select * from mysql.proc where name="foo4" and db='mysqltest1';
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
+drop procedure foo;
+drop procedure foo2;
+drop procedure foo3;
+create function fn1(x int)
+returns int
+deterministic
+begin
+insert into t1 values (x);
+return x+2;
+end|
+delete t1,t2 from t1,t2;
+select fn1(20);
+fn1(20)
+22
+insert into t2 values(fn1(21));
+select * from t1;
+a
+21
+20
+select * from t2;
+a
+23
+select * from t1;
+a
+21
+20
+select * from t2;
+a
+23
+drop function fn1;
+create function fn1()
+returns int
+begin
+return unix_timestamp();
+end|
+alter function fn1 no sql;
+delete from t1;
+set timestamp=1000000000;
+insert into t1 values(fn1());
+create function fn2()
+returns int
+no sql
+begin
+return unix_timestamp();
+end|
+create function fn3()
+returns int
+not deterministic
+reads sql data
+begin
+return 0;
+end|
+select fn3();
+fn3()
+0
+select * from mysql.proc where db='mysqltest1';
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
+mysqltest1 fn1 FUNCTION fn1 SQL NO_SQL NO DEFINER int(11) begin
+return unix_timestamp();
+end root@localhost # #
+mysqltest1 fn2 FUNCTION fn2 SQL NO_SQL NO DEFINER int(11) begin
+return unix_timestamp();
+end zedjzlcsjhd@localhost # #
+mysqltest1 fn3 FUNCTION fn3 SQL READS_SQL_DATA NO DEFINER int(11) begin
+return 0;
+end root@localhost # #
+select * from t1;
+a
+1000000000
+use mysqltest1;
+select * from t1;
+a
+1000000000
+select * from mysql.proc where db='mysqltest1';
+db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
+mysqltest1 fn1 FUNCTION fn1 SQL NO_SQL NO DEFINER int(11) begin
+return unix_timestamp();
+end root@localhost # #
+mysqltest1 fn2 FUNCTION fn2 SQL NO_SQL NO DEFINER int(11) begin
+return unix_timestamp();
+end zedjzlcsjhd@localhost # #
+mysqltest1 fn3 FUNCTION fn3 SQL READS_SQL_DATA NO DEFINER int(11) begin
+return 0;
+end root@localhost # #
+delete from t2;
+alter table t2 add unique (a);
+drop function fn1;
+create function fn1()
+returns int
+begin
+insert into t2 values(20),(20);
+return 10;
+end|
+select fn1();
+ERROR 23000: Duplicate entry '20' for key 1
+select * from t2;
+a
+20
+select * from t2;
+a
+20
+create trigger trg before insert on t1 for each row set new.a= 10;
+ERROR 42000: Access denied; you need the SUPER privilege for this operation
+delete from t1;
+create trigger trg before insert on t1 for each row set new.a= 10;
+insert into t1 values (1);
+select * from t1;
+a
+10
+select * from t1;
+a
+10
+delete from t1;
+drop trigger trg;
+insert into t1 values (1);
+select * from t1;
+a
+1
+show binlog events in 'master-bin.000001' from 102;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # drop database if exists mysqltest1
+master-bin.000001 # Query 1 # create database mysqltest1
+master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a varchar(100))
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Update_rows 1 #
+master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1
+master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int)
+master-bin.000001 # Query 1 # use `mysqltest1`; create table t2 (a int)
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.user
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.db
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.tables_priv
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.tables_priv
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.procs_priv
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t2
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t2
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Update_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t2
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `mysqltest1`; delete from t2
+master-bin.000001 # Query 1 # use `mysqltest1`; alter table t2 add unique (a)
+master-bin.000001 # Table_map 1 # mysql.procs_priv
+master-bin.000001 # Delete_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Delete_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t2
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Delete_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Delete_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Delete_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Delete_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t2
+master-bin.000001 # Delete_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t1
+master-bin.000001 # Delete_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t2
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Delete_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Update_rows 1 #
+master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
+master-bin.000001 # Table_map 1 # mysqltest1.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.procs_priv
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `mysqltest1`; delete from t2
+master-bin.000001 # Query 1 # use `mysqltest1`; alter table t2 add unique (a)
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Delete_rows 1 #
+master-bin.000001 # Table_map 1 # mysql.proc
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Table_map 1 # mysqltest1.t2
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
+master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` trigger trg before insert on t1 for each row set new.a= 10
+master-bin.000001 # Table_map 1 # mysqltest1.t1
+master-bin.000001 # Write_rows 1 #
+master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
+master-bin.000001 # Query 1 # use `mysqltest1`; drop trigger trg
+master-bin.000001 # Table_map 1 # mysqltest1.t1
+master-bin.000001 # Write_rows 1 #
+select * from t1;
+a
+1
+create procedure foo()
+not deterministic
+reads sql data
+select * from t1;
+call foo();
+a
+1
+drop procedure foo;
+drop function fn1;
+drop database mysqltest1;
+drop user "zedjzlcsjhd"@127.0.0.1;
diff --git a/mysql-test/r/rpl_row_sp001.result b/mysql-test/r/rpl_row_sp001.result
new file mode 100644
index 00000000000..0276fb721b9
--- /dev/null
+++ b/mysql-test/r/rpl_row_sp001.result
@@ -0,0 +1,85 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+
+<Begin test section 1 (non deterministic SP)>
+---------------------------------------------
+create table test.t1 (n MEDIUMINT NOT NULL AUTO_INCREMENT, f FLOAT, d DATETIME, PRIMARY KEY(n));
+create procedure test.p1()
+begin
+INSERT INTO test.t1 (f,d) VALUES (RAND(),NOW());
+end//
+
+<End test section 1 (non deterministic SP)>
+-------------------------------------------
+CREATE TABLE test.t2 (a INT NOT NULL AUTO_INCREMENT, t CHAR(4), PRIMARY KEY(a));
+CREATE PROCEDURE test.p2(n int)
+begin
+CASE n
+WHEN 1 THEN
+UPDATE test.t2 set t ='Tex';
+WHEN 2 THEN
+UPDATE test.t2 set t ='SQL';
+ELSE
+UPDATE test.t2 set t ='NONE';
+END CASE;
+end//
+INSERT INTO test.t2 VALUES(NULL,'NEW'),(NULL,'NEW'),(NULL,'NEW'),(NULL,'NEW');
+select * from test.t2;
+a t
+1 NEW
+2 NEW
+3 NEW
+4 NEW
+select * from test.t2;
+a t
+1 NEW
+2 NEW
+3 NEW
+4 NEW
+call test.p2(1);
+select * from test.t2;
+a t
+1 Tex
+2 Tex
+3 Tex
+4 Tex
+select * from test.t2;
+a t
+1 Tex
+2 Tex
+3 Tex
+4 Tex
+call test.p2(2);
+select * from test.t2;
+a t
+1 SQL
+2 SQL
+3 SQL
+4 SQL
+select * from test.t2;
+a t
+1 SQL
+2 SQL
+3 SQL
+4 SQL
+call test.p2(3);
+select * from test.t2;
+a t
+1 NONE
+2 NONE
+3 NONE
+4 NONE
+select * from test.t2;
+a t
+1 NONE
+2 NONE
+3 NONE
+4 NONE
+DROP PROCEDURE test.p1;
+DROP PROCEDURE test.p2;
+DROP TABLE test.t1;
+DROP TABLE test.t2;
diff --git a/mysql-test/r/rpl_row_sp002_innodb.result b/mysql-test/r/rpl_row_sp002_innodb.result
new file mode 100644
index 00000000000..a42c9af988c
--- /dev/null
+++ b/mysql-test/r/rpl_row_sp002_innodb.result
@@ -0,0 +1,239 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP TABLE IF EXISTS test.t3;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+CREATE TABLE test.t1 (a INT AUTO_INCREMENT KEY, t CHAR(6)) ENGINE=INNODB;
+CREATE TABLE test.t2 (a INT AUTO_INCREMENT KEY, f INT, FOREIGN KEY(a) REFERENCES test.t1(a) ON DELETE CASCADE) ENGINE=INNODB;
+create procedure test.p1(IN i CHAR(6))
+begin
+INSERT INTO test.t1 (t) VALUES (i);
+INSERT INTO test.t2 VALUES (NULL,LAST_INSERT_ID());
+end|
+create procedure test.p2(IN i INT)
+begin
+DELETE FROM test.t1 where a < i;
+end|
+
+< -- test 1 call p1 -- >
+------------------------
+SET FOREIGN_KEY_CHECKS=1;
+call test.p1('texas');
+call test.p1('Live');
+call test.p1('next');
+call test.p1('to');
+call test.p1('OK');
+call test.p1('MySQL');
+
+< -- test 1 select master after p1 -- >
+---------------------------------------
+SELECT * FROM test.t1;
+a t
+1 texas
+2 Live
+3 next
+4 to
+5 OK
+6 MySQL
+SELECT * FROM test.t2;
+a f
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+
+< -- test 1 select slave after p1 -- >
+--------------------------------------
+SELECT * FROM test.t1;
+a t
+1 texas
+2 Live
+3 next
+4 to
+5 OK
+6 MySQL
+SELECT * FROM test.t2;
+a f
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+
+< -- test 1 call p2 & select master -- >
+----------------------------------------
+call test.p2(4);
+SELECT * FROM test.t1;
+a t
+4 to
+5 OK
+6 MySQL
+SELECT * FROM test.t2;
+a f
+4 4
+5 5
+6 6
+
+< -- test 1 select slave after p2 -- >
+--------------------------------------
+SELECT * FROM test.t1;
+a t
+4 to
+5 OK
+6 MySQL
+SELECT * FROM test.t2;
+a f
+4 4
+5 5
+6 6
+
+< -- End test 1 Begin test 2 -- >
+---------------------------------
+SET FOREIGN_KEY_CHECKS=0;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+CREATE TABLE test.t1 (a INT, t CHAR(6), PRIMARY KEY(a)) ENGINE=INNODB;
+CREATE TABLE test.t2 (a INT, f INT, FOREIGN KEY(a) REFERENCES test.t1(a) ON UPDATE CASCADE, PRIMARY KEY(a)) ENGINE=INNODB;
+CREATE PROCEDURE test.p1(IN nm INT, IN ch CHAR(6))
+BEGIN
+INSERT INTO test.t1 (a,t) VALUES (nm, ch);
+INSERT INTO test.t2 VALUES (nm, LAST_INSERT_ID());
+END|
+CREATE PROCEDURE test.p2(IN i INT)
+BEGIN
+UPDATE test.t1 SET a = i*10 WHERE a = i;
+END|
+SET FOREIGN_KEY_CHECKS=1;
+CALL test.p1(1,'texas');
+CALL test.p1(2,'Live');
+CALL test.p1(3,'next');
+CALL test.p1(4,'to');
+CALL test.p1(5,'OK');
+CALL test.p1(6,'MySQL');
+
+< -- test 2 select Master after p1 -- >
+---------------------------------------
+SELECT * FROM test.t1;
+a t
+1 texas
+2 Live
+3 next
+4 to
+5 OK
+6 MySQL
+SELECT * FROM test.t2;
+a f
+1 6
+2 6
+3 6
+4 6
+5 6
+6 6
+
+< -- test 2 select Slave after p1 -- >
+--------------------------------------
+SELECT * FROM test.t1;
+a t
+1 texas
+2 Live
+3 next
+4 to
+5 OK
+6 MySQL
+SELECT * FROM test.t2;
+a f
+1 6
+2 6
+3 6
+4 6
+5 6
+6 6
+
+< -- test 2 call p2 & select Master -- >
+----------------------------------------
+CALL test.p2(2);
+CALL test.p2(4);
+CALL test.p2(6);
+SELECT * FROM test.t1;
+a t
+1 texas
+3 next
+5 OK
+20 Live
+40 to
+60 MySQL
+SELECT * FROM test.t2;
+a f
+1 6
+3 6
+5 6
+20 6
+40 6
+60 6
+
+< -- test 1 select Slave after p2 -- >
+--------------------------------------
+SELECT * FROM test.t1;
+a t
+1 texas
+3 next
+5 OK
+20 Live
+40 to
+60 MySQL
+SELECT * FROM test.t2;
+a f
+1 6
+3 6
+5 6
+20 6
+40 6
+60 6
+
+< -- End test 2 Begin test 3 -- >
+---------------------------------
+CREATE TABLE test.t3 (a INT AUTO_INCREMENT KEY, t CHAR(6))ENGINE=INNODB;
+CREATE PROCEDURE test.p3(IN n INT)
+begin
+CASE n
+WHEN 2 THEN
+DELETE from test.t3;
+ELSE
+INSERT INTO test.t3 VALUES (NULL,'NONE');
+END CASE;
+end|
+SET AUTOCOMMIT=0;
+START TRANSACTION;
+ROLLBACK;
+select * from test.t3;
+a t
+select * from test.t3;
+a t
+START TRANSACTION;
+COMMIT;
+select * from test.t3;
+a t
+98 NONE
+select * from test.t3;
+a t
+98 NONE
+SET AUTOCOMMIT=1;
+SET FOREIGN_KEY_CHECKS=0;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
diff --git a/mysql-test/r/rpl_row_sp003.result b/mysql-test/r/rpl_row_sp003.result
new file mode 100644
index 00000000000..01e352c3d46
--- /dev/null
+++ b/mysql-test/r/rpl_row_sp003.result
@@ -0,0 +1,49 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+CREATE TABLE test.t1(a INT,PRIMARY KEY(a))ENGINE=INNODB;
+CREATE PROCEDURE test.p1()
+BEGIN
+INSERT INTO test.t1 VALUES (4);
+SELECT get_lock("test", 100);
+UPDATE test.t1 set a=a+4 WHERE a=4;
+END|
+CREATE PROCEDURE test.p2()
+BEGIN
+UPDATE test.t1 SET a=a+1;
+END|
+SELECT get_lock("test", 200);
+get_lock("test", 200)
+1
+ CALL test.p1();
+CALL test.p2();
+SELECT release_lock("test");
+release_lock("test")
+1
+SELECT * FROM test.t1;
+a
+5
+SELECT * FROM test.t1;
+a
+5
+DROP TABLE IF EXISTS test.t1;
+CREATE TABLE test.t1(a INT,PRIMARY KEY(a))ENGINE=INNODB;
+CALL test.p2();
+CALL test.p1();
+get_lock("test", 100)
+0
+SELECT * FROM test.t1;
+a
+8
+SELECT * FROM test.t1;
+a
+8
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
diff --git a/mysql-test/r/rpl_row_sp005.result b/mysql-test/r/rpl_row_sp005.result
new file mode 100644
index 00000000000..24d68f3af3d
--- /dev/null
+++ b/mysql-test/r/rpl_row_sp005.result
@@ -0,0 +1,100 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t3;
+CREATE TABLE IF NOT EXISTS test.t1(id INT, data CHAR(16),PRIMARY KEY(id));
+CREATE TABLE IF NOT EXISTS test.t2(id2 INT,PRIMARY KEY(id2));
+CREATE TABLE IF NOT EXISTS test.t3(id3 INT,PRIMARY KEY(id3), c CHAR(16));
+CREATE PROCEDURE test.p1()
+BEGIN
+DECLARE done INT DEFAULT 0;
+DECLARE spa CHAR(16);
+DECLARE spb,spc INT;
+DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
+DECLARE cur2 CURSOR FOR SELECT id2 FROM test.t2;
+DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
+OPEN cur1;
+OPEN cur2;
+REPEAT
+FETCH cur1 INTO spb, spa;
+FETCH cur2 INTO spc;
+IF NOT done THEN
+IF spb < spc THEN
+INSERT INTO test.t3 VALUES (spb,spa);
+ELSE
+INSERT INTO test.t3 VALUES (spc,spa);
+END IF;
+END IF;
+UNTIL done END REPEAT;
+CLOSE cur1;
+CLOSE cur2;
+END|
+CREATE PROCEDURE test.p2()
+BEGIN
+INSERT INTO test.t1 VALUES (4,'MySQL'),(20,'ROCKS'),(11,'Texas'),(10,'kyle');
+INSERT INTO test.t2 VALUES (4),(2),(1),(3);
+UPDATE test.t1 SET id=id+4 WHERE id=4;
+END|
+
+< ---- Master selects-- >
+-------------------------
+CALL test.p2();
+SELECT * FROM test.t1;
+id data
+8 MySQL
+20 ROCKS
+11 Texas
+10 kyle
+SELECT * FROM test.t2;
+id2
+1
+2
+3
+4
+
+< ---- Slave selects-- >
+------------------------
+SELECT * FROM test.t1;
+id data
+8 MySQL
+20 ROCKS
+11 Texas
+10 kyle
+SELECT * FROM test.t2;
+id2
+1
+2
+3
+4
+
+< ---- Master selects-- >
+-------------------------
+CALL test.p1();
+SELECT * FROM test.t3;
+id3 c
+1 MySQL
+2 ROCKS
+3 Texas
+4 kyle
+
+< ---- Slave selects-- >
+------------------------
+SELECT * FROM test.t3;
+id3 c
+1 MySQL
+2 ROCKS
+3 Texas
+4 kyle
+ALTER PROCEDURE test.p1 MODIFIES SQL DATA;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
diff --git a/mysql-test/r/rpl_row_sp006_InnoDB.result b/mysql-test/r/rpl_row_sp006_InnoDB.result
new file mode 100644
index 00000000000..9b9b04dbbee
--- /dev/null
+++ b/mysql-test/r/rpl_row_sp006_InnoDB.result
@@ -0,0 +1,45 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create database if not exists mysqltest1;
+DROP PROCEDURE IF EXISTS mysqltest1.p1;
+DROP PROCEDURE IF EXISTS mysqltest1.p2;
+DROP TABLE IF EXISTS mysqltest1.t2;
+DROP TABLE IF EXISTS mysqltest1.t1;
+CREATE TABLE IF NOT EXISTS mysqltest1.t1(name CHAR(16), birth DATE,PRIMARY KEY(name))ENGINE=InnoDB;
+CREATE TABLE IF NOT EXISTS mysqltest1.t2(name CHAR(16), age INT ,PRIMARY KEY(name))ENGINE=InnoDB;
+CREATE PROCEDURE mysqltest1.p1()
+BEGIN
+DECLARE done INT DEFAULT 0;
+DECLARE spa CHAR(16);
+DECLARE spb INT;
+DECLARE cur1 CURSOR FOR SELECT name,
+(YEAR(CURDATE())-YEAR(birth))-(RIGHT(CURDATE(),5)<RIGHT(birth,5))
+FROM mysqltest1.t1;
+DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
+OPEN cur1;
+SET AUTOCOMMIT=0;
+REPEAT
+FETCH cur1 INTO spa, spb;
+IF NOT done THEN
+START TRANSACTION;
+INSERT INTO mysqltest1.t2 VALUES (spa,spb);
+COMMIT;
+END IF;
+UNTIL done END REPEAT;
+SET AUTOCOMMIT=1;
+CLOSE cur1;
+END|
+CREATE PROCEDURE mysqltest1.p2()
+BEGIN
+INSERT INTO mysqltest1.t1 VALUES ('MySQL','1993-02-04'),('ROCKS', '1990-08-27'),('Texas', '1999-03-30'),('kyle','2005-1-1');
+END|
+CALL mysqltest1.p2();
+CALL mysqltest1.p1();
+DROP PROCEDURE IF EXISTS mysqltest1.p1;
+DROP PROCEDURE IF EXISTS mysqltest1.p2;
+DROP TABLE IF EXISTS mysqltest1.t1;
+DROP TABLE IF EXISTS mysqltest1.t2;
diff --git a/mysql-test/r/rpl_row_sp007_innodb.result b/mysql-test/r/rpl_row_sp007_innodb.result
new file mode 100644
index 00000000000..9a2822835f8
--- /dev/null
+++ b/mysql-test/r/rpl_row_sp007_innodb.result
@@ -0,0 +1,50 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
+CREATE PROCEDURE test.p1(IN i INT)
+BEGIN
+DECLARE CONTINUE HANDLER FOR sqlexception BEGIN END;
+DROP TABLE IF EXISTS test.t1;
+CREATE TABLE test.t1 (num INT,PRIMARY KEY(num))ENGINE=INNODB;
+START TRANSACTION;
+INSERT INTO test.t1 VALUES(i);
+savepoint t1_save;
+INSERT INTO test.t1 VALUES (14);
+ROLLBACK to savepoint t1_save;
+COMMIT;
+END|
+
+< ---- Master selects-- >
+-------------------------
+CALL test.p1(12);
+Warnings:
+Note 1051 Unknown table 't1'
+SELECT * FROM test.t1;
+num
+12
+
+< ---- Slave selects-- >
+------------------------
+SELECT * FROM test.t1;
+num
+12
+
+< ---- Master selects-- >
+-------------------------
+CALL test.p1(13);
+SELECT * FROM test.t1;
+num
+13
+
+< ---- Slave selects-- >
+------------------------
+SELECT * FROM test.t1;
+num
+13
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
diff --git a/mysql-test/r/rpl_row_sp008.result b/mysql-test/r/rpl_row_sp008.result
new file mode 100644
index 00000000000..57606e26f19
--- /dev/null
+++ b/mysql-test/r/rpl_row_sp008.result
@@ -0,0 +1,45 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t2;
+CREATE TABLE test.t1 (a INT,PRIMARY KEY(a));
+CREATE TABLE test.t2 (a INT,PRIMARY KEY(a));
+INSERT INTO test.t1 VALUES(1),(2);
+CREATE PROCEDURE test.p1()
+BEGIN
+SELECT SQL_CALC_FOUND_ROWS * FROM test.t1 LIMIT 1;
+INSERT INTO test.t2 VALUES(FOUND_ROWS());
+END|
+
+< ---- Master selects-- >
+-------------------------
+CALL test.p1();
+a
+1
+SELECT * FROM test.t2;
+a
+2
+
+< ---- Slave selects-- >
+------------------------
+SELECT * FROM test.t2;
+a
+2
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 4 Format_desc 1 102 Server ver: VERSION, Binlog ver: 4
+master-bin.000001 102 Query 1 193 use `test`; DROP TABLE IF EXISTS test.t2
+master-bin.000001 193 Query 1 299 use `test`; CREATE TABLE test.t1 (a INT,PRIMARY KEY(a))
+master-bin.000001 299 Query 1 405 use `test`; CREATE TABLE test.t2 (a INT,PRIMARY KEY(a))
+master-bin.000001 405 Table_map 1 444 test.t1
+master-bin.000001 444 Write_rows 1 483
+master-bin.000001 483 Table_map 1 540 mysql.proc
+master-bin.000001 540 Write_rows 1 723
+master-bin.000001 723 Table_map 1 762 test.t2
+master-bin.000001 762 Write_rows 1 796
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
diff --git a/mysql-test/r/rpl_row_sp009.result b/mysql-test/r/rpl_row_sp009.result
new file mode 100644
index 00000000000..8073e506ade
--- /dev/null
+++ b/mysql-test/r/rpl_row_sp009.result
@@ -0,0 +1,77 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+CREATE TABLE test.t1 (a INT, PRIMARY KEY(a));
+INSERT INTO test.t1 VALUES (1),(2),(3),(4);
+CREATE TABLE test.t2 (a INT, PRIMARY KEY(a));
+CREATE PROCEDURE test.p1 (arg1 CHAR(1))
+BEGIN
+DECLARE b, c INT;
+IF arg1 = 'a' THEN
+BEGIN
+DECLARE cur1 CURSOR FOR SELECT A FROM test.t1 WHERE a % 2;
+DECLARE continue handler for not found set b = 1;
+SET b = 0;
+OPEN cur1;
+c1_repeat: REPEAT
+FETCH cur1 INTO c;
+IF (b = 1) THEN
+LEAVE c1_repeat;
+END IF;
+INSERT INTO test.t2 VALUES (c);
+UNTIL b = 1
+END REPEAT;
+CLOSE cur1;
+END;
+END IF;
+IF arg1 = 'b' THEN
+BEGIN
+DECLARE cur2 CURSOR FOR SELECT a FROM test.t1 WHERE NOT a % 2;
+DECLARE continue handler for not found set b = 1;
+SET b = 0;
+OPEN cur2;
+c2_repeat: REPEAT
+FETCH cur2 INTO c;
+IF (b = 1) THEN
+LEAVE c2_repeat;
+END IF;
+INSERT INTO test.t2 VALUES (c);
+UNTIL b = 1
+END REPEAT;
+CLOSE cur2;
+END;
+END IF;
+END|
+CALL test.p1('a');
+SELECT * FROM test.t2;
+a
+1
+3
+SELECT * FROM test.t2;
+a
+1
+3
+truncate test.t2;
+call test.p1('b');
+select * from test.t2;
+a
+2
+4
+SELECT * FROM test.t2;
+a
+2
+4
+truncate test.t2;
+SELECT * FROM test.t2;
+a
+SELECT * FROM test.t2;
+a
+DROP PROCEDURE test.p1;
+DROP TABLE test.t1;
+DROP TABLE test.t2;
diff --git a/mysql-test/r/rpl_row_sp010.result b/mysql-test/r/rpl_row_sp010.result
new file mode 100644
index 00000000000..ba97f83b86a
--- /dev/null
+++ b/mysql-test/r/rpl_row_sp010.result
@@ -0,0 +1,56 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP PROCEDURE IF EXISTS test.p4;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+CREATE PROCEDURE test.p1()
+BEGIN
+INSERT INTO test.t1 VALUES(2);
+END|
+CREATE PROCEDURE test.p2()
+BEGIN
+DROP TEMPORARY TABLE IF EXISTS test.t1;
+CREATE TEMPORARY TABLE test.t1 (a int, PRIMARY KEY(a));
+INSERT INTO test.t1 VALUES(1);
+CALL test.p1();
+END|
+CALL test.p2();
+SELECT * FROM test.t1;
+a
+1
+2
+show tables;
+Tables_in_test
+CREATE PROCEDURE test.p3()
+BEGIN
+INSERT INTO test.t2 VALUES(7);
+END|
+CREATE PROCEDURE test.p4()
+BEGIN
+DROP TABLE IF EXISTS test.t2;
+CREATE TABLE test.t2 (a int, PRIMARY KEY(a));
+INSERT INTO test.t2 VALUES(6);
+CALL test.p3();
+END|
+CALL test.p4();
+SELECT * FROM test.t2;
+a
+6
+7
+SELECT * FROM test.t2;
+a
+6
+7
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP PROCEDURE IF EXISTS test.p4;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
diff --git a/mysql-test/r/rpl_row_sp011.result b/mysql-test/r/rpl_row_sp011.result
new file mode 100644
index 00000000000..e35c9f21adb
--- /dev/null
+++ b/mysql-test/r/rpl_row_sp011.result
@@ -0,0 +1,69 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP PROCEDURE IF EXISTS test.p4;
+DROP PROCEDURE IF EXISTS test.p5;
+DROP PROCEDURE IF EXISTS test.p6;
+DROP PROCEDURE IF EXISTS test.p7;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+CREATE TABLE test.t1 (a int, PRIMARY KEY(a));
+INSERT INTO test.t1 VALUES (1);
+CREATE PROCEDURE test.p1()
+BEGIN
+ALTER TABLE test.t1 ADD COLUMN b CHAR(4) AFTER a;
+UPDATE test.t1 SET b = 'rbr' WHERE a = 1;
+CALL test.p2();
+END|
+CREATE PROCEDURE test.p2()
+BEGIN
+ALTER TABLE test.t1 ADD COLUMN f FLOAT AFTER b;
+UPDATE test.t1 SET f = RAND() WHERE a = 1;
+CALL test.p3();
+END|
+CREATE PROCEDURE test.p3()
+BEGIN
+ALTER TABLE test.t1 RENAME test.t2;
+CALL test.p4();
+END|
+CREATE PROCEDURE test.p4()
+BEGIN
+ALTER TABLE test.t2 ADD INDEX (f);
+ALTER TABLE test.t2 CHANGE a a INT UNSIGNED NOT NULL AUTO_INCREMENT;
+INSERT INTO test.t2 VALUES (NULL,'TEST',RAND());
+CALL test.p5();
+END|
+CREATE PROCEDURE test.p5()
+BEGIN
+ALTER TABLE test.t2 ORDER BY f;
+INSERT INTO test.t2 VALUES (NULL,'STM',RAND());
+CALL test.p6();
+END|
+CREATE PROCEDURE test.p6()
+BEGIN
+ALTER TABLE test.t2 ADD COLUMN b2 CHAR(4) FIRST;
+ALTER TABLE test.t2 ADD COLUMN to_drop BIT(8) AFTER b2;
+INSERT INTO test.t2 VALUES ('new',1,NULL,'STM',RAND());
+CALL test.p7();
+END|
+CREATE PROCEDURE test.p7()
+BEGIN
+ALTER TABLE test.t2 DROP COLUMN to_drop;
+INSERT INTO test.t2 VALUES ('gone',NULL,'STM',RAND());
+END|
+CALL test.p1();
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP PROCEDURE IF EXISTS test.p4;
+DROP PROCEDURE IF EXISTS test.p5;
+DROP PROCEDURE IF EXISTS test.p6;
+DROP PROCEDURE IF EXISTS test.p7;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
diff --git a/mysql-test/r/rpl_row_sp012.result b/mysql-test/r/rpl_row_sp012.result
new file mode 100644
index 00000000000..28da1c3208e
--- /dev/null
+++ b/mysql-test/r/rpl_row_sp012.result
@@ -0,0 +1,58 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+grant usage on *.* to user1@localhost;
+flush privileges;
+SELECT CURRENT_USER();
+CURRENT_USER()
+root@localhost
+SELECT USER();
+USER()
+root@localhost
+CREATE PROCEDURE test.p1 () SQL SECURITY INVOKER SELECT CURRENT_USER(), USER();
+CREATE PROCEDURE test.p2 () SQL SECURITY DEFINER CALL test.p1();
+CREATE PROCEDURE test.p3 () SQL SECURITY INVOKER CALL test.p1();
+GRANT EXECUTE ON PROCEDURE p1 TO user1@localhost;
+GRANT EXECUTE ON PROCEDURE p2 TO user1@localhost;
+GRANT EXECUTE ON PROCEDURE p3 TO user1@localhost;
+
+<******** Master user1 p3 & p2 calls *******>
+----------------------------------------------
+SELECT CURRENT_USER();
+CURRENT_USER()
+user1@localhost
+SELECT USER();
+USER()
+user1@localhost
+CALL test.p3();
+CURRENT_USER() USER()
+user1@localhost user1@localhost
+CALL test.p2();
+CURRENT_USER() USER()
+root@localhost user1@localhost
+
+<******** Slave user1 p3 & p2 calls *******>
+---------------------------------------------
+SELECT CURRENT_USER();
+CURRENT_USER()
+user1@localhost
+SELECT USER();
+USER()
+user1@localhost
+CALL test.p3();
+CURRENT_USER() USER()
+user1@localhost user1@localhost
+CALL test.p2();
+CURRENT_USER() USER()
+root@localhost user1@localhost
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
diff --git a/mysql-test/r/rpl_row_stop_middle.result b/mysql-test/r/rpl_row_stop_middle.result
new file mode 100644
index 00000000000..46ca5748174
--- /dev/null
+++ b/mysql-test/r/rpl_row_stop_middle.result
@@ -0,0 +1,26 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1 (a int not null auto_increment primary key, b int, key(b));
+stop slave;
+INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+start slave;
+stop slave;
+drop table t1;
+drop table t1;
diff --git a/mysql-test/r/rpl_row_stop_middle_update.result b/mysql-test/r/rpl_row_stop_middle_update.result
new file mode 100644
index 00000000000..584a3af4543
--- /dev/null
+++ b/mysql-test/r/rpl_row_stop_middle_update.result
@@ -0,0 +1,16 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1 (words varchar(20)) engine=myisam;
+load data infile '../../std_data/words.dat' into table t1 (words);
+select count(*) from t1;
+count(*)
+70
+select count(*) from t1;
+count(*)
+70
+drop table t1;
+drop table t1;
diff --git a/mysql-test/r/rpl_row_tabledefs.result b/mysql-test/r/rpl_row_tabledefs.result
new file mode 100644
index 00000000000..715ffcc7578
--- /dev/null
+++ b/mysql-test/r/rpl_row_tabledefs.result
@@ -0,0 +1,248 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=myisam;
+CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=myisam;
+CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=myisam;
+CREATE TABLE t4 (a INT) ENGINE=myisam;
+CREATE TABLE t5 (a INT, b INT, c INT) ENGINE=myisam;
+CREATE TABLE t6 (a INT, b INT, c INT) ENGINE=myisam;
+CREATE TABLE t9 (a INT PRIMARY KEY) ENGINE=myisam;
+ALTER TABLE t1 ADD x INT DEFAULT 42;
+ALTER TABLE t2 ADD x INT DEFAULT 42 AFTER a;
+ALTER TABLE t3 ADD x INT DEFAULT 42 FIRST;
+ALTER TABLE t4 MODIFY a FLOAT;
+ALTER TABLE t5 MODIFY b FLOAT;
+ALTER TABLE t6 MODIFY c FLOAT;
+INSERT INTO t9 VALUES (1);
+INSERT INTO t1 VALUES (1,2);
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_PORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 1042
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running Yes
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 1454
+Last_Error Table width mismatch - received 2 columns, test.t1 has 3 columns
+Skip_Counter 0
+Exec_Master_Log_Pos 968
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+INSERT INTO t9 VALUES (2);
+INSERT INTO t2 VALUES (2,4);
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_PORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 1185
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running Yes
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 1454
+Last_Error Table width mismatch - received 2 columns, test.t2 has 3 columns
+Skip_Counter 0
+Exec_Master_Log_Pos 1111
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+INSERT INTO t9 VALUES (3);
+INSERT INTO t3 VALUES (3,6);
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_PORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 1328
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running Yes
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 1454
+Last_Error Table width mismatch - received 2 columns, test.t3 has 3 columns
+Skip_Counter 0
+Exec_Master_Log_Pos 1254
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+INSERT INTO t9 VALUES (4);
+INSERT INTO t4 VALUES (4);
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_PORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 1466
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running Yes
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 1454
+Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4
+Skip_Counter 0
+Exec_Master_Log_Pos 1397
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+INSERT INTO t9 VALUES (5);
+INSERT INTO t5 VALUES (5,10,25);
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_PORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 1614
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running Yes
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 1454
+Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4
+Skip_Counter 0
+Exec_Master_Log_Pos 1535
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+INSERT INTO t9 VALUES (6);
+INSERT INTO t6 VALUES (6,12,36);
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_PORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 1762
+Relay_Log_File #
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running Yes
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 1454
+Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4
+Skip_Counter 0
+Exec_Master_Log_Pos 1683
+Relay_Log_Space #
+Until_Condition None
+Until_Log_File
+Until_Log_Pos 0
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
+SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2;
+START SLAVE;
+DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t9;
diff --git a/mysql-test/r/rpl_row_timezone.result b/mysql-test/r/rpl_row_timezone.result
new file mode 100644
index 00000000000..26c10648ffb
--- /dev/null
+++ b/mysql-test/r/rpl_row_timezone.result
@@ -0,0 +1,121 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+set timestamp=100000000;
+create table t1 (t timestamp, n int not null auto_increment, PRIMARY KEY(n));
+create table t2 (t char(32), n int not null auto_increment, PRIMARY KEY(n));
+select @@time_zone;
+@@time_zone
+Europe/Moscow
+select @@time_zone;
+@@time_zone
+Europe/Moscow
+insert into t1 values ('20050101000000', NULL), ('20050611093902',NULL);
+insert into t1 values ('20040101000000',NULL), ('20040611093902',NULL);
+select * from t1;
+t n
+2005-01-01 00:00:00 1
+2005-06-11 09:39:02 2
+2004-01-01 00:00:00 3
+2004-06-11 09:39:02 4
+select * from t1;
+t n
+2005-01-01 00:00:00 1
+2005-06-11 09:39:02 2
+2004-01-01 00:00:00 3
+2004-06-11 09:39:02 4
+delete from t1;
+set time_zone='Europe/Moscow';
+insert into t1 values ('20040101000000',NULL), ('20040611093902',NULL);
+select * from t1;
+t n
+2004-01-01 00:00:00 5
+2004-06-11 09:39:02 6
+set time_zone='Europe/Moscow';
+select * from t1;
+t n
+2004-01-01 00:00:00 5
+2004-06-11 09:39:02 6
+/*!40019 SET @@session.max_insert_delayed_threads=0*/;
+/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ROLLBACK;
+use test;
+SET TIMESTAMP=100000000;
+SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1;
+SET @@session.sql_mode=0;
+SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
+create table t1 (t timestamp, n int not null auto_increment, PRIMARY KEY(n));
+SET TIMESTAMP=100000000;
+create table t2 (t char(32), n int not null auto_increment, PRIMARY KEY(n));
+SET TIMESTAMP=100000000;
+delete from t1;
+# End of log file
+ROLLBACK /* added by mysqlbinlog */;
+/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+delete from t1;
+set time_zone='UTC';
+load data infile '../../std_data/rpl_timezone2.dat' into table t1;
+Warnings:
+Warning 1265 Data truncated for column 't' at row 1
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1265 Data truncated for column 't' at row 2
+Warning 1261 Row 2 doesn't contain data for all columns
+select * from t1;
+t n
+0000-00-00 00:00:00 7
+0000-00-00 00:00:00 8
+set time_zone='UTC';
+select * from t1;
+t n
+0000-00-00 00:00:00 7
+0000-00-00 00:00:00 8
+set time_zone='Europe/Moscow';
+set time_zone='Europe/Moscow';
+delete from t1;
+insert into t1 values ('20040101000000',NULL), ('20040611093902',NULL);
+set time_zone='MET';
+insert into t2 (select * from t1);
+select * from t1;
+t n
+2003-12-31 22:00:00 9
+2004-06-11 07:39:02 10
+select * from t2;
+t n
+2003-12-31 22:00:00 9
+2004-06-11 07:39:02 10
+delete from t2;
+set timestamp=1000072000;
+insert into t2 values (current_timestamp,NULL), (current_date,NULL), (current_time,NULL);
+select * from t2;
+t n
+2001-09-09 23:46:40 11
+2001-09-09 12
+23:46:40 13
+delete from t2;
+insert into t2 values (from_unixtime(1000000000),NULL),
+(unix_timestamp('2001-09-09 03:46:40'),NULL);
+select * from t2;
+t n
+2001-09-09 03:46:40 14
+1000000000 15
+select * from t2;
+t n
+2001-09-09 03:46:40 14
+1000000000 15
+set global time_zone='MET';
+delete from t2;
+set time_zone='UTC';
+insert into t2 values(convert_tz('2004-01-01 00:00:00','MET',@@time_zone),NULL);
+insert into t2 values(convert_tz('2005-01-01 00:00:00','MET','Japan'),NULL);
+select * from t2;
+t n
+2003-12-31 23:00:00 16
+2005-01-01 08:00:00 17
+select * from t2;
+t n
+2003-12-31 23:00:00 16
+2005-01-01 08:00:00 17
+drop table t1, t2;
diff --git a/mysql-test/r/rpl_row_trig001.result b/mysql-test/r/rpl_row_trig001.result
new file mode 100644
index 00000000000..dcbb05e4ab4
--- /dev/null
+++ b/mysql-test/r/rpl_row_trig001.result
@@ -0,0 +1,29 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE test.t1 (n MEDIUMINT NOT NULL, d DATETIME, PRIMARY KEY(n));
+CREATE TABLE test.t2 (n MEDIUMINT NOT NULL AUTO_INCREMENT, f FLOAT, d DATETIME, PRIMARY KEY(n));
+CREATE TABLE test.t3 (n MEDIUMINT NOT NULL AUTO_INCREMENT, d DATETIME, PRIMARY KEY(n));
+INSERT INTO test.t1 VALUES (1,NOW());
+CREATE TRIGGER test.t2_ai AFTER INSERT ON test.t2 FOR EACH ROW UPDATE test.t1 SET d=NOW() where n = 1;//
+CREATE PROCEDURE test.p3()
+BEGIN
+INSERT INTO test.t3 (d) VALUES (NOW());
+END//
+CREATE TRIGGER test.t3_bi_t2 BEFORE INSERT ON test.t2 FOR EACH ROW CALL test.p3()//
+CREATE PROCEDURE test.p2()
+BEGIN
+INSERT INTO test.t2 (f,d) VALUES (RAND(),NOW());
+END//
+
+<End test section 2 (Tiggers & SP)>
+-----------------------------------
+DROP PROCEDURE test.p2;
+DROP TRIGGER test.t2_ai;
+DROP TRIGGER test.t3_bi_t2;
+DROP TABLE test.t1;
+DROP TABLE test.t2;
+DROP TABLE test.t3;
diff --git a/mysql-test/r/rpl_row_trig002.result b/mysql-test/r/rpl_row_trig002.result
new file mode 100644
index 00000000000..62dc2f17562
--- /dev/null
+++ b/mysql-test/r/rpl_row_trig002.result
@@ -0,0 +1,63 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP TRIGGER test.t2_ai;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
+CREATE TABLE test.t2 (value CHAR(30),domain_id INT, mailaccount_id INT, program CHAR(30),keey CHAR(30),PRIMARY KEY(domain_id));
+CREATE TABLE test.t3 (value CHAR(30),domain_id INT, mailaccount_id INT, program CHAR(30),keey CHAR(30),PRIMARY KEY(domain_id));
+CREATE TABLE test.t1 (id INT,domain CHAR(30),PRIMARY KEY(id));
+CREATE TRIGGER test.t2_ai AFTER INSERT ON test.t2 FOR EACH ROW UPDATE test.t3 ms, test.t1 d SET ms.value='No' WHERE ms.domain_id = (SELECT max(id) FROM test.t1 WHERE domain='example.com') AND ms.mailaccount_id IS NULL AND ms.program='spamfilter' AND ms.keey='scan_incoming'|
+INSERT INTO test.t1 VALUES (1, 'example.com'),(2, 'mysql.com'),(3, 'earthmotherwear.com'), (4, 'yahoo.com'),(5, 'example.com');
+select * from test.t1;
+id domain
+1 example.com
+2 mysql.com
+3 earthmotherwear.com
+4 yahoo.com
+5 example.com
+select * from test.t1;
+id domain
+1 example.com
+2 mysql.com
+3 earthmotherwear.com
+4 yahoo.com
+5 example.com
+INSERT INTO test.t3 VALUES ('Yes', 5, NULL, 'spamfilter','scan_incoming');
+INSERT INTO test.t3 VALUES ('Yes', 1, NULL, 'spamfilter','scan_incoming');
+INSERT INTO test.t2 VALUES ('Yes', 1, NULL, 'spamfilter','scan_incoming');
+select * from test.t2;
+value domain_id mailaccount_id program keey
+Yes 1 NULL spamfilter scan_incoming
+select * from test.t3;
+value domain_id mailaccount_id program keey
+No 5 NULL spamfilter scan_incoming
+Yes 1 NULL spamfilter scan_incoming
+select * from test.t2;
+value domain_id mailaccount_id program keey
+Yes 1 NULL spamfilter scan_incoming
+select * from test.t3;
+value domain_id mailaccount_id program keey
+No 5 NULL spamfilter scan_incoming
+Yes 1 NULL spamfilter scan_incoming
+DELETE FROM test.t1 WHERE id = 1;
+select * from test.t1;
+id domain
+2 mysql.com
+3 earthmotherwear.com
+4 yahoo.com
+5 example.com
+select * from test.t1;
+id domain
+2 mysql.com
+3 earthmotherwear.com
+4 yahoo.com
+5 example.com
+DROP TRIGGER test.t2_ai;
+DROP TABLE test.t1;
+DROP TABLE test.t2;
+DROP TABLE test.t3;
diff --git a/mysql-test/r/rpl_row_trig003.result b/mysql-test/r/rpl_row_trig003.result
new file mode 100644
index 00000000000..43c2ecde2b4
--- /dev/null
+++ b/mysql-test/r/rpl_row_trig003.result
@@ -0,0 +1,83 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP TRIGGER test.t1_bi;
+DROP TRIGGER test.t2_ai;
+DROP TRIGGER test.t1_bu;
+DROP TRIGGER test.t2_au;
+DROP TRIGGER test.t1_bd;
+DROP TRIGGER test.t2_ad;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
+CREATE TABLE test.t1 (id MEDIUMINT NOT NULL AUTO_INCREMENT, b1 BIT(8), vc VARCHAR(255), bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, f FLOAT DEFAULT 0, total BIGINT UNSIGNED, y YEAR, t TIMESTAMP,PRIMARY KEY(id));
+CREATE TABLE test.t2 (id MEDIUMINT NOT NULL AUTO_INCREMENT, b1 BIT(8), vc VARCHAR(255), bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, f FLOAT DEFAULT 0, total BIGINT UNSIGNED, y YEAR, t TIMESTAMP,PRIMARY KEY(id));
+CREATE TABLE test.t3 (id MEDIUMINT NOT NULL AUTO_INCREMENT, b1 BIT(8), vc VARCHAR(255), bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, f FLOAT DEFAULT 0, total BIGINT UNSIGNED, y YEAR, t TIMESTAMP,PRIMARY KEY(id));
+CREATE TRIGGER test.t1_bi BEFORE INSERT ON test.t1 FOR EACH ROW UPDATE test.t3 SET b1=1 and y=YEAR(NOW())|
+CREATE TRIGGER test.t2_ai AFTER INSERT ON test.t2 FOR EACH ROW BEGIN
+INSERT INTO test.t3 VALUES(NULL,0,'MySQL Replication team rocks!', 'Dark beer in prague is #1',12345.34,12.51,0,1965,NOW());
+UPDATE test.t3 SET f = ROUND(f);
+END|
+CREATE TRIGGER test.t1_bu BEFORE UPDATE on test.t1 FOR EACH ROW BEGIN
+UPDATE test.t3 SET y = '2000';
+INSERT INTO test.t3 VALUES(NULL,1,'Testing MySQL databases before update ', 'Insert should work',621.43, 0105.21,0,1974,NOW());
+END|
+CREATE TRIGGER test.t2_au AFTER UPDATE on test.t2 FOR EACH ROW BEGIN
+DECLARE done INT DEFAULT 0;
+DECLARE a DECIMAL(10,4);
+DECLARE b FLOAT;
+DECLARE num MEDIUMINT;
+DECLARE cur1 CURSOR FOR SELECT t2.id, t2.d, t2.f FROM test.t2;
+DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
+OPEN cur1;
+REPEAT
+FETCH cur1 INTO num, a, b;
+IF NOT done THEN
+UPDATE test.t3 SET total =(a*b) WHERE ID = num;
+END IF;
+UNTIL done END REPEAT;
+CLOSE cur1;
+END|
+CREATE TRIGGER test.t1_bd BEFORE DELETE on test.t1 FOR EACH ROW BEGIN
+DECLARE done INT DEFAULT 0;
+DECLARE a BIT(8);
+DECLARE b VARCHAR(255);
+DECLARE c CHAR(255);
+DECLARE d DECIMAL(10,4);
+DECLARE e FLOAT;
+DECLARE f BIGINT UNSIGNED;
+DECLARE g YEAR;
+DECLARE h TIMESTAMP;
+DECLARE cur1 CURSOR FOR SELECT t1.b1, t1.vc, t1.bc, t1.d, t1.f, t1.total, t1.y, t1.t FROM test.t1;
+DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
+OPEN cur1;
+REPEAT
+FETCH cur1 INTO a, b, c, d, e, f, g, h;
+IF NOT done THEN
+INSERT INTO test.t3 VALUES(NULL, a, b, c, d, e, f, g, h);
+END IF;
+UNTIL done END REPEAT;
+CLOSE cur1;
+END|
+CREATE TRIGGER test.t2_ad AFTER DELETE ON test.t2 FOR EACH ROW
+DELETE FROM test.t1|
+INSERT INTO test.t1 VALUES(NULL,1,'Testing MySQL databases is a cool ', 'Must make it bug free for the customer',654321.4321,15.21,0,1965,NOW());
+INSERT INTO test.t2 VALUES(NULL,0,'Testing MySQL databases is a cool ', 'MySQL Customers ROCK!',654321.4321,1.24521,0,YEAR(NOW()),NOW());
+UPDATE test.t1 SET b1 = 0 WHERE b1 = 1;
+INSERT INTO test.t2 VALUES(NULL,1,'This is an after update test.', 'If this works, total will not be zero on the master or slave',1.4321,5.221,0,YEAR(NOW()),NOW());
+UPDATE test.t2 SET b1 = 0 WHERE b1 = 1;
+INSERT INTO test.t1 VALUES(NULL,1,'add some more test data test.', 'and hope for the best', 3.321,5.221,0,YEAR(NOW()),NOW());
+DELETE FROM test.t1 WHERE id = 1;
+DELETE FROM test.t2 WHERE id = 1;
+DROP TRIGGER test.t1_bi;
+DROP TRIGGER test.t2_ai;
+DROP TRIGGER test.t1_bu;
+DROP TRIGGER test.t2_au;
+DROP TRIGGER test.t1_bd;
+DROP TRIGGER test.t2_ad;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
diff --git a/mysql-test/r/rpl_row_trig004.result b/mysql-test/r/rpl_row_trig004.result
new file mode 100644
index 00000000000..04f46121994
--- /dev/null
+++ b/mysql-test/r/rpl_row_trig004.result
@@ -0,0 +1,29 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP TRIGGER test.t1_bi_t2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+CREATE TABLE test.t1 (n MEDIUMINT NOT NULL AUTO_INCREMENT, d FLOAT, PRIMARY KEY(n))ENGINE=INNODB;
+CREATE TABLE test.t2 (n MEDIUMINT NOT NULL, f FLOAT, PRIMARY KEY(n))ENGINE=INNODB;
+CREATE TRIGGER test.t1_bi_t2 BEFORE INSERT ON test.t2 FOR EACH ROW INSERT INTO test.t1 VALUES (NULL, 1.234)//
+INSERT INTO test.t2 VALUES (1, 0.0);
+INSERT INTO test.t2 VALUES (1, 0.0);
+select * from test.t1;
+n d
+1 1.234
+select * from test.t2;
+n f
+1 0
+select * from test.t1;
+n d
+1 1.234
+select * from test.t2;
+n f
+1 0
+DROP TRIGGER test.t1_bi_t2;
+DROP TABLE test.t1;
+DROP TABLE test.t2;
diff --git a/mysql-test/r/rpl_row_until.result b/mysql-test/r/rpl_row_until.result
new file mode 100644
index 00000000000..8d4b0d6b591
--- /dev/null
+++ b/mysql-test/r/rpl_row_until.result
@@ -0,0 +1,62 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+stop slave;
+create table t1(n int not null auto_increment primary key);
+insert into t1 values (1),(2),(3),(4);
+drop table t1;
+create table t2(n int not null auto_increment primary key);
+insert into t2 values (1),(2);
+insert into t2 values (3),(4);
+drop table t2;
+start slave until master_log_file='master-bin.000001', master_log_pos=311;
+select * from t1;
+n
+1
+2
+3
+4
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 740 slave-relay-bin.000004 # master-bin.000001 # No 0 0 311 # Master master-bin.000001 311 No #
+start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
+select * from t1;
+n
+1
+2
+3
+4
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 740 slave-relay-bin.000004 # master-bin.000001 # No 0 0 311 # Master master-no-such-bin.000001 291 No #
+start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728;
+select * from t2;
+n
+1
+2
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 740 slave-relay-bin.000004 # master-bin.000001 # No 0 0 586 # Relay slave-relay-bin.000004 728 No #
+start slave;
+stop slave;
+start slave until master_log_file='master-bin.000001', master_log_pos=740;
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 740 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 740 # Master master-bin.000001 740 No #
+start slave until master_log_file='master-bin', master_log_pos=561;
+ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL
+start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12;
+ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL
+start slave until master_log_file='master-bin.000001';
+ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL
+start slave until relay_log_file='slave-relay-bin.000002';
+ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL
+start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=561;
+ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL
+start slave sql_thread;
+start slave until master_log_file='master-bin.000001', master_log_pos=740;
+Warnings:
+Note 1254 Slave is already running
diff --git a/mysql-test/r/rpl_row_user_variables.result b/mysql-test/r/rpl_row_user_variables.result
new file mode 100644
index 00000000000..3e2efcbe9da
--- /dev/null
+++ b/mysql-test/r/rpl_row_user_variables.result
@@ -0,0 +1,82 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+reset master;
+create table t1(n char(30));
+set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
+set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
+set @n1:=null;
+set @s2:='', @s3:='abc\'def', @s4:= 'abc\\def', @s5:= 'abc''def';
+insert into t1 values (@i1), (@i2), (@i3), (@i4);
+insert into t1 values (@r1), (@r2);
+insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5);
+insert into t1 values (@n1);
+insert into t1 values (@n2);
+insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1);
+insert into t1 values (@a+(@b:=@a+1));
+set @q:='abc';
+insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
+set @a:=5;
+insert into t1 values (@a),(@a);
+select * from t1 where n = '<nonexistant>';
+n
+insert into t1 values (@a),(@a),(@a*5);
+select * from t1;
+n
+12345678901234
+-12345678901234
+0
+-1
+12.5
+-12.5
+This is a test
+
+abc'def
+abc\def
+abc'def
+NULL
+NULL
+0
+1
+2
+5
+abc
+abcn1
+abcn1n2
+5
+5
+NULL
+NULL
+NULL
+select * from t1;
+n
+12345678901234
+-12345678901234
+0
+-1
+12.5
+-12.5
+This is a test
+
+abc'def
+abc\def
+abc'def
+NULL
+NULL
+0
+1
+2
+5
+abc
+abcn1
+abcn1n2
+5
+5
+NULL
+NULL
+NULL
+drop table t1;
+stop slave;
diff --git a/mysql-test/r/rpl_row_view.result b/mysql-test/r/rpl_row_view.result
new file mode 100644
index 00000000000..ce807a361ba
--- /dev/null
+++ b/mysql-test/r/rpl_row_view.result
@@ -0,0 +1,44 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop table if exists t1,v1;
+drop view if exists t1,v1;
+create table t1 (a int);
+insert into t1 values (1);
+create view v1 as select a from t1;
+insert into v1 values (2);
+select * from v1 order by a;
+a
+1
+2
+select * from v1 order by a;
+a
+1
+2
+update v1 set a=3 where a=1;
+select * from v1 order by a;
+a
+2
+3
+select * from v1 order by a;
+a
+2
+3
+delete from v1 where a=2;
+select * from v1 order by a;
+a
+3
+select * from v1 order by a;
+a
+3
+alter view v1 as select a as b from t1;
+select * from v1 order by 1;
+b
+3
+drop view v1;
+select * from v1 order by a;
+ERROR 42S02: Table 'test.v1' doesn't exist
+drop table t1;
diff --git a/mysql-test/r/rpl_row_view01.result b/mysql-test/r/rpl_row_view01.result
new file mode 100644
index 00000000000..039d14d6272
--- /dev/null
+++ b/mysql-test/r/rpl_row_view01.result
@@ -0,0 +1,100 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create database if not exists mysqltest1;
+DROP VIEW IF EXISTS mysqltest1.v1;
+DROP VIEW IF EXISTS mysqltest1.v2;
+DROP VIEW IF EXISTS mysqltest1.v3;
+DROP VIEW IF EXISTS mysqltest1.v4;
+DROP TABLE IF EXISTS mysqltest1.t3;
+DROP TABLE IF EXISTS mysqltest1.t1;
+DROP TABLE IF EXISTS mysqltest1.t2;
+DROP TABLE IF EXISTS mysqltest1.t4;
+CREATE TABLE mysqltest1.t1 (a INT, c CHAR(6),PRIMARY KEY(a));
+CREATE TABLE mysqltest1.t2 (a INT, c CHAR(6),PRIMARY KEY(a));
+CREATE TABLE mysqltest1.t3 (a INT, c CHAR(6), c2 CHAR(6), PRIMARY KEY(a));
+CREATE TABLE mysqltest1.t4 (a INT, qty INT, price INT,PRIMARY KEY(a));
+CREATE TABLE mysqltest1.t5 (qty INT, price INT, total INT, PRIMARY KEY(qty));
+INSERT INTO mysqltest1.t1 VALUES (1,'Thank'),(2,'it'),(3,'Friday');
+INSERT INTO mysqltest1.t2 VALUES (1,'GOD'),(2,'is'),(3,'TGIF');
+INSERT INTO mysqltest1.t4 VALUES(1, 3, 50),(2, 18, 3),(4, 4, 4);
+CREATE VIEW mysqltest1.v2 AS SELECT qty, price, qty*price AS value FROM mysqltest1.t4;
+CREATE VIEW mysqltest1.v1 AS SELECT t1.a, t1.c, t2.c as c2 FROM mysqltest1.t1 as t1, mysqltest1.t2 AS t2 WHERE mysqltest1.t1.a = mysqltest1.t2.a;
+CREATE VIEW mysqltest1.v3 AS SELECT * FROM mysqltest1.t1;
+CREATE VIEW mysqltest1.v4 AS SELECT * FROM mysqltest1.v3 WHERE a > 1 WITH LOCAL CHECK OPTION;
+SELECT * FROM mysqltest1.v2;
+qty price value
+3 50 150
+18 3 54
+4 4 16
+SELECT * FROM mysqltest1.v1;
+a c c2
+1 Thank GOD
+2 it is
+3 Friday TGIF
+SELECT * FROM mysqltest1.v2;
+qty price value
+3 50 150
+18 3 54
+4 4 16
+SELECT * FROM mysqltest1.v1;
+a c c2
+1 Thank GOD
+2 it is
+3 Friday TGIF
+INSERT INTO mysqltest1.t5 SELECT * FROM mysqltest1.v2;
+INSERT INTO mysqltest1.t3 SELECT * FROM mysqltest1.v1;
+SELECT * FROM mysqltest1.t5;
+qty price total
+3 50 150
+18 3 54
+4 4 16
+SELECT * FROM mysqltest1.t3;
+a c c2
+1 Thank GOD
+2 it is
+3 Friday TGIF
+SELECT * FROM mysqltest1.t5;
+qty price total
+3 50 150
+18 3 54
+4 4 16
+SELECT * FROM mysqltest1.t3;
+a c c2
+1 Thank GOD
+2 it is
+3 Friday TGIF
+INSERT INTO mysqltest1.v4 VALUES (4,'TEST');
+SELECT * FROM mysqltest1.t1;
+a c
+1 Thank
+2 it
+3 Friday
+4 TEST
+SELECT * FROM mysqltest1.v4;
+a c
+2 it
+3 Friday
+4 TEST
+SELECT * FROM mysqltest1.t1;
+a c
+1 Thank
+2 it
+3 Friday
+4 TEST
+SELECT * FROM mysqltest1.v4;
+a c
+2 it
+3 Friday
+4 TEST
+DROP VIEW IF EXISTS mysqltest1.v1;
+DROP VIEW IF EXISTS mysqltest1.v2;
+DROP VIEW IF EXISTS mysqltest1.v3;
+DROP VIEW IF EXISTS mysqltest1.v4;
+DROP TABLE IF EXISTS mysqltest1.t3;
+DROP TABLE IF EXISTS mysqltest1.t1;
+DROP TABLE IF EXISTS mysqltest1.t2;
+DROP TABLE IF EXISTS mysqltest1.t4;
diff --git a/mysql-test/r/rpl_server_id1.result b/mysql-test/r/rpl_server_id1.result
index a3ab6672f69..c94a7748fcd 100644
--- a/mysql-test/r/rpl_server_id1.result
+++ b/mysql-test/r/rpl_server_id1.result
@@ -10,7 +10,7 @@ stop slave;
change master to master_port=SLAVE_PORT;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
- 127.0.0.1 root SLAVE_PORT 1 4 slave-relay-bin.000001 4 No No # 0 0 0 98 None 0 No NULL
+ 127.0.0.1 root SLAVE_PORT 1 4 slave-relay-bin.000001 4 No No # # 0 0 0 102 None 0 No NULL
start slave;
insert into t1 values (1);
show status like "slave_running";
diff --git a/mysql-test/r/rpl_server_id2.result b/mysql-test/r/rpl_server_id2.result
index b196646aecc..72db862040e 100644
--- a/mysql-test/r/rpl_server_id2.result
+++ b/mysql-test/r/rpl_server_id2.result
@@ -10,7 +10,7 @@ stop slave;
change master to master_port=SLAVE_PORT;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
- 127.0.0.1 root SLAVE_PORT 1 4 slave-relay-bin.000001 4 No No # 0 0 0 98 None 0 No NULL
+ 127.0.0.1 root SLAVE_PORT 1 4 slave-relay-bin.000001 4 No No # 0 0 0 102 None 0 No NULL
start slave;
insert into t1 values (1);
select * from t1;
diff --git a/mysql-test/r/rpl_sp004.result b/mysql-test/r/rpl_sp004.result
new file mode 100644
index 00000000000..dfc672d4cd7
--- /dev/null
+++ b/mysql-test/r/rpl_sp004.result
@@ -0,0 +1,93 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t3;
+CREATE PROCEDURE test.p1()
+BEGIN
+CREATE TABLE IF NOT EXISTS test.t1(a INT,PRIMARY KEY(a));
+CREATE TABLE IF NOT EXISTS test.t2(a INT,PRIMARY KEY(a));
+INSERT INTO test.t1 VALUES (4),(2),(1),(3);
+UPDATE test.t1 SET a=a+4 WHERE a=4;
+INSERT INTO test.t2 (a) SELECT t1.a FROM test.t1;
+UPDATE test.t1 SET a=a+4 WHERE a=8;
+CREATE TABLE IF NOT EXISTS test.t3(n MEDIUMINT NOT NULL AUTO_INCREMENT, f FLOAT, d DATETIME, PRIMARY KEY(n));
+END|
+CREATE PROCEDURE test.p2()
+BEGIN
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+INSERT INTO test.t3 VALUES(NULL,11111111.233333,NOW());
+END|
+CALL test.p1();
+SELECT * FROM test.t1;
+a
+1
+2
+3
+12
+SELECT * FROM test.t2;
+a
+1
+2
+3
+8
+SELECT * FROM test.t1;
+a
+1
+2
+3
+12
+SELECT * FROM test.t2;
+a
+1
+2
+3
+8
+CALL test.p2();
+USE test;
+SHOW TABLES;
+Tables_in_test
+t3
+USE test;
+SHOW TABLES;
+Tables_in_test
+t3
+CALL test.p1();
+Warnings:
+Note 1050 Table 't3' already exists
+SELECT * FROM test.t1;
+a
+1
+2
+3
+12
+SELECT * FROM test.t2;
+a
+1
+2
+3
+8
+SELECT * FROM test.t1;
+a
+1
+2
+3
+12
+SELECT * FROM test.t2;
+a
+1
+2
+3
+8
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
diff --git a/mysql-test/r/rpl000001.result b/mysql-test/r/rpl_stm_000001.result
index de9f6f16b2a..de9f6f16b2a 100644
--- a/mysql-test/r/rpl000001.result
+++ b/mysql-test/r/rpl_stm_000001.result
diff --git a/mysql-test/r/rpl_EE_error.result b/mysql-test/r/rpl_stm_EE_err.result
index f4765b4b13c..f4765b4b13c 100644
--- a/mysql-test/r/rpl_EE_error.result
+++ b/mysql-test/r/rpl_stm_EE_err.result
diff --git a/mysql-test/r/rpl_charset.result b/mysql-test/r/rpl_stm_charset.result
index 28f694a3933..fcadf43c21c 100644
--- a/mysql-test/r/rpl_charset.result
+++ b/mysql-test/r/rpl_stm_charset.result
@@ -103,7 +103,7 @@ a b
1 cp850_general_ci
drop database mysqltest2;
drop database mysqltest3;
-show binlog events from 98;
+show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # drop database if exists mysqltest2
master-bin.000001 # Query 1 # drop database if exists mysqltest3
diff --git a/mysql-test/r/rpl_ddl.result b/mysql-test/r/rpl_stm_ddl.result
index 4d8f2f11d4a..91163f1fe29 100644
--- a/mysql-test/r/rpl_ddl.result
+++ b/mysql-test/r/rpl_stm_ddl.result
@@ -10,28 +10,28 @@ DROP DATABASE IF EXISTS mysqltest2;
DROP DATABASE IF EXISTS mysqltest3;
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
-CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE= "InnoDB";
+CREATE TABLE mysqltest1.t1 (f1 BIGINT) ENGINE="InnoDB";
INSERT INTO mysqltest1.t1 SET f1= 0;
-CREATE TABLE mysqltest1.t2 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t3 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t4 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t5 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t6 (f1 BIGINT) ENGINE= "InnoDB";
+CREATE TABLE mysqltest1.t2 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t3 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t4 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t5 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t6 (f1 BIGINT) ENGINE="InnoDB";
CREATE INDEX my_idx6 ON mysqltest1.t6(f1);
-CREATE TABLE mysqltest1.t7 (f1 BIGINT) ENGINE= "InnoDB";
+CREATE TABLE mysqltest1.t7 (f1 BIGINT) ENGINE="InnoDB";
INSERT INTO mysqltest1.t7 SET f1= 0;
-CREATE TABLE mysqltest1.t8 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t9 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t10 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t11 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t12 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t13 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t14 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t15 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t16 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t17 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t18 (f1 BIGINT) ENGINE= "InnoDB";
-CREATE TABLE mysqltest1.t19 (f1 BIGINT) ENGINE= "InnoDB";
+CREATE TABLE mysqltest1.t8 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t9 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t10 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t11 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t12 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t13 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t14 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t15 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t16 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t17 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t18 (f1 BIGINT) ENGINE="InnoDB";
+CREATE TABLE mysqltest1.t19 (f1 BIGINT) ENGINE="InnoDB";
CREATE TEMPORARY TABLE mysqltest1.t23 (f1 BIGINT);
SET AUTOCOMMIT = 0;
use mysqltest1;
diff --git a/mysql-test/r/rpl_error_ignored_table.result b/mysql-test/r/rpl_stm_err_ignoredtable.result
index a0a808ce9a8..42abb2c3c44 100644
--- a/mysql-test/r/rpl_error_ignored_table.result
+++ b/mysql-test/r/rpl_stm_err_ignoredtable.result
@@ -9,7 +9,7 @@ insert into t1 values (1),(1);
ERROR 23000: Duplicate entry '1' for key 1
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 288 # # master-bin.000001 Yes Yes test.t3,test.t1,test.t2 0 0 288 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 292 # # master-bin.000001 Yes Yes test.t3,test.t1,test.t2 0 0 292 # None 0 No #
show tables like 't1';
Tables_in_test (t1)
drop table t1;
@@ -26,7 +26,7 @@ select (@id := id) - id from t3;
0
kill @id;
drop table t2,t3;
-show binlog events from 98;
+show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # use `test`; create table t1 (a int primary key)
master-bin.000001 # Query 1 # use `test`; insert into t1 values (1),(1)
diff --git a/mysql-test/r/rpl_stm_flsh_tbls.result b/mysql-test/r/rpl_stm_flsh_tbls.result
new file mode 100644
index 00000000000..8a813c57451
--- /dev/null
+++ b/mysql-test/r/rpl_stm_flsh_tbls.result
@@ -0,0 +1,32 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1 (a int);
+insert into t1 values (10);
+create table t2 (a int);
+create table t3 (a int) engine=merge union(t1);
+create table t4 (a int);
+insert into t4 select * from t3;
+rename table t1 to t5, t2 to t1;
+flush no_write_to_binlog tables;
+SHOW BINLOG EVENTS FROM 652 ;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; rename table t1 to t5, t2 to t1
+select * from t3;
+a
+flush tables;
+SHOW BINLOG EVENTS FROM 652 ;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; rename table t1 to t5, t2 to t1
+master-bin.000001 # Query 1 # use `test`; flush tables
+select * from t3;
+a
+stop slave;
+drop table t1;
+flush tables with read lock;
+start slave;
+stop slave;
+ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
diff --git a/mysql-test/r/rpl_loaddata_rule_m.result b/mysql-test/r/rpl_stm_loaddata_m.result
index 3571c9973ea..9c7dba0e711 100644
--- a/mysql-test/r/rpl_loaddata_rule_m.result
+++ b/mysql-test/r/rpl_stm_loaddata_m.result
@@ -7,13 +7,14 @@ start slave;
drop database if exists mysqltest;
stop slave;
create database mysqltest;
-create table t1(a int, b int, unique(b));
use mysqltest;
-load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
-show binlog events from 98;
+create table t1(a int, b int, unique(b));
+load data infile '../../std_data/rpl_loaddata.dat' into table t1;
+show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # drop database if exists mysqltest
master-bin.000001 # Query 1 # create database mysqltest
+master-bin.000001 # Query 1 # use `mysqltest`; create table t1(a int, b int, unique(b))
master-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=12
-master-bin.000001 # Execute_load_query 1 # use `mysqltest`; load data infile '../../std_data/rpl_loaddata.dat' into table test.t1 ;file_id=1
+master-bin.000001 # Execute_load_query 1 # use `mysqltest`; load data infile '../../std_data/rpl_loaddata.dat' into table t1 ;file_id=1
drop database mysqltest;
diff --git a/mysql-test/r/rpl_stm_log.result b/mysql-test/r/rpl_stm_log.result
new file mode 100644
index 00000000000..a7ef117854d
--- /dev/null
+++ b/mysql-test/r/rpl_stm_log.result
@@ -0,0 +1,103 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+stop slave;
+reset master;
+reset slave;
+reset master;
+create table t1(n int not null auto_increment primary key);
+insert into t1 values (NULL);
+drop table t1;
+create table t1 (word char(20) not null);
+load data infile '../../std_data/words.dat' into table t1 ignore 1 lines;
+select count(*) from t1;
+count(*)
+69
+drop table t1;
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
+master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)
+master-bin.000001 # Intvar 1 # INSERT_ID=1
+master-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL)
+master-bin.000001 # Query 1 # use `test`; drop table t1
+master-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)
+master-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581
+master-bin.000001 # Execute_load_query 1 # use `test`; load data infile '../../std_data/words.dat' into table t1 ignore 1 lines ;file_id=1
+master-bin.000001 # Query 1 # use `test`; drop table t1
+show binlog events from 102 limit 1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)
+show binlog events from 102 limit 2;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)
+master-bin.000001 # Intvar 1 # INSERT_ID=1
+show binlog events from 102 limit 2,1;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL)
+flush logs;
+create table t5 (a int);
+drop table t5;
+start slave;
+flush logs;
+stop slave;
+create table t1 (n int);
+insert into t1 values (1);
+drop table t1;
+show binlog events;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
+master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)
+master-bin.000001 # Intvar 1 # INSERT_ID=1
+master-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL)
+master-bin.000001 # Query 1 # use `test`; drop table t1
+master-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)
+master-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581
+master-bin.000001 # Execute_load_query 1 # use `test`; load data infile '../../std_data/words.dat' into table t1 ignore 1 lines ;file_id=1
+master-bin.000001 # Query 1 # use `test`; drop table t1
+master-bin.000001 # Rotate 1 # master-bin.000002;pos=4
+show binlog events in 'master-bin.000002';
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000002 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
+master-bin.000002 # Query 1 # use `test`; create table t5 (a int)
+master-bin.000002 # Query 1 # use `test`; drop table t5
+master-bin.000002 # Query 1 # use `test`; create table t1 (n int)
+master-bin.000002 # Query 1 # use `test`; insert into t1 values (1)
+master-bin.000002 # Query 1 # use `test`; drop table t1
+show binary logs;
+Log_name File_size
+master-bin.000001 1393
+master-bin.000002 514
+start slave;
+show binary logs;
+Log_name File_size
+slave-bin.000001 1563
+slave-bin.000002 352
+show binlog events in 'slave-bin.000001' from 4;
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000001 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4
+slave-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)
+slave-bin.000001 # Intvar 1 # INSERT_ID=1
+slave-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL)
+slave-bin.000001 # Query 1 # use `test`; drop table t1
+slave-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)
+slave-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581
+slave-bin.000001 # Execute_load_query 1 # use `test`; load data INFILE '../../var/tmp/SQL_LOAD-2-1-1.data' INTO table t1 ignore 1 lines ;file_id=1
+slave-bin.000001 # Query 1 # use `test`; drop table t1
+slave-bin.000001 # Query 1 # use `test`; create table t5 (a int)
+slave-bin.000001 # Query 1 # use `test`; drop table t5
+slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4
+show binlog events in 'slave-bin.000002' from 4;
+Log_name Pos Event_type Server_id End_log_pos Info
+slave-bin.000002 # Format_desc 2 # Server ver: VERSION, Binlog ver: 4
+slave-bin.000002 # Query 1 # use `test`; create table t1 (n int)
+slave-bin.000002 # Query 1 # use `test`; insert into t1 values (1)
+slave-bin.000002 # Query 1 # use `test`; drop table t1
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 514 # # master-bin.000002 Yes Yes # 0 0 514 # None 0 No #
+show binlog events in 'slave-bin.000005' from 4;
+ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log
diff --git a/mysql-test/r/rpl_stm_max_relay_size.result b/mysql-test/r/rpl_stm_max_relay_size.result
new file mode 100644
index 00000000000..1afbc406a8e
--- /dev/null
+++ b/mysql-test/r/rpl_stm_max_relay_size.result
@@ -0,0 +1,61 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+stop slave;
+create table t1 (a int);
+drop table t1;
+reset slave;
+set global max_binlog_size=8192;
+set global max_relay_log_size=8192-1;
+select @@global.max_relay_log_size;
+@@global.max_relay_log_size
+4096
+start slave;
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 72956 # # master-bin.000001 Yes Yes # 0 0 72956 # None 0 No #
+stop slave;
+reset slave;
+set global max_relay_log_size=(5*4096);
+select @@global.max_relay_log_size;
+@@global.max_relay_log_size
+20480
+start slave;
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 72956 # # master-bin.000001 Yes Yes # 0 0 72956 # None 0 No #
+stop slave;
+reset slave;
+set global max_relay_log_size=0;
+select @@global.max_relay_log_size;
+@@global.max_relay_log_size
+0
+start slave;
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 72956 # # master-bin.000001 Yes Yes # 0 0 72956 # None 0 No #
+stop slave;
+reset slave;
+flush logs;
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 4 # # No No # 0 0 0 # None 0 No #
+reset slave;
+start slave;
+flush logs;
+create table t1 (a int);
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73042 # # master-bin.000001 Yes Yes # 0 0 73042 # None 0 No #
+flush logs;
+drop table t1;
+show slave status;
+Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 73118 # # master-bin.000001 Yes Yes # 0 0 73118 # None 0 No #
+flush logs;
+show master status;
+File Position Binlog_Do_DB Binlog_Ignore_DB
+master-bin.000002 102 <Binlog_Ignore_DB>
diff --git a/mysql-test/r/rpl_multi_query.result b/mysql-test/r/rpl_stm_multi_query.result
index f2d8ea77536..bf914e6ce6c 100644
--- a/mysql-test/r/rpl_multi_query.result
+++ b/mysql-test/r/rpl_stm_multi_query.result
@@ -19,7 +19,7 @@ n
3
4
5
-show binlog events from 98;
+show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # drop database if exists mysqltest
master-bin.000001 # Query 1 # create database mysqltest
diff --git a/mysql-test/r/rpl_stm_mystery22.result b/mysql-test/r/rpl_stm_mystery22.result
new file mode 100644
index 00000000000..ea34b308ec2
--- /dev/null
+++ b/mysql-test/r/rpl_stm_mystery22.result
@@ -0,0 +1,31 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+create table t1(n int auto_increment primary key, s char(10));
+insert into t1 values (2,'old');
+insert into t1 values(NULL,'new');
+insert into t1 values(NULL,'new');
+select * from t1 order by n;
+n s
+1 new
+2 old
+delete from t1 where n = 2;
+start slave;
+stop slave;
+create table t2(n int);
+drop table t2;
+insert into t1 values(NULL,'new');
+set sql_log_bin=0;
+insert into t1 values(NULL,'new');
+set sql_log_bin=1;
+delete from t1 where n=4;
+start slave;
+select * from t1 order by n;
+n s
+1 new
+2 new
+3 new
+drop table t1;
diff --git a/mysql-test/r/rpl_delete_all.result b/mysql-test/r/rpl_stm_no_op.result
index 1aa556270c9..eb445085a1d 100644
--- a/mysql-test/r/rpl_delete_all.result
+++ b/mysql-test/r/rpl_stm_no_op.result
@@ -16,16 +16,37 @@ Warnings:
Note 1051 Unknown table 't1'
select * from t1;
ERROR 42S02: Table 'test.t1' doesn't exist
-create table t1 (a int);
-insert into t1 values(1);
+create table t1 (a int, b int);
+insert into t1 values(1,1);
delete from t1;
select * from t1;
-a
-insert into t1 values(1);
-insert into t1 values(2);
+a b
+insert into t1 values(1,1);
+insert into t1 values(2,1);
+update t1 set a=2;
+select * from t1;
+a b
+2 1
+2 1
+create table t2 (a int, b int);
+delete from t1;
+insert into t1 values(1,1);
+insert into t2 values(1,1);
update t1 set a=2;
+UPDATE t1, t2 SET t1.a = t2.a;
+select * from t1;
+a b
+1 1
+select * from t2;
+a b
+1 1
+delete from t1;
+delete from t2;
+insert into t1 values(1,1);
+insert into t2 values(1,1);
+DELETE t1.*, t2.* from t1, t2;
select * from t1;
-a
-2
-2
+a b
+select * from t2;
+a b
drop table t1;
diff --git a/mysql-test/r/rpl_reset_slave.result b/mysql-test/r/rpl_stm_reset_slave.result
index ab55423b773..834b9add089 100644
--- a/mysql-test/r/rpl_reset_slave.result
+++ b/mysql-test/r/rpl_stm_reset_slave.result
@@ -6,20 +6,20 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 98 # # master-bin.000001 Yes Yes 0 0 98 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 102 # # master-bin.000001 Yes Yes # 0 0 102 # None 0 No #
stop slave;
change master to master_user='test';
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 test MASTER_PORT 1 master-bin.000001 98 # # master-bin.000001 No No 0 0 98 # None 0 No #
+# 127.0.0.1 test MASTER_PORT 1 master-bin.000001 102 # # master-bin.000001 No No # 0 0 102 # None 0 No #
reset slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 4 # # No No 0 0 0 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 4 # # No No # 0 0 0 # None 0 No #
start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 98 # # master-bin.000001 Yes Yes 0 0 98 # None 0 No #
+# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 102 # # master-bin.000001 Yes Yes # 0 0 102 # None 0 No #
stop slave;
reset slave;
start slave;
diff --git a/mysql-test/r/rpl_stm_rewrt_db.result b/mysql-test/r/rpl_stm_rewrt_db.result
new file mode 100644
index 00000000000..6c72e982e3e
--- /dev/null
+++ b/mysql-test/r/rpl_stm_rewrt_db.result
@@ -0,0 +1,93 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+drop database if exists mysqltest1;
+create database mysqltest1;
+use mysqltest1;
+create table t1 (a int);
+insert into t1 values(9);
+select * from mysqltest1.t1;
+a
+9
+show databases like 'mysqltest1';
+Database (mysqltest1)
+mysqltest1
+select * from test.t1;
+a
+9
+drop table t1;
+drop database mysqltest1;
+drop database if exists rewrite;
+create database rewrite;
+use test;
+create table t1 (a date, b date, c date not null, d date);
+load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',';
+Warnings:
+Warning 1265 Data truncated for column 'a' at row 1
+Warning 1265 Data truncated for column 'c' at row 1
+Warning 1265 Data truncated for column 'd' at row 1
+Warning 1265 Data truncated for column 'a' at row 2
+Warning 1265 Data truncated for column 'b' at row 2
+Warning 1265 Data truncated for column 'd' at row 2
+load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' IGNORE 2 LINES;
+select * from rewrite.t1;
+a b c d
+0000-00-00 NULL 0000-00-00 0000-00-00
+0000-00-00 0000-00-00 0000-00-00 0000-00-00
+2003-03-03 2003-03-03 2003-03-03 NULL
+2003-03-03 2003-03-03 2003-03-03 NULL
+truncate table t1;
+load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' LINES STARTING BY ',' (b,c,d);
+Warnings:
+Warning 1265 Data truncated for column 'c' at row 1
+Warning 1265 Data truncated for column 'd' at row 1
+Warning 1265 Data truncated for column 'b' at row 2
+Warning 1265 Data truncated for column 'd' at row 2
+select * from rewrite.t1;
+a b c d
+NULL NULL 0000-00-00 0000-00-00
+NULL 0000-00-00 0000-00-00 0000-00-00
+NULL 2003-03-03 2003-03-03 NULL
+drop table t1;
+create table t1 (a text, b text);
+load data infile '../../std_data/loaddata2.dat' into table t1 fields terminated by ',' enclosed by '''';
+Warnings:
+Warning 1261 Row 3 doesn't contain data for all columns
+select concat('|',a,'|'), concat('|',b,'|') from rewrite.t1;
+concat('|',a,'|') concat('|',b,'|')
+|Field A| |Field B|
+|Field 1| |Field 2'
+Field 3,'Field 4|
+|Field 5' ,'Field 6| NULL
+|Field 6| | 'Field 7'|
+drop table t1;
+create table t1 (a int, b char(10));
+load data infile '../../std_data/loaddata3.dat' into table t1 fields terminated by '' enclosed by '' ignore 1 lines;
+Warnings:
+Warning 1264 Out of range value for column 'a' at row 3
+Warning 1262 Row 3 was truncated; it contained more data than there were input columns
+Warning 1264 Out of range value for column 'a' at row 5
+Warning 1262 Row 5 was truncated; it contained more data than there were input columns
+select * from rewrite.t1;
+a b
+1 row 1
+2 row 2
+0 1234567890
+3 row 3
+0 1234567890
+truncate table t1;
+load data infile '../../std_data/loaddata4.dat' into table t1 fields terminated by '' enclosed by '' lines terminated by '' ignore 1 lines;
+Warnings:
+Warning 1264 Out of range value for column 'a' at row 4
+Warning 1261 Row 4 doesn't contain data for all columns
+select * from rewrite.t1;
+a b
+1 row 1
+2 row 2
+3 row 3
+0
+drop database rewrite;
+drop table t1;
diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_stm_sp.result
index 41bcfc7d72c..4fe0f61b550 100644
--- a/mysql-test/r/rpl_sp.result
+++ b/mysql-test/r/rpl_stm_sp.result
@@ -261,7 +261,7 @@ insert into t1 values (1);
select * from t1;
a
1
-show binlog events in 'master-bin.000001' from 98;
+show binlog events in 'master-bin.000001' from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query 1 # drop database if exists mysqltest1
master-bin.000001 # Query 1 # create database mysqltest1
diff --git a/mysql-test/r/rpl_timezone.result b/mysql-test/r/rpl_stm_timezone.result
index 64d05aa787e..64d05aa787e 100644
--- a/mysql-test/r/rpl_timezone.result
+++ b/mysql-test/r/rpl_stm_timezone.result
diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_stm_until.result
index b584e04ed57..11b69f55f82 100644
--- a/mysql-test/r/rpl_until.result
+++ b/mysql-test/r/rpl_stm_until.result
@@ -12,17 +12,7 @@ create table t2(n int not null auto_increment primary key);
insert into t2 values (1),(2);
insert into t2 values (3),(4);
drop table t2;
-show binlog events;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 4 Format_desc 1 98 Server ver: VERSION, Binlog ver: 4
-master-bin.000001 98 Query 1 219 use `test`; create table t1(n int not null auto_increment primary key)
-master-bin.000001 219 Query 1 319 use `test`; insert into t1 values (1),(2),(3),(4)
-master-bin.000001 319 Query 1 395 use `test`; drop table t1
-master-bin.000001 395 Query 1 516 use `test`; create table t2(n int not null auto_increment primary key)
-master-bin.000001 516 Query 1 608 use `test`; insert into t2 values (1),(2)
-master-bin.000001 608 Query 1 700 use `test`; insert into t2 values (3),(4)
-master-bin.000001 700 Query 1 776 use `test`; drop table t2
-start slave until master_log_file='master-bin.000001', master_log_pos=319;
+start slave until master_log_file='master-bin.000001', master_log_pos=323;
select * from t1;
n
1
@@ -31,7 +21,7 @@ n
4
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 # No 0 0 319 # Master master-bin.000001 319 No #
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 780 slave-relay-bin.000004 # master-bin.000001 # No 0 0 323 # Master master-bin.000001 323 No #
start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
select * from t1;
n
@@ -41,7 +31,7 @@ n
4
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 # No 0 0 319 # Master master-no-such-bin.000001 291 No #
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 780 slave-relay-bin.000004 # master-bin.000001 # No 0 0 323 # Master master-no-such-bin.000001 291 No #
start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=746;
select * from t2;
n
@@ -49,13 +39,13 @@ n
2
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 # No 0 0 608 # Relay slave-relay-bin.000004 746 No #
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 780 slave-relay-bin.000004 # master-bin.000001 # No 0 0 612 # Relay slave-relay-bin.000004 746 No #
start slave;
stop slave;
start slave until master_log_file='master-bin.000001', master_log_pos=776;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 776 # Master master-bin.000001 776 No #
+# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 780 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 780 # Master master-bin.000001 776 No #
start slave until master_log_file='master-bin', master_log_pos=561;
ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL
start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12;
diff --git a/mysql-test/r/rpl_stm_user_variables.result b/mysql-test/r/rpl_stm_user_variables.result
new file mode 100644
index 00000000000..3e2efcbe9da
--- /dev/null
+++ b/mysql-test/r/rpl_stm_user_variables.result
@@ -0,0 +1,82 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+reset master;
+create table t1(n char(30));
+set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
+set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
+set @n1:=null;
+set @s2:='', @s3:='abc\'def', @s4:= 'abc\\def', @s5:= 'abc''def';
+insert into t1 values (@i1), (@i2), (@i3), (@i4);
+insert into t1 values (@r1), (@r2);
+insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5);
+insert into t1 values (@n1);
+insert into t1 values (@n2);
+insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1);
+insert into t1 values (@a+(@b:=@a+1));
+set @q:='abc';
+insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
+set @a:=5;
+insert into t1 values (@a),(@a);
+select * from t1 where n = '<nonexistant>';
+n
+insert into t1 values (@a),(@a),(@a*5);
+select * from t1;
+n
+12345678901234
+-12345678901234
+0
+-1
+12.5
+-12.5
+This is a test
+
+abc'def
+abc\def
+abc'def
+NULL
+NULL
+0
+1
+2
+5
+abc
+abcn1
+abcn1n2
+5
+5
+NULL
+NULL
+NULL
+select * from t1;
+n
+12345678901234
+-12345678901234
+0
+-1
+12.5
+-12.5
+This is a test
+
+abc'def
+abc\def
+abc'def
+NULL
+NULL
+0
+1
+2
+5
+abc
+abcn1
+abcn1n2
+5
+5
+NULL
+NULL
+NULL
+drop table t1;
+stop slave;
diff --git a/mysql-test/r/rpl_view.result b/mysql-test/r/rpl_stm_view.result
index cf4c161b296..cf4c161b296 100644
--- a/mysql-test/r/rpl_view.result
+++ b/mysql-test/r/rpl_stm_view.result
diff --git a/mysql-test/r/rpl_temporary.result b/mysql-test/r/rpl_temporary.result
index a76fb87a52b..a7dbfd44944 100644
--- a/mysql-test/r/rpl_temporary.result
+++ b/mysql-test/r/rpl_temporary.result
@@ -36,21 +36,6 @@ select * from t2;
f
5
7
-show binlog events;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Format_desc 1 # Server ver: VERSION, Binlog ver: 4
-master-bin.000001 # Query 1 # use `test`; drop table if exists t1,t2
-master-bin.000001 # Query 1 # use `test`; create table t1(f int)
-master-bin.000001 # Query 1 # use `test`; create table t2(f int)
-master-bin.000001 # Query 1 # use `test`; insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)
-master-bin.000001 # Query 1 # use `test`; create temporary table t3(f int)
-master-bin.000001 # Query 1 # use `test`; insert into t3 select * from t1 where f<6
-master-bin.000001 # Query 1 # use `test`; create temporary table t3(f int)
-master-bin.000001 # Query 1 # use `test`; insert into t2 select count(*) from t3
-master-bin.000001 # Query 1 # use `test`; insert into t3 select * from t1 where f>=4
-master-bin.000001 # Query 1 # use `test`; drop temporary table t3
-master-bin.000001 # Query 1 # use `test`; insert into t2 select count(*) from t3
-master-bin.000001 # Query 1 # use `test`; drop temporary table t3
drop table t1, t2;
use test;
SET TIMESTAMP=1040323920;
diff --git a/mysql-test/r/rpl_user_variables.result b/mysql-test/r/rpl_user_variables.result
deleted file mode 100644
index 4198bbcc154..00000000000
--- a/mysql-test/r/rpl_user_variables.result
+++ /dev/null
@@ -1,110 +0,0 @@
-stop slave;
-drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
-reset master;
-reset slave;
-drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
-start slave;
-reset master;
-create table t1(n char(30));
-set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
-set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
-set @n1:=null;
-set @s2:='', @s3:='abc\'def', @s4:= 'abc\\def', @s5:= 'abc''def';
-insert into t1 values (@i1), (@i2), (@i3), (@i4);
-insert into t1 values (@r1), (@r2);
-insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5);
-insert into t1 values (@n1);
-insert into t1 values (@n2);
-insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1);
-insert into t1 values (@a+(@b:=@a+1));
-set @q:='abc';
-insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
-set @a:=5;
-insert into t1 values (@a),(@a);
-insert into t1 values (@a),(@a),(@a*5);
-select * from t1;
-n
-12345678901234
--12345678901234
-0
--1
-12.5
--12.5
-This is a test
-
-abc'def
-abc\def
-abc'def
-NULL
-NULL
-0
-1
-2
-5
-abc
-abcn1
-abcn1n2
-5
-5
-NULL
-NULL
-NULL
-select * from t1;
-n
-12345678901234
--12345678901234
-0
--1
-12.5
--12.5
-This is a test
-
-abc'def
-abc\def
-abc'def
-NULL
-NULL
-0
-1
-2
-5
-abc
-abcn1
-abcn1n2
-5
-5
-NULL
-NULL
-NULL
-show binlog events from 98;
-Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000001 # Query 1 # use `test`; create table t1(n char(30))
-slave-bin.000001 # User var 2 # @`i1`=12345678901234
-slave-bin.000001 # User var 2 # @`i2`=-12345678901234
-slave-bin.000001 # User var 2 # @`i3`=0
-slave-bin.000001 # User var 2 # @`i4`=-1
-slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@i1), (@i2), (@i3), (@i4)
-slave-bin.000001 # User var 2 # @`r1`=12.5
-slave-bin.000001 # User var 2 # @`r2`=-12.5
-slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@r1), (@r2)
-slave-bin.000001 # User var 2 # @`s1`=_latin1 0x5468697320697320612074657374 COLLATE latin1_swedish_ci
-slave-bin.000001 # User var 2 # @`s2`=_latin1 "" COLLATE latin1_swedish_ci
-slave-bin.000001 # User var 2 # @`s3`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci
-slave-bin.000001 # User var 2 # @`s4`=_latin1 0x6162635C646566 COLLATE latin1_swedish_ci
-slave-bin.000001 # User var 2 # @`s5`=_latin1 0x61626327646566 COLLATE latin1_swedish_ci
-slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5)
-slave-bin.000001 # User var 2 # @`n1`=NULL
-slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@n1)
-slave-bin.000001 # User var 2 # @`n2`=NULL
-slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@n2)
-slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1)
-slave-bin.000001 # User var 2 # @`a`=2
-slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a+(@b:=@a+1))
-slave-bin.000001 # User var 2 # @`q`=_latin1 0x616263 COLLATE latin1_swedish_ci
-slave-bin.000001 # Query 1 # use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'))
-slave-bin.000001 # User var 2 # @`a`=5
-slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a),(@a)
-slave-bin.000001 # User var 2 # @`a`=NULL
-slave-bin.000001 # Query 1 # use `test`; insert into t1 values (@a),(@a),(@a*5)
-drop table t1;
-stop slave;
diff --git a/mysql-test/r/user_var-binlog.result b/mysql-test/r/user_var-binlog.result
index 700ec7b09e0..a77ec20a402 100644
--- a/mysql-test/r/user_var-binlog.result
+++ b/mysql-test/r/user_var-binlog.result
@@ -6,13 +6,13 @@ INSERT INTO t1 VALUES(@`a b`);
set @var1= "';aaa";
SET @var2=char(ascii('a'));
insert into t1 values (@var1),(@var2);
-show binlog events from 98;
+show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 User var 1 139 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci
-master-bin.000001 139 Query 1 231 use `test`; INSERT INTO t1 VALUES(@`a b`)
-master-bin.000001 231 User var 1 273 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci
-master-bin.000001 273 User var 1 311 @`var2`=_binary 0x61 COLLATE binary
-master-bin.000001 311 Query 1 411 use `test`; insert into t1 values (@var1),(@var2)
+master-bin.000001 # User var 1 # @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci
+master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES(@`a b`)
+master-bin.000001 # User var 1 # @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci
+master-bin.000001 # User var 1 # @`var2`=_binary 0x61 COLLATE binary
+master-bin.000001 # Query 1 # use `test`; insert into t1 values (@var1),(@var2)
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
ROLLBACK;
diff --git a/mysql-test/std_data/rpl_timezone2.dat b/mysql-test/std_data/rpl_timezone2.dat
new file mode 100644
index 00000000000..9faeed4b207
--- /dev/null
+++ b/mysql-test/std_data/rpl_timezone2.dat
@@ -0,0 +1,2 @@
+20040101000000,NULL
+20040611093902,NULL
diff --git a/mysql-test/std_data/words2.dat b/mysql-test/std_data/words2.dat
new file mode 100644
index 00000000000..dd52469f8e8
--- /dev/null
+++ b/mysql-test/std_data/words2.dat
@@ -0,0 +1,50 @@
+abase
+abased
+abasement
+abasements
+abases
+abash
+abashed
+abashes
+abashing
+abasing
+abate
+abated
+abatement
+abatements
+abater
+abates
+abating
+Abba
+abbe
+abbey
+abbeys
+abbot
+abbots
+Abbott
+abbreviate
+abbreviated
+abbreviates
+abbreviating
+abbreviation
+abbreviations
+Abby
+abdomen
+abdomens
+abdominal
+abduct
+abducted
+abduction
+abductions
+abductor
+abductors
+abducts
+Abe
+abed
+Abel
+Abelian
+Abelson
+Aberdeen
+Abernathy
+aberrant
+aberration
diff --git a/mysql-test/t/binlog-master.opt b/mysql-test/t/binlog_row_binlog-master.opt
index ad2c6a647b5..ad2c6a647b5 100644
--- a/mysql-test/t/binlog-master.opt
+++ b/mysql-test/t/binlog_row_binlog-master.opt
diff --git a/mysql-test/t/binlog_row_binlog.test b/mysql-test/t/binlog_row_binlog.test
new file mode 100644
index 00000000000..8adc8eee5c1
--- /dev/null
+++ b/mysql-test/t/binlog_row_binlog.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_row.inc
+-- source extra/binlog_tests/binlog.test
diff --git a/mysql-test/t/binlog_row_blackhole.test b/mysql-test/t/binlog_row_blackhole.test
new file mode 100644
index 00000000000..5bf1efb1ecb
--- /dev/null
+++ b/mysql-test/t/binlog_row_blackhole.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_row.inc
+-- source extra/binlog_tests/blackhole.test
diff --git a/mysql-test/t/binlog_row_ctype_cp932.test b/mysql-test/t/binlog_row_ctype_cp932.test
new file mode 100644
index 00000000000..595af5a3114
--- /dev/null
+++ b/mysql-test/t/binlog_row_ctype_cp932.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_row.inc
+-- source extra/binlog_tests/ctype_cp932.test
diff --git a/mysql-test/t/binlog_row_ctype_ucs.test b/mysql-test/t/binlog_row_ctype_ucs.test
new file mode 100644
index 00000000000..96e14ed8882
--- /dev/null
+++ b/mysql-test/t/binlog_row_ctype_ucs.test
@@ -0,0 +1,6 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_row.inc
+-- source extra/binlog_tests/ctype_ucs_binlog.test
+
diff --git a/mysql-test/t/binlog_row_drop_tmp_tbl.test b/mysql-test/t/binlog_row_drop_tmp_tbl.test
new file mode 100644
index 00000000000..5b503b78d85
--- /dev/null
+++ b/mysql-test/t/binlog_row_drop_tmp_tbl.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_row.inc
+-- source extra/binlog_tests/drop_temp_table.test
diff --git a/mysql-test/t/binlog_row_innodb_stat.test b/mysql-test/t/binlog_row_innodb_stat.test
new file mode 100644
index 00000000000..e4e6762226b
--- /dev/null
+++ b/mysql-test/t/binlog_row_innodb_stat.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_row.inc
+-- source extra/binlog_tests/innodb_stat.test
diff --git a/mysql-test/t/binlog_row_insert_select.test b/mysql-test/t/binlog_row_insert_select.test
new file mode 100644
index 00000000000..780dfb75293
--- /dev/null
+++ b/mysql-test/t/binlog_row_insert_select.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_row.inc
+-- source extra/binlog_tests/insert_select-binlog.test
diff --git a/mysql-test/t/binlog_row_mix_innodb_myisam.test b/mysql-test/t/binlog_row_mix_innodb_myisam.test
new file mode 100644
index 00000000000..7986467e5e5
--- /dev/null
+++ b/mysql-test/t/binlog_row_mix_innodb_myisam.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_row.inc
+-- source extra/binlog_tests/mix_innodb_myisam_binlog.test
diff --git a/mysql-test/t/binlog_stm_binlog-master.opt b/mysql-test/t/binlog_stm_binlog-master.opt
new file mode 100644
index 00000000000..ad2c6a647b5
--- /dev/null
+++ b/mysql-test/t/binlog_stm_binlog-master.opt
@@ -0,0 +1 @@
+-O max_binlog_size=4096
diff --git a/mysql-test/t/binlog_stm_binlog.test b/mysql-test/t/binlog_stm_binlog.test
new file mode 100644
index 00000000000..da93d86c7ce
--- /dev/null
+++ b/mysql-test/t/binlog_stm_binlog.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_statement.inc
+-- source extra/binlog_tests/binlog.test
diff --git a/mysql-test/t/binlog_stm_blackhole.test b/mysql-test/t/binlog_stm_blackhole.test
new file mode 100644
index 00000000000..3c0096fa3f6
--- /dev/null
+++ b/mysql-test/t/binlog_stm_blackhole.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_statement.inc
+-- source extra/binlog_tests/blackhole.test
diff --git a/mysql-test/t/binlog_stm_ctype_cp932.test b/mysql-test/t/binlog_stm_ctype_cp932.test
new file mode 100644
index 00000000000..cef179e0028
--- /dev/null
+++ b/mysql-test/t/binlog_stm_ctype_cp932.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_statement.inc
+-- source extra/binlog_tests/ctype_cp932.test
diff --git a/mysql-test/t/binlog_stm_ctype_ucs.test b/mysql-test/t/binlog_stm_ctype_ucs.test
new file mode 100644
index 00000000000..a32ac3155c7
--- /dev/null
+++ b/mysql-test/t/binlog_stm_ctype_ucs.test
@@ -0,0 +1,6 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_statement.inc
+-- source extra/binlog_tests/ctype_ucs_binlog.test
+
diff --git a/mysql-test/t/binlog_stm_drop_tmp_tbl.test b/mysql-test/t/binlog_stm_drop_tmp_tbl.test
new file mode 100644
index 00000000000..e8acd00c779
--- /dev/null
+++ b/mysql-test/t/binlog_stm_drop_tmp_tbl.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_statement.inc
+-- source extra/binlog_tests/drop_temp_table.test
diff --git a/mysql-test/t/binlog_stm_innodb_stat-master.opt b/mysql-test/t/binlog_stm_innodb_stat-master.opt
new file mode 100644
index 00000000000..4cb927540bf
--- /dev/null
+++ b/mysql-test/t/binlog_stm_innodb_stat-master.opt
@@ -0,0 +1 @@
+--binlog_cache_size=32768
diff --git a/mysql-test/t/binlog_stm_innodb_stat.test b/mysql-test/t/binlog_stm_innodb_stat.test
new file mode 100644
index 00000000000..c6017246e6d
--- /dev/null
+++ b/mysql-test/t/binlog_stm_innodb_stat.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_statement.inc
+-- source extra/binlog_tests/innodb_stat.test
diff --git a/mysql-test/t/binlog_stm_insert_select.test b/mysql-test/t/binlog_stm_insert_select.test
new file mode 100644
index 00000000000..06792990a55
--- /dev/null
+++ b/mysql-test/t/binlog_stm_insert_select.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_statement.inc
+-- source extra/binlog_tests/insert_select-binlog.test
diff --git a/mysql-test/t/binlog_stm_mix_innodb_myisam.test b/mysql-test/t/binlog_stm_mix_innodb_myisam.test
new file mode 100644
index 00000000000..2e096aebe1e
--- /dev/null
+++ b/mysql-test/t/binlog_stm_mix_innodb_myisam.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 9/19/2005 [jbm]
+
+-- source include/have_binlog_format_statement.inc
+-- source extra/binlog_tests/mix_innodb_myisam_binlog.test
diff --git a/mysql-test/t/create_select_tmp.test b/mysql-test/t/create_select_tmp.test
index 1661a115f72..dad83942806 100644
--- a/mysql-test/t/create_select_tmp.test
+++ b/mysql-test/t/create_select_tmp.test
@@ -5,6 +5,9 @@
# binlog if it was a transactional table, it resulted in an
# inconsistency between binlog and the internal list of temp tables.
+# This does not work for RBR yet.
+--source include/have_binlog_format_statement.inc
+
-- source include/have_innodb.inc
--disable_warnings
drop table if exists t1, t2;
diff --git a/mysql-test/t/ctype_cp932_binlog_row.test b/mysql-test/t/ctype_cp932_binlog_row.test
new file mode 100644
index 00000000000..38614ea45c0
--- /dev/null
+++ b/mysql-test/t/ctype_cp932_binlog_row.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 11/07/2005 [jbm]
+
+-- source include/have_binlog_format_row.inc
+-- source extra/binlog_tests/ctype_cp932_binlog.test
diff --git a/mysql-test/t/ctype_cp932_binlog_stm.test b/mysql-test/t/ctype_cp932_binlog_stm.test
new file mode 100644
index 00000000000..83a9ec59000
--- /dev/null
+++ b/mysql-test/t/ctype_cp932_binlog_stm.test
@@ -0,0 +1,5 @@
+# This is a wrapper for binlog.test so that the same test case can be used
+# For both statement and row based bin logs 11/07/2005 [jbm]
+
+-- source include/have_binlog_format_statement.inc
+-- source extra/binlog_tests/ctype_cp932_binlog.test
diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test
index c007c2f5205..88106ae6956 100644
--- a/mysql-test/t/date_formats.test
+++ b/mysql-test/t/date_formats.test
@@ -6,7 +6,9 @@
drop table if exists t1;
--enable_warnings
+--replace_result ROW <format> STATEMENT <format>
SHOW GLOBAL VARIABLES LIKE "%_format%";
+--replace_result ROW <format> STATEMENT <format>
SHOW SESSION VARIABLES LIKE "%_format%";
#
@@ -34,6 +36,7 @@ set datetime_format= '%H:%i:%s.%f %m-%d-%Y';
set datetime_format= '%h:%i:%s %p %Y-%m-%d';
set datetime_format= '%h:%i:%s.%f %p %Y-%m-%d';
+--replace_result ROW <format> STATEMENT <format>
SHOW SESSION VARIABLES LIKE "%format";
--error 1231
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 9cfb69ecd8f..f32ed667864 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -6,16 +6,22 @@
#
# <testcasename> : Comment test
#
-# Don't use any TAB characters for whitespace.
+# Do not use any TAB characters for whitespace.
#
##############################################################################
sp-goto : GOTO is currently is disabled - will be fixed in the future
kill : Unstable test case, bug#9712
-ndb_cache2 : Bug#15004
-ndb_cache_multi2: Bug#15004
-func_group : Bug#15448
-func_math : Bug#15448
-group_min_max : Bug#15448
+rpl_bit_npk : Bug #13418
+ndb_cache2 : Bug #15004
+ndb_cache_multi2: Bug #15004
+func_group : Bug #15448
+func_math : Bug #15448
+group_min_max : Bug #15448
+#mysqlslap : Bug #15483
+innodb_concurrent : Results are not deterministic, Elliot will fix (BUG#3300)
subselect : Bug#15706
type_time : Bug#15805
+rpl000002 : Bug#15920 Temporary tables are not binlogged in SBR
+ps_7ndb : Bug#15923 Core dump in RBR mode when executing test suite
+sp_trans : Bug#15924 Code dump in RBR mode when executing test suite
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 4b97f27ebe6..71b92c419ca 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -1142,40 +1142,6 @@ drop table t2, t1;
#
-# Let us test binlog_cache_use and binlog_cache_disk_use status vars.
-# Actually this test has nothing to do with innodb per se, it just requires
-# transactional table.
-#
-show status like "binlog_cache_use";
-show status like "binlog_cache_disk_use";
-
-create table t1 (a int) engine=innodb;
-
-# Now we are going to create transaction which is long enough so its
-# transaction binlog will be flushed to disk...
-let $1=2000;
-disable_query_log;
-begin;
-while ($1)
-{
- eval insert into t1 values( $1 );
- dec $1;
-}
-commit;
-enable_query_log;
-show status like "binlog_cache_use";
-show status like "binlog_cache_disk_use";
-
-# Transaction which should not be flushed to disk and so should not
-# increase binlog_cache_disk_use.
-begin;
-delete from t1;
-commit;
-show status like "binlog_cache_use";
-show status like "binlog_cache_disk_use";
-drop table t1;
-
-#
# Bug #6126: Duplicate columns in keys gives misleading error message
#
--error 1060
@@ -1289,15 +1255,6 @@ select * from t1 where x > -16;
select count(*) from t1 where x = 18446744073709551601;
drop table t1;
-
-# Test for testable InnoDB status variables. This test
-# uses previous ones(pages_created, rows_deleted, ...).
-show status like "Innodb_buffer_pool_pages_total";
-show status like "Innodb_page_size";
-show status like "Innodb_rows_deleted";
-show status like "Innodb_rows_inserted";
-show status like "Innodb_rows_updated";
-
# Test for row locks InnoDB status variables.
show status like "Innodb_row_lock_waits";
show status like "Innodb_row_lock_current_waits";
diff --git a/mysql-test/t/innodb_concurrent-master.opt b/mysql-test/t/innodb_concurrent-master.opt
new file mode 100644
index 00000000000..f76bada5208
--- /dev/null
+++ b/mysql-test/t/innodb_concurrent-master.opt
@@ -0,0 +1 @@
+--innodb_locks_unsafe_for_binlog
diff --git a/mysql-test/t/innodb_concurrent.test b/mysql-test/t/innodb_concurrent.test
new file mode 100644
index 00000000000..1595fcd2467
--- /dev/null
+++ b/mysql-test/t/innodb_concurrent.test
@@ -0,0 +1,346 @@
+#
+# Concurrent InnoDB tests, mainly in UPDATE's
+# Bug#3300
+# Designed and tested by Sinisa Milivojevic, sinisa@mysql.com
+#
+# two non-interfering UPDATE's not changing result set
+#
+
+# test takes circa 5 minutes to run, so it's big
+-- source include/big_test.inc
+
+connection default;
+drop table if exists t1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+connect (thread1, localhost, mysqltest,,);
+connection thread1;
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",1);
+connect (thread2, localhost, mysqltest,,);
+connection thread2;
+begin;
+send update t1 set eta=1+get_lock("hello",1)*0 where tipo=11;
+sleep 1;
+connection thread1;
+begin;
+update t1 set eta=2 where tipo=22;
+select release_lock("hello");
+select * from t1;
+connection thread2;
+reap;
+select * from t1;
+send commit;
+connection thread1;
+select * from t1;
+commit;
+select * from t1;
+connection thread2;
+reap;
+select * from t1;
+connection thread1;
+select * from t1;
+connection default;
+drop table t1;
+
+#
+# two UPDATE's running and one changing result set
+#
+#connect (thread1, localhost, mysqltest,,);
+connection thread1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",10);
+#connect (thread2, localhost, mysqltest,,);
+connection thread2;
+begin;
+send update t1 set eta=1+get_lock("hello",10)*0 where tipo=1;
+sleep 1;
+connection thread1;
+begin;
+update t1 set tipo=1 where tipo=2;
+select release_lock("hello");
+select * from t1;
+connection thread2;
+reap;
+select * from t1;
+send commit;
+connection thread1;
+select * from t1;
+commit;
+select * from t1;
+connection thread2;
+reap;
+select * from t1;
+connection thread1;
+select * from t1;
+connection default;
+drop table t1;
+
+
+#
+# One UPDATE and one INSERT .... Monty's test
+#
+
+#connect (thread1, localhost, mysqltest,,);
+connection thread1;
+create table t1 (a int not null, b int not null) engine=innodb;
+insert into t1 values (1,1),(2,1),(3,1),(4,1);
+select get_lock("hello2",1000);
+#connect (thread2, localhost, mysqltest,,);
+connection thread2;
+begin;
+send update t1 set b=10+get_lock(concat("hello",a),1000)*0 where
+a=2;
+sleep 1;
+connection thread1;
+insert into t1 values (1,1);
+select release_lock("hello2");
+select * from t1;
+connection thread2;
+reap;
+select * from t1;
+send commit;
+connection thread1;
+sleep 1;
+connection thread2;
+reap;
+connection default;
+drop table t1;
+
+#
+# one UPDATE changing result set and SELECT ... FOR UPDATE
+#
+#connect (thread1, localhost, mysqltest,,);
+connection thread1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",10);
+#connect (thread2, localhost, mysqltest,,);
+connection thread2;
+begin;
+send select * from t1 where tipo=2 FOR UPDATE;
+sleep 1;
+connection thread1;
+begin;
+select release_lock("hello");
+--error 1205
+update t1 set tipo=1+get_lock("hello",10)*0 where tipo=2;
+select * from t1;
+connection thread2;
+reap;
+select * from t1;
+send commit;
+connection thread1;
+commit;
+connection thread2;
+reap;
+select * from t1;
+connection thread1;
+select * from t1;
+connection default;
+drop table t1;
+
+#
+# one UPDATE not changing result set and SELECT ... FOR UPDATE
+#
+#connect (thread1, localhost, mysqltest,,);
+connection thread1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",10);
+#connect (thread2, localhost, mysqltest,,);
+connection thread2;
+begin;
+send select * from t1 where tipo=2 FOR UPDATE;
+sleep 1;
+connection thread1;
+begin;
+select release_lock("hello");
+--error 1205
+update t1 set tipo=11+get_lock("hello",10)*0 where tipo=22;
+select * from t1;
+connection thread2;
+reap;
+select * from t1;
+send commit;
+connection thread1;
+commit;
+connection thread2;
+reap;
+select * from t1;
+connection thread1;
+select * from t1;
+connection default;
+drop table t1;
+
+#
+# two SELECT ... FOR UPDATE
+#
+#connect (thread1, localhost, mysqltest,,);
+connection thread1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",10);
+#connect (thread2, localhost, mysqltest,,);
+connection thread2;
+begin;
+send select * from t1 where tipo=2 FOR UPDATE;
+sleep 1;
+connection thread1;
+begin;
+select release_lock("hello");
+--error 1205
+select * from t1 where tipo=1 FOR UPDATE;
+connection thread2;
+reap;
+select * from t1;
+send commit;
+connection thread1;
+commit;
+connection thread2;
+reap;
+select * from t1;
+connection thread1;
+select * from t1;
+connection default;
+drop table t1;
+
+
+#
+# one UPDATE changing result set and DELETE
+#
+#connect (thread1, localhost, mysqltest,,);
+connection thread1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",10);
+#connect (thread2, localhost, mysqltest,,);
+connection thread2;
+begin;
+send delete from t1 where tipo=2;
+sleep 1;
+connection thread1;
+begin;
+select release_lock("hello");
+--error 1205
+update t1 set tipo=1+get_lock("hello",10)*0 where tipo=2;
+select * from t1;
+connection thread2;
+reap;
+select * from t1;
+send commit;
+connection thread1;
+commit;
+connection thread2;
+reap;
+select * from t1;
+connection thread1;
+select * from t1;
+connection default;
+drop table t1;
+
+
+#
+# one UPDATE not changing result set and DELETE
+#
+#connect (thread1, localhost, mysqltest,,);
+connection thread1;
+create table t1(eta int(11) not null, tipo int(11), c varchar(255)) type=innodb;
+insert into t1 values (7,7, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+insert into t1 values (8,8, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
+insert into t1 values (10,1,"ccccccccccccccccccccccccccccccccccccccccccc");
+insert into t1 values (20,2,"ddddddddddddddddddddddddddddddddddddddddddd");
+insert into t1 values (30,1,"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
+insert into t1 values (40,2,"fffffffffffffffffffffffffffffffffffffffffff");
+insert into t1 values (50,1,"ggggggggggggggggggggggggggggggggggggggggggg");
+insert into t1 values (60,2,"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
+insert into t1 values (70,1,"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");
+insert into t1 values (80,22,"jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj");
+insert into t1 values (90,11,"kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk");
+select get_lock("hello",10);
+#connect (thread2, localhost, mysqltest,,);
+connection thread2;
+begin;
+send delete from t1 where tipo=2;
+sleep 1;
+connection thread1;
+begin;
+select release_lock("hello");
+update t1 set tipo=1+get_lock("hello",10)*0 where tipo=22;
+select * from t1;
+connection thread2;
+reap;
+select * from t1;
+send commit;
+connection thread1;
+commit;
+connection thread2;
+reap;
+select * from t1;
+connection thread1;
+select * from t1;
+connection default;
+sleep 1;
+drop table t1;
+disconnect thread1;
+disconnect thread2;
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
index 61d7d9994ba..30af9fd8126 100644
--- a/mysql-test/t/mysqlbinlog.test
+++ b/mysql-test/t/mysqlbinlog.test
@@ -1,4 +1,6 @@
# We are using .opt file since we need small binlog size
+# TODO: Need to look at making a row based version once the new row based client is completed. [jbm]
+-- source include/have_binlog_format_statement.inc
# Embedded server doesn't support binlogging
-- source include/not_embedded.inc
@@ -63,7 +65,7 @@ select "--- --database --" as "";
select "--- --position --" as "";
--enable_query_log
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --position=231 $MYSQL_TEST_DIR/var/log/master-bin.000002
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --position=235 $MYSQL_TEST_DIR/var/log/master-bin.000002
# These are tests for remote binlog.
# They should return the same as previous test.
@@ -95,7 +97,7 @@ select "--- --database --" as "";
select "--- --position --" as "";
--enable_query_log
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
---exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --position=231 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
+--exec $MYSQL_BINLOG --short-form --local-load=$MYSQL_TEST_DIR/var/tmp/ --read-from-remote-server --position=235 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002
# Bug#7853 (mysqlbinlog does not accept input from stdin)
--disable_query_log
diff --git a/mysql-test/t/mysqlbinlog2.test b/mysql-test/t/mysqlbinlog2.test
index a2f1aba05b0..89af8e33a03 100644
--- a/mysql-test/t/mysqlbinlog2.test
+++ b/mysql-test/t/mysqlbinlog2.test
@@ -1,6 +1,9 @@
# Test for the new options --start-datetime, stop-datetime,
# and a few others.
+# TODO: Need to look at making row based version once new binlog client is complete.
+-- source include/have_binlog_format_statement.inc
+
# Embedded server doesn't support binlogging
-- source include/not_embedded.inc
@@ -49,11 +52,11 @@ select "--- offset --" as "";
--disable_query_log
select "--- start-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=600 $MYSQL_TEST_DIR/var/log/master-bin.000001
+--exec $MYSQL_BINLOG --short-form --start-position=604 $MYSQL_TEST_DIR/var/log/master-bin.000001
--disable_query_log
select "--- stop-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --stop-position=600 $MYSQL_TEST_DIR/var/log/master-bin.000001
+--exec $MYSQL_BINLOG --short-form --stop-position=604 $MYSQL_TEST_DIR/var/log/master-bin.000001
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
@@ -78,11 +81,11 @@ select "--- offset --" as "";
--disable_query_log
select "--- start-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=600 $MYSQL_TEST_DIR/var/log/master-bin.000001 $MYSQL_TEST_DIR/var/log/master-bin.000002
+--exec $MYSQL_BINLOG --short-form --start-position=604 $MYSQL_TEST_DIR/var/log/master-bin.000001 $MYSQL_TEST_DIR/var/log/master-bin.000002
--disable_query_log
select "--- stop-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --stop-position=126 $MYSQL_TEST_DIR/var/log/master-bin.000001 $MYSQL_TEST_DIR/var/log/master-bin.000002
+--exec $MYSQL_BINLOG --short-form --stop-position=130 $MYSQL_TEST_DIR/var/log/master-bin.000001 $MYSQL_TEST_DIR/var/log/master-bin.000002
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
@@ -105,11 +108,11 @@ select "--- offset --" as "";
--disable_query_log
select "--- start-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=600 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
+--exec $MYSQL_BINLOG --short-form --start-position=604 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
--disable_query_log
select "--- stop-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --stop-position=600 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
+--exec $MYSQL_BINLOG --short-form --stop-position=604 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
@@ -132,11 +135,11 @@ select "--- offset --" as "";
--disable_query_log
select "--- start-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --start-position=600 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
+--exec $MYSQL_BINLOG --short-form --start-position=604 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
--disable_query_log
select "--- stop-position --" as "";
--enable_query_log
---exec $MYSQL_BINLOG --short-form --stop-position=126 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
+--exec $MYSQL_BINLOG --short-form --stop-position=130 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001 master-bin.000002
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
diff --git a/mysql-test/t/mysqlbinlog_base64.test b/mysql-test/t/mysqlbinlog_base64.test
new file mode 100644
index 00000000000..3aab767f9fa
--- /dev/null
+++ b/mysql-test/t/mysqlbinlog_base64.test
@@ -0,0 +1,38 @@
+-- source include/have_binlog_format_row.inc
+#
+# Write different events to binlog
+#
+create table t1 (a int);
+insert into t1 values (1);
+insert into t1 values (2);
+insert into t1 values (3);
+update t1 set a=a+2 where a=2;
+update t1 set a=a+2 where a=3;
+
+create table t2 (word varchar(20));
+load data infile '../../std_data/words.dat' into table t2;
+
+#
+# Save binlog
+#
+--exec $MYSQL_BINLOG --hexdump $MYSQL_TEST_DIR/var/log/master-bin.000001 > $MYSQL_TEST_DIR/var/tmp/mysqlbinlog_base64.sql
+
+#
+# Clear database and restore from binlog
+#
+drop table t1;
+drop table t2;
+--exec $MYSQL test < $MYSQL_TEST_DIR/var/tmp/mysqlbinlog_base64.sql
+
+#
+# Verify that all binlog events have been executed
+#
+select * from t1;
+select * from t2;
+
+#
+# Test cleanup
+#
+--exec rm $MYSQL_TEST_DIR/var/tmp/mysqlbinlog_base64.sql
+drop table t1;
+drop table t2;
diff --git a/mysql-test/t/rpl000002.test b/mysql-test/t/rpl000002.test
index bafd8a30159..5b9ed6898b8 100644
--- a/mysql-test/t/rpl000002.test
+++ b/mysql-test/t/rpl000002.test
@@ -1,3 +1,8 @@
+# Mixed DDL-DML (CREATE ... SELECT ...) statements can only be
+# replicated properly in statement-based replication.
+# Currently statement based due to bug 12345
+--source include/have_binlog_format_statement.inc
+
source include/master-slave.inc;
# Test replication of auto_increment
diff --git a/mysql-test/t/rpl000006.test b/mysql-test/t/rpl000006.test
index 334ed575835..bca97391f8e 100644
--- a/mysql-test/t/rpl000006.test
+++ b/mysql-test/t/rpl000006.test
@@ -1,47 +1,2 @@
-#
-# Test forced timestamp
-#
-source include/master-slave.inc;
-
-# Don't log table creating to the slave as we want to test LOAD TABLE
-set SQL_LOG_BIN=0,timestamp=200006;
-create table t1(t timestamp not null,a char(1));
-insert into t1 ( a) values ('F');
-select unix_timestamp(t) from t1;
-connection slave;
-load table t1 from master;
-select unix_timestamp(t) from t1;
-
-# Delete the created table on master and slave
-connection master;
-set SQL_LOG_BIN=1,timestamp=default;
-drop table t1;
-save_master_pos;
-connection slave;
-sync_with_master;
-connection master;
-
-#
-# Test copying table with checksum
-#
-
-# Don't log table creating to the slave as we want to test LOAD TABLE
-set SQL_LOG_BIN=0;
-
-CREATE TABLE t1 (
- a int not null
-) ENGINE=MyISAM MAX_ROWS=4000 CHECKSUM=1;
-INSERT INTO t1 VALUES (1);
-save_master_pos;
-connection slave;
-sync_with_master;
-load table t1 from master;
-check table t1;
-drop table t1;
-connection master;
-drop table t1;
-save_master_pos;
-connection slave;
-sync_with_master;
-
-# End of 4.1 tests
+let $engine_type=MyISAM;
+-- source extra/rpl_tests/rpl000006.test
diff --git a/mysql-test/t/rpl000013-slave.opt b/mysql-test/t/rpl000013-slave.opt
deleted file mode 100644
index 2662c695b41..00000000000
--- a/mysql-test/t/rpl000013-slave.opt
+++ /dev/null
@@ -1 +0,0 @@
---abort-slave-event-count=1
diff --git a/mysql-test/t/rpl000013.test b/mysql-test/t/rpl000013.test
index eca4803c6bc..c681e76cf51 100644
--- a/mysql-test/t/rpl000013.test
+++ b/mysql-test/t/rpl000013.test
@@ -1,3 +1,13 @@
+# This test is to verify that DROP TEMPORARY TABLE
+# is automatically binlogged and sent to slave
+# when a temp table is dropped by disconnection
+# of a master's conection.
+# So it does not apply to row-based, where we neither need
+# nor do this automatic binlogging. And if we run this test
+# in row-based, it hangs waiting for an offset which is never
+# reached (the "sync_with_master 1"), logically.
+
+--source include/have_binlog_format_statement.inc
source include/master-slave.inc;
save_master_pos;
connection slave;
diff --git a/mysql-test/t/rpl000017.test b/mysql-test/t/rpl000017.test
index 3b4574e9547..792801dd3d2 100644
--- a/mysql-test/t/rpl000017.test
+++ b/mysql-test/t/rpl000017.test
@@ -1,7 +1,7 @@
-connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
-connect (slave,localhost,root,,test,$SLAVE_MYPORT,slave.sock);
+source include/master-slave.inc;
+connection slave;
+stop slave;
connection master;
-reset master;
grant replication slave on *.* to replicate@localhost identified by 'aaaaaaaaaaaaaaab';
grant replication slave on *.* to replicate@127.0.0.1 identified by 'aaaaaaaaaaaaaaab';
connection slave;
diff --git a/mysql-test/t/rpl000012.test b/mysql-test/t/rpl_000012.test
index 2c1c65e4202..17f1d38dbae 100644
--- a/mysql-test/t/rpl000012.test
+++ b/mysql-test/t/rpl_000012.test
@@ -1,37 +1,53 @@
-source include/master-slave.inc;
-connection master;
+# drop table t1 t2 t3 are included int master-slave.inc
+# Like rpl000013, meaningful only in statement-based:
+-- source include/have_binlog_format_statement.inc
+# Should work on both stm and row
+-- source include/master-slave.inc
-create table t2 (n int);
+
+create table t2 (n int, PRIMARY KEY(n));
create temporary table t1 (n int);
-insert into t1 values(1),(2),(3);
-insert into t2 select * from t1;
create temporary table t3 (n int not null);
+
+insert into t1 values(1),(2),(3),(100),(25),(26),(200),(300);
+insert into t2 select * from t1;
alter table t3 add primary key(n);
+
flush logs;
-insert into t3 values (100);
+insert into t3 values (1010);
insert into t2 select * from t3;
+
drop table if exists t3;
-insert into t2 values (101);
+insert into t2 values (1012);
+
connection master1;
create temporary table t1 (n int);
insert into t1 values (4),(5);
insert into t2 select * from t1;
+
save_master_pos;
disconnect master;
-connection slave;
+connection slave;
#add 1 to the saved position, so we will catch drop table on disconnect
#for sure
sync_with_master 1;
+
connection master1;
-insert into t2 values(6);
+insert into t2 values(61);
+
save_master_pos;
disconnect master1;
+
connection slave;
#same trick - make sure we catch drop of temporary table on disconnect
sync_with_master 1;
+
select * from t2;
+select count(*) from t2;
+select sum(n) from t2;
show status like 'Slave_open_temp_tables';
+
#
# Clean up
#
@@ -41,5 +57,3 @@ drop table if exists t1,t2;
save_master_pos;
connection slave;
sync_with_master;
-
-# End of 4.1 tests
diff --git a/mysql-test/t/rpl000015-slave.sh b/mysql-test/t/rpl_000015-slave.sh
index 62748605af1..62748605af1 100755
--- a/mysql-test/t/rpl000015-slave.sh
+++ b/mysql-test/t/rpl_000015-slave.sh
diff --git a/mysql-test/t/rpl000015.slave-mi b/mysql-test/t/rpl_000015.slave-mi
index 28bc753dd56..28bc753dd56 100644
--- a/mysql-test/t/rpl000015.slave-mi
+++ b/mysql-test/t/rpl_000015.slave-mi
diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl_000015.test
index a53049386af..a19bae1bed0 100644
--- a/mysql-test/t/rpl000015.test
+++ b/mysql-test/t/rpl_000015.test
@@ -30,12 +30,12 @@ connection master;
--disable_warnings
drop table if exists t1;
--enable_warnings
-create table t1 (n int);
+create table t1 (n int, PRIMARY KEY(n));
insert into t1 values (10),(45),(90);
sync_slave_with_master;
+connection slave;
select * from t1;
connection master;
+select * from t1;
drop table t1;
sync_slave_with_master;
-
-# End of 4.1 tests
diff --git a/mysql-test/t/rpl_LD_INFILE.test b/mysql-test/t/rpl_LD_INFILE.test
new file mode 100644
index 00000000000..769462b5898
--- /dev/null
+++ b/mysql-test/t/rpl_LD_INFILE.test
@@ -0,0 +1,41 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/18/2005 #
+#############################################################################
+# TEST: To test the LOAD DATA INFILE in rbr #
+#############################################################################
+
+# Includes
+-- source include/master-slave.inc
+
+# Begin clean up test section
+--disable_warnings
+connection master;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
+--enable_warnings
+
+# Section 1 test
+CREATE TABLE test.t1 (a VARCHAR(255), PRIMARY KEY(a));
+LOAD DATA INFILE '../../std_data/words2.dat' INTO TABLE test.t1;
+DELETE FROM test.t1 WHERE a = 'abashed';
+DELETE FROM test.t1;
+LOAD DATA INFILE '../../std_data/words2.dat' INTO TABLE test.t1;
+
+
+connection master;
+SELECT * FROM test.t1;
+save_master_pos;
+sync_slave_with_master;
+connection slave;
+SELECT * FROM test.t1;
+
+connection master;
+# Lets cleanup
+#show binlog events;
+
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE test.t1;
+
+# End of 5.0 test case
+
diff --git a/mysql-test/t/rpl_auto_increment.test b/mysql-test/t/rpl_auto_increment.test
index 71032404307..fe0f1689471 100644
--- a/mysql-test/t/rpl_auto_increment.test
+++ b/mysql-test/t/rpl_auto_increment.test
@@ -1,104 +1,7 @@
-#
-# Test of auto_increment with offset
-#
-source include/have_innodb.inc;
-source include/master-slave.inc;
-
-create table t1 (a int not null auto_increment,b int, primary key (a)) engine=myisam auto_increment=3;
-insert into t1 values (NULL,1),(NULL,2),(NULL,3);
-select * from t1;
-
-sync_slave_with_master;
-select * from t1;
-connection master;
-drop table t1;
-
-create table t1 (a int not null auto_increment,b int, primary key (a)) engine=myisam;
-insert into t1 values (1,1),(NULL,2),(3,3),(NULL,4);
-delete from t1 where b=4;
-insert into t1 values (NULL,5),(NULL,6);
-select * from t1;
-
-sync_slave_with_master;
-select * from t1;
-connection master;
-
-drop table t1;
-
-set @@session.auto_increment_increment=100, @@session.auto_increment_offset=10;
-show variables like "%auto_inc%";
-
-create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
-# Insert with 2 insert statements to get better testing of logging
-insert into t1 values (NULL),(5),(NULL);
-insert into t1 values (250),(NULL);
-select * from t1;
-insert into t1 values (1000);
-set @@insert_id=400;
-insert into t1 values(NULL),(NULL);
-select * from t1;
-
-sync_slave_with_master;
-select * from t1;
-connection master;
-drop table t1;
-
-#
-# Same test with innodb (as the innodb code is a bit different)
-#
-create table t1 (a int not null auto_increment, primary key (a)) engine=innodb;
-# Insert with 2 insert statements to get better testing of logging
-insert into t1 values (NULL),(5),(NULL);
-insert into t1 values (250),(NULL);
-select * from t1;
-insert into t1 values (1000);
-set @@insert_id=400;
-insert into t1 values(NULL),(NULL);
-select * from t1;
-
-sync_slave_with_master;
-select * from t1;
-connection master;
-drop table t1;
-
-set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1;
-create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
-# Insert with 2 insert statements to get better testing of logging
-insert into t1 values (NULL),(5),(NULL),(NULL);
-insert into t1 values (500),(NULL),(502),(NULL),(NULL);
-select * from t1;
-set @@insert_id=600;
---error 1062
-insert into t1 values(600),(NULL),(NULL);
-set @@insert_id=600;
-insert ignore into t1 values(600),(NULL),(NULL),(610),(NULL);
-select * from t1;
-
-sync_slave_with_master;
-select * from t1;
-connection master;
-drop table t1;
-
-#
-# Test that auto-increment works when slave has rows in the table
-#
-set @@session.auto_increment_increment=10, @@session.auto_increment_offset=1;
-
-create table t1 (a int not null auto_increment, primary key (a)) engine=myisam;
-
-sync_slave_with_master;
-insert into t1 values(2),(12),(22),(32),(42);
-connection master;
-
-insert into t1 values (NULL),(NULL);
-insert into t1 values (3),(NULL),(NULL);
-select * from t1;
-
-sync_slave_with_master;
-select * from t1;
-connection master;
-
-drop table t1;
-
-# End cleanup
-sync_slave_with_master;
+#####################################
+# Wrapper for rpl_auto_increment.test#
+#####################################
+-- source include/have_innodb.inc
+let $engine_type=innodb;
+let $engine_type2=myisam;
+-- source extra/rpl_tests/rpl_auto_increment.test
diff --git a/mysql-test/t/rpl_bit.test b/mysql-test/t/rpl_bit.test
new file mode 100644
index 00000000000..5211f375274
--- /dev/null
+++ b/mysql-test/t/rpl_bit.test
@@ -0,0 +1,90 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Sept/15/2005 #
+#############################################################################
+# Test: To test the replication of the bit field #
+#############################################################################
+
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP TABLE IF EXISTS test.t1;
+--enable_warnings
+# End of cleanup
+
+# Begin test section 1
+
+CREATE TABLE test.t1 (
+ dummyKey INTEGER NOT NULL,
+ f01 TINYINT,
+ f10 TINYINT,
+ f12 TINYINT,
+ f15 TINYINT,
+ f16 TINYINT,
+ f7 TINYINT,
+ f9 TINYINT,
+ f29 TINYINT,
+ f0 TINYINT,
+ fA1 TINYINT,
+ C32 TINYINT,
+ A42 TINYINT,
+ CA3 TINYINT,
+ A044 TINYINT,
+ f001 TINYINT,
+ A3002 TINYINT,
+ fC003 TINYINT,
+ CA300 TINYINT,
+ A305 TINYINT,
+ CA321 TINYINT,
+ r001 TINYINT,
+ bit1 BIT(6),
+ bit2 BIT(6),
+ bit3 BIT(6),
+ State1 TINYINT,
+ State2 TINYINT,
+ State3 TINYINT,
+ State4 TINYINT,
+ SubState TINYINT,
+ gState TINYINT,
+ oSupp TINYINT,
+ tSupp TINYINT,
+ sSuppD TINYINT,
+ mSuppf TINYINT,
+ GSuppDf TINYINT,
+ VNotSupp TINYINT,
+ x034 TINYINT,
+PRIMARY KEY USING HASH (dummyKey) );
+
+LOCK TABLES test.t1 WRITE;
+INSERT INTO test.t1 VALUES (6,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'111110',b'110101',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'000000',b'100100',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (2,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'000000',b'101010',b'010101',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (3,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'101010',b'111111',b'000000',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (4,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (5,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (7,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (8,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+UNLOCK TABLES;
+
+
+SELECT oSupp, sSuppD, GSuppDf, VNotSupp, x034 FROM test.t1;
+SELECT hex(bit1) from test.t1;
+SELECT hex(bit2) from test.t1;
+SELECT hex(bit3) from test.t1;
+save_master_pos;
+
+connection slave;
+sync_with_master;
+SELECT oSupp, sSuppD, GSuppDf, VNotSupp, x034 FROM test.t1;
+SELECT hex(bit1) from test.t1;
+SELECT hex(bit2) from test.t1;
+SELECT hex(bit3) from test.t1;
+
+connection master;
+DROP TABLE IF EXISTS test.t1;
+sync_slave_with_master;
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_bit_npk.test b/mysql-test/t/rpl_bit_npk.test
new file mode 100644
index 00000000000..07fc42b09ef
--- /dev/null
+++ b/mysql-test/t/rpl_bit_npk.test
@@ -0,0 +1,112 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Sept/15/2005 #
+#############################################################################
+# Test: To test the replication of the bit field #
+#############################################################################
+
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP TABLE IF EXISTS test.t1;
+--enable_warnings
+# End of cleanup
+
+# Begin test section 1
+
+CREATE TABLE test.t1 (
+ dummyKey INTEGER NOT NULL,
+ f01 TINYINT,
+ f10 TINYINT,
+ f12 TINYINT,
+ f15 TINYINT,
+ f16 TINYINT,
+ f7 TINYINT,
+ f9 TINYINT,
+ f29 TINYINT,
+ f0 TINYINT,
+ fA1 TINYINT,
+ C32 TINYINT,
+ A42 TINYINT,
+ CA3 TINYINT,
+ A044 TINYINT,
+ f001 TINYINT,
+ A3002 TINYINT,
+ fC003 TINYINT,
+ CA300 TINYINT,
+ A305 TINYINT,
+ CA321 TINYINT,
+ r001 TINYINT,
+ bit1 BIT(6),
+ bit2 BIT(6),
+ bit3 BIT(6),
+ State1 TINYINT,
+ State2 TINYINT,
+ State3 TINYINT,
+ State4 TINYINT,
+ SubState TINYINT,
+ gState TINYINT,
+ oSupp TINYINT,
+ tSupp TINYINT,
+ sSuppD TINYINT,
+ mSuppf TINYINT,
+ GSuppDf TINYINT,
+ VNotSupp TINYINT,
+ x034 TINYINT);
+
+LOCK TABLES test.t1 WRITE;
+INSERT INTO test.t1 VALUES (6,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'111110',b'110101',4,5,5,5,5,5,5,5,5,5,3,NULL,1);
+INSERT INTO test.t1 VALUES (1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'111111',b'000000',b'100100',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (2,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'000000',b'101010',b'010101',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (3,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'101010',b'111111',b'000000',4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (4,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,b'0',1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (5,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (7,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+INSERT INTO test.t1 VALUES (8,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,5,5,5,5,5,5,5,5,5,3,2,1);
+UNLOCK TABLES;
+
+UPDATE test.t1 set x034 = 50 where bit3 = b'000000';
+UPDATE test.t1 set VNotSupp = 33 where bit1 = b'0';
+SELECT oSupp, sSuppD, GSuppDf, VNotSupp, x034 FROM test.t1;
+SELECT hex(bit1) from test.t1;
+SELECT hex(bit2) from test.t1;
+SELECT hex(bit3) from test.t1;
+save_master_pos;
+
+connection slave;
+sync_with_master;
+SELECT oSupp, sSuppD, GSuppDf, VNotSupp, x034 FROM test.t1;
+SELECT hex(bit1) from test.t1;
+SELECT hex(bit2) from test.t1;
+SELECT hex(bit3) from test.t1;
+
+connection master;
+CREATE TABLE test.t2 (a INT, b BIT(1));
+INSERT INTO test.t2 VALUES (1, b'0');
+INSERT INTO test.t2 VALUES (1, b'1');
+UPDATE test.t2 SET a = 2 WHERE b = b'1';
+
+CREATE TABLE test.t3 (a INT, b INT);
+INSERT INTO test.t3 VALUES (1, NULL);
+INSERT INTO test.t3 VALUES (1, 0);
+UPDATE test.t3 SET a = 2 WHERE b = 0;
+
+SELECT a, hex(b) FROM test.t2;
+SELECT * FROM test.t3;
+save_master_pos;
+
+connection slave;
+sync_with_master;
+SELECT a, hex(b) FROM test.t2;
+SELECT * FROM test.t3;
+
+connection master;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
+sync_slave_with_master;
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_change_master.test b/mysql-test/t/rpl_change_master.test
index 6c055a81ceb..c031464c95e 100644
--- a/mysql-test/t/rpl_change_master.test
+++ b/mysql-test/t/rpl_change_master.test
@@ -19,11 +19,11 @@ connection slave;
--real_sleep 3 # wait for I/O thread to have read updates
stop slave;
--replace_result $MASTER_MYPORT MASTER_MYPORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 7 # 8 # 9 # 23 # 33 #
show slave status;
change master to master_user='root';
--replace_result $MASTER_MYPORT MASTER_MYPORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 7 # 8 # 9 # 23 # 33 #
show slave status;
start slave;
sync_with_master;
diff --git a/mysql-test/t/rpl_commit_after_flush.test b/mysql-test/t/rpl_commit_after_flush.test
index 6129e5485a6..9f6d4591f96 100644
--- a/mysql-test/t/rpl_commit_after_flush.test
+++ b/mysql-test/t/rpl_commit_after_flush.test
@@ -1,19 +1,6 @@
-source include/master-slave.inc;
-source include/have_innodb.inc;
-create table t1 (a int) engine=innodb;
-begin;
-insert into t1 values(1);
-flush tables with read lock;
-commit;
-save_master_pos;
-connection slave;
-sync_with_master;
-# cleanup
-connection master;
-unlock tables;
-drop table t1;
-save_master_pos;
-connection slave;
-sync_with_master;
-
-# End of 4.1 tests
+#####################################
+# Wrapper for rpl_commit_after_flush#
+#####################################
+-- source include/have_innodb.inc
+let $engine_type=innodb;
+-- source extra/rpl_tests/rpl_commit_after_flush.test
diff --git a/mysql-test/t/rpl_create_database.test b/mysql-test/t/rpl_create_database.test
index cfccc4567b5..7ec73132113 100644
--- a/mysql-test/t/rpl_create_database.test
+++ b/mysql-test/t/rpl_create_database.test
@@ -55,9 +55,6 @@ CREATE DATABASE mysqltest_sisyfos;
USE mysqltest_sisyfos;
CREATE TABLE t2 (a INT);
let $VERSION=`select version()`;
---replace_result $VERSION VERSION
---replace_column 2 # 5 #
-SHOW BINLOG EVENTS;
SHOW DATABASES;
sync_slave_with_master;
SHOW DATABASES;
diff --git a/mysql-test/t/rpl_deadlock-slave.opt b/mysql-test/t/rpl_deadlock_innodb-slave.opt
index f4a8c640458..f4a8c640458 100644
--- a/mysql-test/t/rpl_deadlock-slave.opt
+++ b/mysql-test/t/rpl_deadlock_innodb-slave.opt
diff --git a/mysql-test/t/rpl_deadlock_innodb.test b/mysql-test/t/rpl_deadlock_innodb.test
new file mode 100644
index 00000000000..155bb9fdf34
--- /dev/null
+++ b/mysql-test/t/rpl_deadlock_innodb.test
@@ -0,0 +1,6 @@
+################################
+# Wrapper for rpl_deadlock.test#
+################################
+-- source include/have_innodb.inc
+let $engine_type=innodb;
+-- source extra/rpl_tests/rpl_deadlock.test
diff --git a/mysql-test/t/rpl_delete_all.test b/mysql-test/t/rpl_delete_all.test
deleted file mode 100644
index e0c0757bbc2..00000000000
--- a/mysql-test/t/rpl_delete_all.test
+++ /dev/null
@@ -1,43 +0,0 @@
-source include/master-slave.inc;
-
-connection slave;
-create database mysqltest;
-connection master;
-drop database if exists mysqltest;
-sync_slave_with_master;
-# can't read dir
---replace_result "Errcode: 1" "Errcode: X" "Errcode: 2" "Errcode: X" \\ /
---error 1049
-show tables from mysqltest;
-
-connection slave;
-create table t1 (a int);
-connection master;
-drop table if exists t1;
-sync_slave_with_master;
-# table does not exist
---error 1146
-select * from t1;
-
-connection master;
-create table t1 (a int);
-sync_slave_with_master;
-insert into t1 values(1);
-connection master;
-delete from t1;
-sync_slave_with_master;
-select * from t1;
-
-insert into t1 values(1);
-connection master;
-insert into t1 values(2);
-update t1 set a=2;
-sync_slave_with_master;
-select * from t1;
-
-# cleanup
-connection master;
-drop table t1;
-sync_slave_with_master;
-
-# End of 4.1 tests
diff --git a/mysql-test/t/rpl_delete_no_where.test b/mysql-test/t/rpl_delete_no_where.test
new file mode 100644
index 00000000000..b4cbda64ea3
--- /dev/null
+++ b/mysql-test/t/rpl_delete_no_where.test
@@ -0,0 +1,2 @@
+let $engine_type=myisam;
+-- source extra/rpl_tests/rpl_delete_no_where.test
diff --git a/mysql-test/t/rpl_do_grant.test b/mysql-test/t/rpl_do_grant.test
index 54287a67657..8d6f99e4bf1 100644
--- a/mysql-test/t/rpl_do_grant.test
+++ b/mysql-test/t/rpl_do_grant.test
@@ -1,6 +1,7 @@
-# Test that GRANT and SET PASSWORD are replicated to the slave
+# Works in statement-based and row-based binlogging.
+# Test that GRANT and other user management commands are replicated to the slave
-source include/master-slave.inc;
+-- source include/master-slave.inc
# do not be influenced by other tests.
connection master;
@@ -46,3 +47,52 @@ sync_with_master;
flush privileges;
# End of 4.1 tests
+
+connection master;
+--error 1141
+show grants for rpl_do_grant@localhost;
+connection slave;
+--error 1141
+show grants for rpl_do_grant@localhost;
+
+connection master;
+create user rpl_do_grant@localhost;
+show grants for rpl_do_grant@localhost;
+--error 1141
+show grants for rpl_do_grant2@localhost;
+sync_slave_with_master;
+show grants for rpl_do_grant@localhost;
+--error 1141
+show grants for rpl_do_grant2@localhost;
+
+connection master;
+rename user rpl_do_grant@localhost to rpl_do_grant2@localhost;
+show grants for rpl_do_grant2@localhost;
+sync_slave_with_master;
+show grants for rpl_do_grant2@localhost;
+
+connection master;
+grant DELETE,INSERT on mysqltest1.* to rpl_do_grant2@localhost;
+show grants for rpl_do_grant2@localhost;
+sync_slave_with_master;
+show grants for rpl_do_grant2@localhost;
+
+connection master;
+revoke DELETE on mysqltest1.* from rpl_do_grant2@localhost;
+show grants for rpl_do_grant2@localhost;
+sync_slave_with_master;
+show grants for rpl_do_grant2@localhost;
+
+connection master;
+revoke all privileges, grant option from rpl_do_grant2@localhost;
+show grants for rpl_do_grant2@localhost;
+sync_slave_with_master;
+show grants for rpl_do_grant2@localhost;
+
+connection master;
+drop user rpl_do_grant2@localhost;
+--error 1141
+show grants for rpl_do_grant2@localhost;
+sync_slave_with_master;
+--error 1141
+show grants for rpl_do_grant2@localhost;
diff --git a/mysql-test/t/rpl_drop.test b/mysql-test/t/rpl_drop.test
index ebb33c92a20..b38007a755f 100644
--- a/mysql-test/t/rpl_drop.test
+++ b/mysql-test/t/rpl_drop.test
@@ -12,3 +12,5 @@ connection slave;
sync_with_master;
# End of 4.1 tests
+
+
diff --git a/mysql-test/t/rpl_empty_master_crash.test b/mysql-test/t/rpl_empty_master_crash.test
index 5f26bedc9fe..707d1eca8c2 100644
--- a/mysql-test/t/rpl_empty_master_crash.test
+++ b/mysql-test/t/rpl_empty_master_crash.test
@@ -1,6 +1,6 @@
source include/master-slave.inc;
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
#
diff --git a/mysql-test/t/rpl_failed_optimize.test b/mysql-test/t/rpl_failed_optimize.test
index 57afaa89e83..4b329208fef 100644
--- a/mysql-test/t/rpl_failed_optimize.test
+++ b/mysql-test/t/rpl_failed_optimize.test
@@ -1,20 +1,6 @@
-source include/have_innodb.inc;
-source include/master-slave.inc;
-
-#
-# BUG#5551 "Failed OPTIMIZE TABLE is logged to binary log"
-# Replication should work when OPTIMIZE TABLE timeouts, and
-# when OPTIMIZE TABLE is executed on a non-existing table
-#
-
-CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
-BEGIN;
-INSERT INTO t1 VALUES (1);
-
-connection master1;
-OPTIMIZE TABLE t1;
-
-OPTIMIZE TABLE non_existing;
-sync_slave_with_master;
-
-# End of 4.1 tests
+#######################################
+# Wrapper for rpl_failed_optimize.test#
+#######################################
+-- source include/have_innodb.inc
+let $engine_type=InnoDB;
+-- source extra/rpl_tests/rpl_failed_optimize.test
diff --git a/mysql-test/t/rpl_flush_log_loop-master.opt b/mysql-test/t/rpl_flushlog_loop-master.opt
index 4f6e0f3d00c..4f6e0f3d00c 100644
--- a/mysql-test/t/rpl_flush_log_loop-master.opt
+++ b/mysql-test/t/rpl_flushlog_loop-master.opt
diff --git a/mysql-test/t/rpl_flush_log_loop-master.sh b/mysql-test/t/rpl_flushlog_loop-master.sh
index 9e56af99f5c..9e56af99f5c 100755
--- a/mysql-test/t/rpl_flush_log_loop-master.sh
+++ b/mysql-test/t/rpl_flushlog_loop-master.sh
diff --git a/mysql-test/t/rpl_flush_log_loop-slave.opt b/mysql-test/t/rpl_flushlog_loop-slave.opt
index d1373f139b1..d1373f139b1 100644
--- a/mysql-test/t/rpl_flush_log_loop-slave.opt
+++ b/mysql-test/t/rpl_flushlog_loop-slave.opt
diff --git a/mysql-test/t/rpl_flush_log_loop-slave.sh b/mysql-test/t/rpl_flushlog_loop-slave.sh
index b8814e059a9..b8814e059a9 100755
--- a/mysql-test/t/rpl_flush_log_loop-slave.sh
+++ b/mysql-test/t/rpl_flushlog_loop-slave.sh
diff --git a/mysql-test/t/rpl_flush_log_loop.test b/mysql-test/t/rpl_flushlog_loop.test
index 6e45047bd30..46f41e9a5e3 100644
--- a/mysql-test/t/rpl_flush_log_loop.test
+++ b/mysql-test/t/rpl_flushlog_loop.test
@@ -1,15 +1,23 @@
# Testing if "flush logs" command bouncing resulting in logs created in a loop
# in case of bi-directional replication
+-- source include/master-slave.inc
-source include/master-slave.inc;
+# This test is dependent on the actual events written to the binary
+# log. To not break statement-based testing, we only run this test
+# under statement-based logging.
connection slave;
+--disable_warnings
stop slave;
+--enable_warnings
--replace_result $MASTER_MYPORT MASTER_PORT
eval change master to master_host='127.0.0.1',master_user='root',
master_password='',master_port=$MASTER_MYPORT;
start slave;
connection master;
+--disable_warnings
+stop slave;
+--enable_warnings
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval change master to master_host='127.0.0.1',master_user='root',
master_password='',master_port=$SLAVE_MYPORT;
@@ -18,7 +26,5 @@ sleep 5;
flush logs;
sleep 5;
--replace_result $SLAVE_MYPORT SLAVE_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
-
-# End of 4.1 tests
diff --git a/mysql-test/t/rpl_foreign_key_innodb.test b/mysql-test/t/rpl_foreign_key_innodb.test
new file mode 100644
index 00000000000..8615a008739
--- /dev/null
+++ b/mysql-test/t/rpl_foreign_key_innodb.test
@@ -0,0 +1,6 @@
+###################################
+# Wrapper for rpl_foreign_key.test#
+###################################
+-- source include/have_innodb.inc
+let $engine_type=INNODB;
+-- source extra/rpl_tests/rpl_foreign_key.test
diff --git a/mysql-test/t/rpl_heap.test b/mysql-test/t/rpl_heap.test
index 3ee335fe58d..03c9070678b 100644
--- a/mysql-test/t/rpl_heap.test
+++ b/mysql-test/t/rpl_heap.test
@@ -1,3 +1,6 @@
+# Requires statement logging
+-- source include/have_binlog_format_statement.inc
+
# You must run this test with --manager.
require_manager;
@@ -18,6 +21,7 @@ drop table if exists t1;
create table t1 type=HEAP select 10 as a;
insert into t1 values(11);
save_master_pos;
+--replace_column 2 # 5 #
show binlog events from 79;
connection slave;
reset slave;
@@ -35,6 +39,7 @@ select * from t1;
# (the LIMIT is to not use the query cache)
select * from t1 limit 10;
save_master_pos;
+--replace_column 2 # 5 #
show binlog events in 'master-bin.002' from 79;
connection slave;
diff --git a/mysql-test/t/rpl_insert_id.test b/mysql-test/t/rpl_insert_id.test
index 49d3a03640c..62a9fdb4d56 100644
--- a/mysql-test/t/rpl_insert_id.test
+++ b/mysql-test/t/rpl_insert_id.test
@@ -1,77 +1,6 @@
-# See if queries that use both auto_increment and LAST_INSERT_ID()
-# are replicated well
-
-# We also check how the foreign_key_check variable is replicated
-
-source include/master-slave.inc;
-source include/have_innodb.inc;
-connection master;
-create table t1(a int auto_increment, key(a));
-create table t2(b int auto_increment, c int, key(b));
-insert into t1 values (1),(2),(3);
-insert into t1 values (null);
-insert into t2 values (null,last_insert_id());
-save_master_pos;
-connection slave;
-sync_with_master;
-select * from t1;
-select * from t2;
-connection master;
-#check if multi-line inserts,
-#which set last_insert_id to the first id inserted,
-#are replicated the same way
-drop table t1;
-drop table t2;
---disable_warnings
-create table t1(a int auto_increment, key(a)) engine=innodb;
-create table t2(b int auto_increment, c int, key(b), foreign key(b) references t1(a)) engine=innodb;
---enable_warnings
-SET FOREIGN_KEY_CHECKS=0;
-insert into t1 values (10);
-insert into t1 values (null),(null),(null);
-insert into t2 values (5,0);
-insert into t2 values (null,last_insert_id());
-SET FOREIGN_KEY_CHECKS=1;
-save_master_pos;
-connection slave;
-sync_with_master;
-select * from t1;
-select * from t2;
-connection master;
-
-# check if INSERT SELECT in auto_increment is well replicated (bug #490)
-
-drop table t2;
-drop table t1;
-create table t1(a int auto_increment, key(a));
-create table t2(b int auto_increment, c int, key(b));
-insert into t1 values (10);
-insert into t1 values (null),(null),(null);
-insert into t2 values (5,0);
-insert into t2 (c) select * from t1;
-select * from t2;
-save_master_pos;
-connection slave;
-sync_with_master;
-select * from t1;
-select * from t2;
-connection master;
-drop table t1;
-drop table t2;
-save_master_pos;
-connection slave;
-sync_with_master;
-
-#
-# Bug#8412: Error codes reported in binary log for CHARACTER SET,
-# FOREIGN_KEY_CHECKS
-#
-connection master;
-SET TIMESTAMP=1000000000;
-CREATE TABLE t1 ( a INT UNIQUE );
-SET FOREIGN_KEY_CHECKS=0;
---error 1062
-INSERT INTO t1 VALUES (1),(1);
-sync_slave_with_master;
-
-# End of 4.1 tests
+#################################
+# Wrapper for rpl_insert_id.test#
+#################################
+-- source include/have_innodb.inc
+let $engine_type=innodb;
+-- source extra/rpl_tests/rpl_insert_id.test
diff --git a/mysql-test/t/rpl_insert_ignore.test b/mysql-test/t/rpl_insert_ignore.test
index a6cc69b1df8..61222b542ac 100644
--- a/mysql-test/t/rpl_insert_ignore.test
+++ b/mysql-test/t/rpl_insert_ignore.test
@@ -1,73 +1,7 @@
-# Testcase for BUG#6287 "Slave skips auto_increment values in Replication with InnoDB"
-# The bug was that if on master, INSERT IGNORE ignored some
-# rows, and the table was InnoDB with auto_inc column, then on slave
-# some rows received an auto_inc bigger than on master.
-# Slave needs to be started with --innodb to store table in InnoDB.
-# Same test for MyISAM (which had no bug).
-
+#####################################
+# Wrapper for rpl_insert_ignore.test#
+#####################################
-- source include/have_innodb.inc
-
--- source include/master-slave.inc
-
-CREATE TABLE t1 (
- a int unsigned not null auto_increment primary key,
- b int unsigned,
- unique (b)
-) ENGINE=innodb;
-
-CREATE TABLE t2 (
- a int unsigned, # to force INSERT SELECT to have a certain order
- b int unsigned
-) ENGINE=innodb;
-
-
-INSERT INTO t1 VALUES (NULL, 1);
-INSERT INTO t1 VALUES (NULL, 2);
-INSERT INTO t1 VALUES (NULL, 3);
-INSERT INTO t1 VALUES (NULL, 4);
-
-# An alternation of values which will conflict in t1 and will not.
-
-INSERT INTO t2 VALUES (1, 1);
-INSERT INTO t2 VALUES (2, 2);
-INSERT INTO t2 VALUES (3, 5);
-INSERT INTO t2 VALUES (4, 3);
-INSERT INTO t2 VALUES (5, 4);
-INSERT INTO t2 VALUES (6, 6);
-
-INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a;
-
-# Compare results
-
-SELECT * FROM t1 ORDER BY a;
-
-sync_slave_with_master;
-SELECT * FROM t1 ORDER BY a;
-
-# Now do the same for MyISAM
-
-connection master;
-drop table t1;
-CREATE TABLE t1 (
- a int unsigned not null auto_increment primary key,
- b int unsigned,
- unique (b)
-) ENGINE=myisam;
-
-INSERT INTO t1 VALUES (1, 1);
-INSERT INTO t1 VALUES (2, 2);
-INSERT INTO t1 VALUES (3, 3);
-INSERT INTO t1 VALUES (4, 4);
-
-INSERT IGNORE INTO t1 SELECT NULL, t2.b FROM t2 ORDER BY t2.a;
-
-SELECT * FROM t1 ORDER BY a;
-
-sync_slave_with_master;
-SELECT * FROM t1 ORDER BY a;
-
-connection master;
-drop table t1, t2;
-sync_slave_with_master;
-
-# End of 4.1 tests
+let $engine_type=innodb;
+let $engine_type2=myisam;
+-- source extra/rpl_tests/rpl_insert_ignore.test
diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test
index 00121092bbf..72914717a12 100644
--- a/mysql-test/t/rpl_loaddata.test
+++ b/mysql-test/t/rpl_loaddata.test
@@ -1,153 +1,2 @@
-# See if replication of a "LOAD DATA in an autoincrement column"
-# Honours autoincrement values
-# i.e. if the master and slave have the same sequence
-#
-# check replication of load data for temporary tables with additional
-# parameters
-#
-# check if duplicate entries trigger an error (they should unless IGNORE or
-# REPLACE was used on the master) (bug 571).
-#
-# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and
-# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986)
-
-source include/master-slave.inc;
-
-connection slave;
-reset master;
-connection master;
-
-create table t1(a int not null auto_increment, b int, primary key(a) );
-load data infile '../../std_data/rpl_loaddata.dat' into table t1;
-
-create temporary table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60));
-load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines;
-
-create table t3 (day date,id int(9),category enum('a','b','c'),name varchar(60));
-insert into t3 select * from t2;
-
-save_master_pos;
-connection slave;
-sync_with_master;
-
-select * from t1;
-select * from t3;
-# We want to be sure that LOAD DATA is in the slave's binlog.
-# But we can't simply read this binlog, because as the slave has not been
-# restarted for this test, the file_id is uncertain (would cause test
-# failures). So instead, we test if the binlog looks long enough to
-# contain LOAD DATA. Since 5.0.3 we assume that binlog of 1292 is ok.
-# If LOAD DATA was not logged, the binlog would be shorter.
-show master status;
-
-connection master;
-
-drop table t1;
-drop table t2;
-drop table t3;
-create table t1(a int, b int, unique(b));
-
-save_master_pos;
-connection slave;
-sync_with_master;
-
-# See if slave stops when there's a duplicate entry for key error in LOAD DATA
-
-insert into t1 values(1,10);
-
-connection master;
-load data infile '../../std_data/rpl_loaddata.dat' into table t1;
-
-save_master_pos;
-connection slave;
-# The SQL slave thread should be stopped now.
-wait_for_slave_to_stop;
-
-# Skip the bad event and see if error is cleared in SHOW SLAVE STATUS by START
-# SLAVE, even though we are not executing any event (as sql_slave_skip_counter
-# takes us directly to the end of the relay log).
-
-set global sql_slave_skip_counter=1;
-start slave;
-sync_with_master;
---replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
-show slave status;
-
-# Trigger error again to test CHANGE MASTER
-
-connection master;
-set sql_log_bin=0;
-delete from t1;
-set sql_log_bin=1;
-load data infile '../../std_data/rpl_loaddata.dat' into table t1;
-save_master_pos;
-connection slave;
-# The SQL slave thread should be stopped now.
-# Exec_Master_Log_Pos should point to the start of Execute event
-# for last load data.
-wait_for_slave_to_stop;
-
-# CHANGE MASTER and see if error is cleared in SHOW SLAVE STATUS.
-stop slave;
-change master to master_user='test';
-change master to master_user='root';
---replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
-show slave status;
-
-# Trigger error again to test RESET SLAVE
-
-set global sql_slave_skip_counter=1;
-start slave;
-sync_with_master;
-connection master;
-set sql_log_bin=0;
-delete from t1;
-set sql_log_bin=1;
-load data infile '../../std_data/rpl_loaddata.dat' into table t1;
-save_master_pos;
-connection slave;
-# The SQL slave thread should be stopped now.
-wait_for_slave_to_stop;
-
-# RESET SLAVE and see if error is cleared in SHOW SLAVE STATUS.
-stop slave;
-reset slave;
---replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
-show slave status;
-
-# Finally, see if logging is done ok on master for a failing LOAD DATA INFILE
-
-connection master;
-reset master;
-create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60),
-unique(day)) engine=MyISAM; # no transactions
---error 1062
-load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
-terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
-'\n##\n' starting by '>' ignore 1 lines;
-select * from t2;
-save_master_pos;
-connection slave;
-start slave;
-sync_with_master;
-select * from t2;
-
-# verify that if no error on slave, this is an error
-
-alter table t2 drop key day;
-connection master;
-delete from t2;
---error 1062
-load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
-terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
-'\n##\n' starting by '>' ignore 1 lines;
-connection slave;
-wait_for_slave_to_stop;
-drop table t2;
-connection master;
-drop table t2;
-
-# End of 4.1 tests
+let $engine_type=MyISAM;
+-- source extra/rpl_tests/rpl_loaddata.test
diff --git a/mysql-test/t/rpl_loaddata2.test b/mysql-test/t/rpl_loaddata2.test
new file mode 100644
index 00000000000..22429666d5f
--- /dev/null
+++ b/mysql-test/t/rpl_loaddata2.test
@@ -0,0 +1,8 @@
+--source include/master-slave.inc
+
+CREATE TABLE t1 (word CHAR(20) NOT NULL);
+LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1;
+SELECT * FROM t1;
+sync_slave_with_master;
+SELECT * FROM t1;
+
diff --git a/mysql-test/t/rpl_loaddata_rule_m-master.opt b/mysql-test/t/rpl_loaddata_s-slave.opt
index 9d4a8f0b95e..9d4a8f0b95e 100644
--- a/mysql-test/t/rpl_loaddata_rule_m-master.opt
+++ b/mysql-test/t/rpl_loaddata_s-slave.opt
diff --git a/mysql-test/t/rpl_loaddata_rule_s.test b/mysql-test/t/rpl_loaddata_s.test
index 98fad3cc06f..c49fe461d7b 100644
--- a/mysql-test/t/rpl_loaddata_rule_s.test
+++ b/mysql-test/t/rpl_loaddata_s.test
@@ -2,13 +2,16 @@
# replicated LOAD DATA INFILE correctly when it has binlog_*_db rules.
# This is for BUG#1100 (LOAD DATA INFILE was half-logged).
-source include/master-slave.inc;
+-- source include/have_binlog_format_statement.inc
+-- source include/master-slave.inc
+
connection slave;
+# Not sure why we connect to slave and then try to reset master, but I will leave it [JBM]
reset master;
connection master;
# 'test' is the current database
-create table t1(a int, b int, unique(b));
+create table test.t1(a int, b int, unique(b));
load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
# Test logging on slave;
@@ -16,7 +19,6 @@ load data infile '../../std_data/rpl_loaddata.dat' into table test.t1;
save_master_pos;
connection slave;
sync_with_master;
-select count(*) from t1; # check that LOAD was replicated
-show binlog events from 98; # should be nothing
-
-# End of 4.1 tests
+select count(*) from test.t1; # check that LOAD was replicated
+--replace_column 2 # 5 #
+show binlog events from 102; # should be nothing
diff --git a/mysql-test/t/rpl_loadfile.test b/mysql-test/t/rpl_loadfile.test
new file mode 100644
index 00000000000..58d5717b7e8
--- /dev/null
+++ b/mysql-test/t/rpl_loadfile.test
@@ -0,0 +1,47 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/18/2005 #
+#############################################################################
+# TEST: To test the LOAD_FILE() in rbr #
+#############################################################################
+
+# Includes
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+--disable_warnings
+connection master;
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
+--enable_warnings
+
+# Section 1 test
+
+CREATE TABLE test.t1 (a INT, blob_column LONGBLOB, PRIMARY KEY(a));
+INSERT INTO test.t1 VALUES(1,'test');
+UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=1;
+delimiter |;
+create procedure test.p1()
+begin
+ INSERT INTO test.t1 VALUES(2,'test');
+ UPDATE test.t1 SET blob_column=LOAD_FILE('../../std_data/words2.dat') WHERE a=2;
+end|
+delimiter ;|
+
+CALL test.p1();
+SELECT * FROM test.t1;
+save_master_pos;
+sync_slave_with_master;
+connection slave;
+SHOW CREATE TABLE test.t1;
+SELECT * FROM test.t1;
+
+connection master;
+# Lets cleanup
+#show binlog events;
+
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE test.t1;
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_log_pos.test b/mysql-test/t/rpl_log_pos.test
index 979b146bb22..44c00f80e6d 100644
--- a/mysql-test/t/rpl_log_pos.test
+++ b/mysql-test/t/rpl_log_pos.test
@@ -1,19 +1,23 @@
#
# Testing of setting slave to wrong log position with master_log_pos
#
+
+# Passes with rbr no problem, removed statement include [jbm]
+
source include/master-slave.inc;
+--replace_column 3 <Binlog_Ignore_DB>
show master status;
sync_slave_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
stop slave;
-change master to master_log_pos=73;
+change master to master_log_pos=74;
start slave;
sleep 5;
stop slave;
-change master to master_log_pos=73;
+change master to master_log_pos=74;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
@@ -23,13 +27,14 @@ sleep 5;
--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
stop slave;
-change master to master_log_pos=173;
+change master to master_log_pos=177;
start slave;
sleep 2;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 8 # 9 # 23 # 33 #
show slave status;
connection master;
+--replace_column 3 <Binlog_Ignore_DB>
show master status;
create table if not exists t1 (n int);
drop table if exists t1;
@@ -38,7 +43,7 @@ insert into t1 values (1),(2),(3);
save_master_pos;
connection slave;
stop slave;
-change master to master_log_pos=98;
+change master to master_log_pos=102;
start slave;
sync_with_master;
select * from t1;
diff --git a/mysql-test/t/rpl_multi_delete.test b/mysql-test/t/rpl_multi_delete.test
index 4a8c0ab6912..2fd7b820b1a 100644
--- a/mysql-test/t/rpl_multi_delete.test
+++ b/mysql-test/t/rpl_multi_delete.test
@@ -16,26 +16,10 @@ sync_with_master;
select * from t1;
select * from t2;
-# End of 4.1 tests
-
-# Check if deleting 0 rows is binlogged (BUG#13348)
-
-connection master;
-delete from t1;
-delete from t2;
-
-sync_slave_with_master;
-# force a difference to see if master's multi-DELETE will correct it
-insert into t1 values(1);
-insert into t2 values(1);
-
-connection master;
-DELETE t1.*, t2.* from t1, t2;
-
-sync_slave_with_master;
-select * from t1;
-select * from t2;
-
connection master;
drop table t1,t2;
-sync_slave_with_master;
+save_master_pos;
+connection slave;
+sync_with_master;
+
+# End of 4.1 tests
diff --git a/mysql-test/t/rpl000001-slave.opt b/mysql-test/t/rpl_multi_engine-slave.opt
index 627becdbfb5..627becdbfb5 100644
--- a/mysql-test/t/rpl000001-slave.opt
+++ b/mysql-test/t/rpl_multi_engine-slave.opt
diff --git a/mysql-test/t/rpl_multi_engine.test b/mysql-test/t/rpl_multi_engine.test
new file mode 100644
index 00000000000..b0879757468
--- /dev/null
+++ b/mysql-test/t/rpl_multi_engine.test
@@ -0,0 +1,99 @@
+# See if replication between MyISAM, MEMORY and InnoDB works.
+
+-- source include/master-slave.inc
+
+connection slave;
+-- source include/have_innodb.inc
+
+connection master;
+-- source include/have_innodb.inc
+--disable_warnings
+create database if not exists mysqltest1;
+use mysqltest1;
+drop table if exists t1;
+
+CREATE TABLE t1 (id MEDIUMINT NOT NULL, b1 BIT(8), vc
+VARCHAR(255), bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, f FLOAT DEFAULT
+0, total BIGINT UNSIGNED, y YEAR, t TIMESTAMP,PRIMARY KEY(id));
+
+sync_slave_with_master;
+use mysqltest1;
+
+# MyISAM to MyISAM then InnoDB then MEMORY
+
+connection master;
+alter table t1 engine=myisam;
+show create table t1;
+
+connection slave;
+alter table t1 engine=myisam;
+show create table t1;
+
+--source include/rpl_multi_engine.inc
+
+connection slave;
+alter table t1 engine=innodb;
+show create table t1;
+
+--source include/rpl_multi_engine.inc
+
+connection slave;
+alter table t1 engine=memory;
+show create table t1;
+
+--source include/rpl_multi_engine.inc
+
+# MEMORY to ...
+
+connection master;
+alter table t1 engine=memory;
+show create table t1;
+
+connection slave;
+alter table t1 engine=myisam;
+show create table t1;
+
+--source include/rpl_multi_engine.inc
+
+connection slave;
+alter table t1 engine=innodb;
+show create table t1;
+
+--source include/rpl_multi_engine.inc
+
+connection slave;
+alter table t1 engine=memory;
+show create table t1;
+
+--source include/rpl_multi_engine.inc
+
+# InnoDB to ...
+
+connection master;
+alter table t1 engine=innodb;
+show create table t1;
+
+connection slave;
+alter table t1 engine=myisam;
+show create table t1;
+
+--source include/rpl_multi_engine.inc
+
+connection slave;
+alter table t1 engine=innodb;
+show create table t1;
+
+--source include/rpl_multi_engine.inc
+
+connection slave;
+alter table t1 engine=memory;
+show create table t1;
+
+--source include/rpl_multi_engine.inc
+
+# cleanup
+connection master;
+DROP TABLE t1;
+sync_slave_with_master;
+
+# End of 5.1 test case
diff --git a/mysql-test/t/rpl_multi_update.test b/mysql-test/t/rpl_multi_update.test
index f6a960434ad..cc147eb3263 100644
--- a/mysql-test/t/rpl_multi_update.test
+++ b/mysql-test/t/rpl_multi_update.test
@@ -1,49 +1,2 @@
-source include/master-slave.inc;
-
-CREATE TABLE t1 (
- a int unsigned not null auto_increment primary key,
- b int unsigned
-) ENGINE=MyISAM;
-
-CREATE TABLE t2 (
- a int unsigned not null auto_increment primary key,
- b int unsigned
-) ENGINE=MyISAM;
-
-INSERT INTO t1 VALUES (NULL, 0);
-INSERT INTO t1 SELECT NULL, 0 FROM t1;
-
-INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
-
-SELECT * FROM t1 ORDER BY a;
-SELECT * FROM t2 ORDER BY a;
-
-UPDATE t1, t2 SET t1.b = t2.b WHERE t1.a = t2.a;
-save_master_pos;
-connection slave;
-sync_with_master;
-
-# End of 4.1 tests
-
-# Check if updating 0 rows is binlogged (BUG#13348)
-
-connection master;
-delete from t1;
-delete from t2;
-insert into t1 values(1,1);
-insert into t2 values(1,1);
-
-sync_slave_with_master;
-# force a difference to see if master's multi-UPDATE will correct it
-update t1 set a=2;
-
-connection master;
-UPDATE t1, t2 SET t1.a = t2.a;
-
-sync_slave_with_master;
-select * from t1;
-select * from t2;
-
-connection master;
-drop table t1, t2;
-sync_slave_with_master;
+let $engine_type=MyISAM;
+-- source extra/rpl_tests/rpl_multi_update.test
diff --git a/mysql-test/t/rpl_multi_update2.test b/mysql-test/t/rpl_multi_update2.test
index a78b1901f51..484d8dd7633 100644
--- a/mysql-test/t/rpl_multi_update2.test
+++ b/mysql-test/t/rpl_multi_update2.test
@@ -1,62 +1,2 @@
-# Let's verify that multi-update is not always skipped by slave if
-# some replicate-* rules exist.
-# (BUG#7011)
-
-source include/master-slave.inc;
-
---disable_warnings
-drop table if exists t1,t2;
---enable_warnings
-
-CREATE TABLE t1 (
- a int unsigned not null auto_increment primary key,
- b int unsigned
-) ENGINE=MyISAM;
-
-CREATE TABLE t2 (
- a int unsigned not null auto_increment primary key,
- b int unsigned
-) ENGINE=MyISAM;
-
-INSERT INTO t1 VALUES (NULL, 0);
-INSERT INTO t1 SELECT NULL, 0 FROM t1;
-
-INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
-
-SELECT * FROM t1 ORDER BY a;
-SELECT * FROM t2 ORDER BY a;
-
-UPDATE t1, t2 SET t1.b = (t2.b+4) WHERE t1.a = t2.a;
-SELECT * FROM t1 ORDER BY a;
-SELECT * FROM t2 ORDER BY a;
-
-save_master_pos;
-connection slave;
-sync_with_master;
-SELECT * FROM t1 ORDER BY a;
-SELECT * FROM t2 ORDER BY a;
-
-connection master;
-drop table t1,t2;
-sync_slave_with_master;
-
-#
-# BUG#13236 multi-update with subquery & --replicate-ignore-table
-#
-reset master;
-
-connection master;
-CREATE TABLE t1 ( a INT );
-INSERT INTO t1 VALUES (0);
-UPDATE t1, (SELECT 3 as b) AS x SET t1.a = x.b;
-select * from t1;
-sync_slave_with_master;
-
-connection slave;
-select * from t1;
-
-connection master;
-drop table t1;
-sync_slave_with_master;
-
-# End of 4.1 tests
+let $engine_type=MyISAM;
+--source extra/rpl_tests/rpl_multi_update2.test
diff --git a/mysql-test/t/rpl_multi_update3.test b/mysql-test/t/rpl_multi_update3.test
index 36ac7a59cb3..d03f03e5638 100644
--- a/mysql-test/t/rpl_multi_update3.test
+++ b/mysql-test/t/rpl_multi_update3.test
@@ -1,220 +1,2 @@
-source include/master-slave.inc;
-
-##############################################################################
-#
-# Let's verify that multi-update with a subselect does not cause the slave to crash
-# (BUG#10442)
-#
---disable_query_log
-SELECT '-------- Test for BUG#9361 --------' as "";
---enable_query_log
-
-CREATE TABLE t1 (
- a int unsigned not null auto_increment primary key,
- b int unsigned
-) ENGINE=MyISAM;
-
-CREATE TABLE t2 (
- a int unsigned not null auto_increment primary key,
- b int unsigned
-) ENGINE=MyISAM;
-
-INSERT INTO t1 VALUES (NULL, 0);
-INSERT INTO t1 SELECT NULL, 0 FROM t1;
-
-INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
-
-SELECT * FROM t1 ORDER BY a;
-SELECT * FROM t2 ORDER BY a;
-
-UPDATE t2, (SELECT a FROM t1) AS t SET t2.b = t.a+5 ;
-SELECT * FROM t1 ORDER BY a;
-SELECT * FROM t2 ORDER BY a;
-
-sync_slave_with_master;
-connection slave;
-SELECT * FROM t1 ORDER BY a;
-SELECT * FROM t2 ORDER BY a;
-
-connection master;
-drop table t1,t2;
-
-##############################################################################
-#
-# Test for BUG#9361:
-# Subselects should work inside multi-updates
-#
---disable_query_log
-SELECT '-------- Test 1 for BUG#9361 --------' as "";
---enable_query_log
-
-connection master;
-
---disable_warnings
-DROP TABLE IF EXISTS t1;
-DROP TABLE IF EXISTS t2;
---enable_warnings
-
-CREATE TABLE t1 (
- a1 char(30),
- a2 int,
- a3 int,
- a4 char(30),
- a5 char(30)
-);
-
-CREATE TABLE t2 (
- b1 int,
- b2 char(30)
-);
-
-# Insert one row per table
-INSERT INTO t1 VALUES ('Yes', 1, NULL, 'foo', 'bar');
-INSERT INTO t2 VALUES (1, 'baz');
-
-# This should update the row in t1
-UPDATE t1 a, t2
- SET a.a1 = 'No'
- WHERE a.a2 =
- (SELECT b1
- FROM t2
- WHERE b2 = 'baz')
- AND a.a3 IS NULL
- AND a.a4 = 'foo'
- AND a.a5 = 'bar';
-
-sync_slave_with_master;
-connection slave;
-SELECT * FROM t1;
-SELECT * FROM t2;
-
-connection master;
-DROP TABLE t1, t2;
-
-##############################################################################
-#
-# Second test for BUG#9361
-#
-
---disable_query_log
-SELECT '-------- Test 2 for BUG#9361 --------' as "";
---enable_query_log
-
-connection master;
-
---disable_warnings
-DROP TABLE IF EXISTS t1;
-DROP TABLE IF EXISTS t2;
-DROP TABLE IF EXISTS t3;
---enable_warnings
-
-CREATE TABLE t1 (
- i INT,
- j INT,
- x INT,
- y INT,
- z INT
-);
-
-CREATE TABLE t2 (
- i INT,
- k INT,
- x INT,
- y INT,
- z INT
-);
-
-CREATE TABLE t3 (
- j INT,
- k INT,
- x INT,
- y INT,
- z INT
-);
-
-INSERT INTO t1 VALUES ( 1, 2,13,14,15);
-INSERT INTO t2 VALUES ( 1, 3,23,24,25);
-INSERT INTO t3 VALUES ( 2, 3, 1,34,35), ( 2, 3, 1,34,36);
-
-UPDATE t1 AS a
-INNER JOIN t2 AS b
- ON a.i = b.i
-INNER JOIN t3 AS c
- ON a.j = c.j AND b.k = c.k
-SET a.x = b.x,
- a.y = b.y,
- a.z = (
- SELECT sum(z)
- FROM t3
- WHERE y = 34
- )
-WHERE b.x = 23;
-
-sync_slave_with_master;
-connection slave;
-
-SELECT * FROM t1;
-
-connection master;
-DROP TABLE t1, t2, t3;
-
-##############################################################################
-#
-# BUG#12618
-#
-# TEST: Replication of a statement containing a join in a multi-update.
-
-DROP TABLE IF EXISTS t1;
-DROP TABLE IF EXISTS t2;
-
-CREATE TABLE t1 (
- idp int(11) NOT NULL default '0',
- idpro int(11) default NULL,
- price decimal(19,4) default NULL,
- PRIMARY KEY (idp)
-);
-
-CREATE TABLE t2 (
- idpro int(11) NOT NULL default '0',
- price decimal(19,4) default NULL,
- nbprice int(11) default NULL,
- PRIMARY KEY (idpro)
-);
-
-INSERT INTO t1 VALUES
- (1,1,'3.0000'),
- (2,2,'1.0000'),
- (3,1,'1.0000'),
- (4,1,'4.0000'),
- (5,3,'2.0000'),
- (6,2,'4.0000');
-
-INSERT INTO t2 VALUES
- (1,'0.0000',0),
- (2,'0.0000',0),
- (3,'0.0000',0);
-
-# This update sets t2 to the minimal prices for each product
-update
- t2
- join
- ( select idpro, min(price) as min_price, count(*) as nbr_price
- from t1
- where idpro>0 and price>0
- group by idpro
- ) as table_price
-on t2.idpro = table_price.idpro
-set t2.price = table_price.min_price,
- t2.nbprice = table_price.nbr_price;
-
-select "-- MASTER AFTER JOIN --" as "";
-select * from t1;
-select * from t2;
-
-sync_slave_with_master;
-
-select "-- SLAVE AFTER JOIN --" as "";
-select * from t1;
-select * from t2;
-
-# End of 4.1 tests
+let $engine_type=MyISAM;
+-- source extra/rpl_tests/rpl_multi_update3.test
diff --git a/mysql-test/t/rpl_openssl.test b/mysql-test/t/rpl_openssl.test
index e15eb9b179a..8a85443e71f 100644
--- a/mysql-test/t/rpl_openssl.test
+++ b/mysql-test/t/rpl_openssl.test
@@ -45,7 +45,7 @@ select * from t1;
#checking show slave status
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_MYPORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 6 # 7 # 8 # 9 # 10 # 11 # 16 # 22 # 23 # 33 #
show slave status;
#checking if replication works without ssl also performing clean up
@@ -58,7 +58,7 @@ save_master_pos;
connection slave;
sync_with_master;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR $MASTER_MYPORT MASTER_MYPORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 6 # 7 # 8 # 9 # 10 # 11 # 16 # 22 # 23 # 33 #
show slave status;
# End of 4.1 tests
diff --git a/mysql-test/t/rpl_redirect.test b/mysql-test/t/rpl_redirect.test
index beb18348b40..c001d85d2f8 100644
--- a/mysql-test/t/rpl_redirect.test
+++ b/mysql-test/t/rpl_redirect.test
@@ -14,7 +14,7 @@ sync_with_master;
#discover slaves
connection master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
SHOW SLAVE STATUS;
--replace_result $SLAVE_MYPORT SLAVE_PORT
SHOW SLAVE HOSTS;
diff --git a/mysql-test/t/rpl_relayrotate.test b/mysql-test/t/rpl_relayrotate.test
index 04f03367e20..99fd870e68f 100644
--- a/mysql-test/t/rpl_relayrotate.test
+++ b/mysql-test/t/rpl_relayrotate.test
@@ -1,75 +1,3 @@
-# When the relay log gets rotated while the I/O thread
-# is reading a transaction, the transaction spans on two or more
-# relay logs. If STOP SLAVE occurs while the SQL thread is
-# executing a part of the transaction in the non-first relay logs,
-# we test if START SLAVE will resume in the beginning of the
-# transaction (i.e., step back to the first relay log)
-
-# The slave is started with max_binlog_size=16384 bytes,
-# to force many rotations (approximately 30 rotations)
-
-source include/have_innodb.inc;
-source include/master-slave.inc;
-connection slave;
-stop slave;
-connection master;
---disable_warnings
-create table t1 (a int) engine=innodb;
---enable_warnings
-let $1=8000;
-disable_query_log;
-begin;
-while ($1)
-{
-# eval means expand $ expressions
- eval insert into t1 values( $1 );
- dec $1;
-}
-commit;
-# This will generate a 500kB master's binlog,
-# which corresponds to 30 slave's relay logs.
-enable_query_log;
-save_master_pos;
-connection slave;
-reset slave;
-start slave;
-# We wait 1 sec for the SQL thread to be somewhere in
-# the middle of the transaction, hopefully not in
-# the first relay log, and hopefully before the COMMIT.
-# Usually it stops when the SQL thread is around the 15th relay log.
-# We cannot use MASTER_POS_WAIT() as master's position
-# increases only when the slave executes the COMMIT.
-# Note that except when using Valgrind, 1 second is enough for the I/O slave
-# thread to fetch the whole master's binlog.
-sleep 1;
-stop slave;
-# We suppose the SQL thread stopped before COMMIT.
-# If so the transaction was rolled back
-# and the table is now empty.
-# Now restart
-start slave;
-# And see if the table contains '8000'
-# which proves that the transaction restarted at
-# the right place.
-# We must wait for the transaction to commit before
-# reading:
-sync_with_master;
-select max(a) from t1;
-connection master;
-
-# The following DROP is a very important cleaning task:
-# imagine the next test is run with --skip-innodb: it will do
-# DROP TABLE IF EXISTS t1; but this will delete the frm and leave
-# some data in the InnoDB datafile (because at that time mysqld
-# does not know about InnoDB : --skip-innodb). So if later in the
-# test suite a test wants to create an InnoDB table called t1, it
-# will fail with
-# InnoDB: Error: table t1 already exists in InnoDB internal
-# InnoDB: data dictionary. Have you deleted the .frm file etc
-drop table t1;
-# wait until this drop is executed on slave
-save_master_pos;
-connection slave;
-sync_with_master;
-
-# End of 4.1 tests
+-- source include/have_innodb.inc
+let $engine_type=innodb;
+-- source extra/rpl_tests/rpl_relayrotate.test
diff --git a/mysql-test/t/rpl_replicate_do.test b/mysql-test/t/rpl_replicate_do.test
index b8559af2394..5a2cb50d53a 100644
--- a/mysql-test/t/rpl_replicate_do.test
+++ b/mysql-test/t/rpl_replicate_do.test
@@ -1,6 +1,5 @@
# This test assumes we are ignoring updates on table t2, but doing
# updates on t1
-
source include/master-slave.inc;
--disable_warnings
drop table if exists t11;
@@ -33,7 +32,7 @@ connection slave;
sync_with_master;
# show slave status, just to see of it prints replicate-do-table
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 7 # 8 # 9 # 16 # 22 # 23 # 33 #
show slave status;
#
diff --git a/mysql-test/t/rpl_replicate_ignore_db-slave.opt b/mysql-test/t/rpl_replicate_ignore_db-slave.opt
new file mode 100644
index 00000000000..6e3aed44f78
--- /dev/null
+++ b/mysql-test/t/rpl_replicate_ignore_db-slave.opt
@@ -0,0 +1 @@
+--replicate_ignore_db=mysqltest1
diff --git a/mysql-test/t/rpl_replicate_ignore_db.test b/mysql-test/t/rpl_replicate_ignore_db.test
new file mode 100644
index 00000000000..bcfef919fad
--- /dev/null
+++ b/mysql-test/t/rpl_replicate_ignore_db.test
@@ -0,0 +1,30 @@
+# see if --replicate-ignore-db works
+
+--source include/master-slave.inc
+
+--disable_warnings
+drop database if exists mysqltest1;
+drop database if exists mysqltest2;
+--enable_warnings
+create database mysqltest1;
+create database mysqltest2;
+
+use mysqltest1;
+create table t1 (a int);
+insert into t1 values(1);
+sync_slave_with_master;
+--error 1146
+select * from mysqltest1.t1;
+
+connection master;
+use mysqltest2;
+create table t1 (a int);
+insert into t1 values(1);
+sync_slave_with_master;
+select * from mysqltest2.t1;
+
+# cleanup
+connection master;
+drop database mysqltest1;
+drop database mysqltest2;
+sync_slave_with_master;
diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test
index b125408d89e..1f5f4ebbed2 100644
--- a/mysql-test/t/rpl_rotate_logs.test
+++ b/mysql-test/t/rpl_rotate_logs.test
@@ -9,6 +9,9 @@
# changes
# - Test creating a duplicate key error and recover from it
+# Requires statement logging
+-- source include/have_binlog_format_statement.inc
+
connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
--disable_warnings
drop table if exists t1, t2, t3, t4;
@@ -56,7 +59,7 @@ create table t1 (s text);
insert into t1 values('Could not break slave'),('Tried hard');
sync_slave_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
select * from t1;
connection master;
@@ -109,7 +112,7 @@ show binary logs;
insert into t2 values (65);
sync_slave_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
select * from t2;
@@ -141,7 +144,7 @@ sync_with_master;
select * from t4;
--replace_result $MASTER_MYPORT MASTER_PORT
---replace_column 1 # 8 # 9 # 23 # 33 #
+--replace_column 1 # 8 # 9 # 16 # 23 # 33 #
show slave status;
# because of concurrent insert, the table may not be up to date
# if we do not lock
diff --git a/mysql-test/t/rpl_row_001.test b/mysql-test/t/rpl_row_001.test
new file mode 100644
index 00000000000..923ed16e8b3
--- /dev/null
+++ b/mysql-test/t/rpl_row_001.test
@@ -0,0 +1,2 @@
+let $engine_type=MYISAM;
+-- source extra/rpl_tests/rpl_row_001.test
diff --git a/mysql-test/t/rpl_row_4_bytes-master.opt b/mysql-test/t/rpl_row_4_bytes-master.opt
new file mode 100644
index 00000000000..0e1929507f7
--- /dev/null
+++ b/mysql-test/t/rpl_row_4_bytes-master.opt
@@ -0,0 +1 @@
+--loose-debug=d,"old_row_based_repl_4_byte_map_id_master"
diff --git a/mysql-test/t/rpl_row_4_bytes.test b/mysql-test/t/rpl_row_4_bytes.test
new file mode 100644
index 00000000000..26a4e2f5bfe
--- /dev/null
+++ b/mysql-test/t/rpl_row_4_bytes.test
@@ -0,0 +1,33 @@
+# This test is to make sure that slaves can read a binlog containining
+# table map ids stored in 4 bytes, even though we now store them in 6
+# bytes. This is for backward-compatibility.
+# If the slave does not detect that the master stores the table map id
+# in 4 bytes, slave will read 6 bytes, and so will read the 2 bytes of
+# flags at the place where there actually is data, so the test should
+# fail.
+
+-- source include/have_binlog_format_row.inc
+-- source include/have_debug.inc
+-- source include/master-slave.inc
+
+connection master;
+--disable_warnings
+drop database if exists mysqltest1;
+create database mysqltest1;
+--enable_warnings
+use mysqltest1;
+CREATE TABLE t1 (a char(3));
+CREATE TABLE t2 (a char(3));
+insert into t1 values("ANN");
+insert into t1 values("GUI");
+insert into t2 values("LIL");
+insert into t2 values("ABE");
+insert into t2 values("ANG");
+sync_slave_with_master;
+use mysqltest1;
+select * from t1 order by a;
+select * from t2 order by a;
+
+connection master;
+DROP TABLE t1,t2;
+sync_slave_with_master;
diff --git a/mysql-test/t/rpl_row_EE_err.test b/mysql-test/t/rpl_row_EE_err.test
new file mode 100644
index 00000000000..7895a66adfd
--- /dev/null
+++ b/mysql-test/t/rpl_row_EE_err.test
@@ -0,0 +1,2 @@
+let $engine_type=myisam;
+-- source extra/rpl_tests/rpl_row_EE_err.test
diff --git a/mysql-test/t/rpl_row_NOW.test b/mysql-test/t/rpl_row_NOW.test
new file mode 100644
index 00000000000..dba6fb16bb2
--- /dev/null
+++ b/mysql-test/t/rpl_row_NOW.test
@@ -0,0 +1,73 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/18/2005 #
+# Updated 08/30/2005 Added dumps and diff #
+#############################################################################
+#TEST: Taken and modfied from http://bugs.mysql.com/bug.php?id=12480 #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+create database if not exists mysqltest1;
+DROP TABLE IF EXISTS mysqltest1.t1;
+--enable_warnings
+
+
+# Begin test section 1
+CREATE TABLE mysqltest1.t1 (n MEDIUMINT NOT NULL AUTO_INCREMENT,
+ a TIMESTAMP DEFAULT '2005-05-05 01:01:01',
+ b TIMESTAMP DEFAULT '2005-05-05 01:01:01',
+ PRIMARY KEY(n));
+delimiter |;
+CREATE FUNCTION mysqltest1.f1() RETURNS TIMESTAMP
+BEGIN
+ DECLARE v1 INT DEFAULT 300;
+ WHILE v1 > 0 DO
+ SET v1 = v1 - 1;
+ END WHILE;
+ RETURN NOW();
+END|
+delimiter ;|
+
+INSERT INTO mysqltest1.t1 VALUES(NULL,NOW(),mysqltest1.f1());
+
+delimiter |;
+CREATE TRIGGER mysqltest1.trig1 BEFORE INSERT ON mysqltest1.t1
+FOR EACH ROW BEGIN
+ SET new.b = mysqltest1.f1();
+END|
+delimiter ;|
+
+INSERT INTO mysqltest1.t1 SET n = NULL, a = now();
+
+sync_slave_with_master;
+
+connection master;
+
+--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > ./var/tmp/NOW_master.sql
+--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > ./var/tmp/NOW_slave.sql
+
+# lets cleanup
+DROP TABLE IF EXISTS mysqltest1.t1;
+DROP FUNCTION mysqltest1.f1;
+
+# Lets compare. Note: If they match test will pass, if they do not match
+# the test will show that the diff statement failed and not reject file
+# will be created. You will need to go to the mysql-test dir and diff
+# the files your self to see what is not matching :-) The failed dump
+# files will be located in mysql-test/var/tmp
+
+exec diff ./var/tmp/NOW_master.sql ./var/tmp/NOW_slave.sql;
+
+# If all is good, when can cleanup our dump files.
+system rm ./var/tmp/NOW_master.sql;
+system rm ./var/tmp/NOW_slave.sql;
+
+sync_slave_with_master;
+# End of 5.1 test case
diff --git a/mysql-test/t/rpl_row_USER.test b/mysql-test/t/rpl_row_USER.test
new file mode 100644
index 00000000000..85eaf571d4a
--- /dev/null
+++ b/mysql-test/t/rpl_row_USER.test
@@ -0,0 +1,54 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/18/2005 #
+#############################################################################
+# TEST: To test the UUID() in rbr #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP DATABASE IF EXISTS mysqltest1;
+CREATE DATABASE mysqltest1;
+--enable_warnings
+
+# Section 1 test
+CREATE USER tester IDENTIFIED BY 'test';
+GRANT ALL ON mysqltest1.* TO 'tester'@'%' IDENTIFIED BY 'test';
+GRANT ALL ON mysqltest1.* TO ''@'localhost%';
+FLUSH PRIVILEGES;
+connect (m_1,localhost,tester,,mysqltest1);
+
+connection m_1;
+CREATE TABLE mysqltest1.t1 (a INT, users VARCHAR(255), PRIMARY KEY(a));
+INSERT INTO mysqltest1.t1 VALUES(1,USER());
+INSERT INTO mysqltest1.t1 VALUES(2,CURRENT_USER());
+delimiter |;
+create procedure mysqltest1.p1()
+begin
+ INSERT INTO mysqltest1.t1 VALUES(3,USER());
+ INSERT INTO mysqltest1.t1 VALUES(4,CURRENT_USER());
+end|
+delimiter ;|
+
+CALL mysqltest1.p1();
+connection master;
+SELECT * FROM mysqltest1.t1;
+sync_slave_with_master;
+SELECT * FROM mysqltest1.t1;
+
+connection master;
+# Lets cleanup
+#show binlog events;
+
+DROP DATABASE mysqltest1;
+REVOKE ALL ON mysqltest1.* FROM 'tester'@'%';
+REVOKE ALL ON mysqltest1.* FROM ''@'localhost%';
+
+sync_slave_with_master;
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_row_UUID.test b/mysql-test/t/rpl_row_UUID.test
new file mode 100644
index 00000000000..477cb31c504
--- /dev/null
+++ b/mysql-test/t/rpl_row_UUID.test
@@ -0,0 +1,2 @@
+let $engine_type=myisam;
+--source extra/rpl_tests/rpl_row_UUID.test
diff --git a/mysql-test/t/rpl_row_basic_2myisam.test b/mysql-test/t/rpl_row_basic_2myisam.test
new file mode 100644
index 00000000000..471f4d6dbc5
--- /dev/null
+++ b/mysql-test/t/rpl_row_basic_2myisam.test
@@ -0,0 +1,3 @@
+let $type= 'MYISAM' ;
+let $extra_index= ;
+-- source include/rpl_row_basic.inc
diff --git a/mysql-test/t/rpl_row_basic_3innodb-slave.opt b/mysql-test/t/rpl_row_basic_3innodb-slave.opt
new file mode 100644
index 00000000000..627becdbfb5
--- /dev/null
+++ b/mysql-test/t/rpl_row_basic_3innodb-slave.opt
@@ -0,0 +1 @@
+--innodb
diff --git a/mysql-test/t/rpl_row_basic_3innodb.test b/mysql-test/t/rpl_row_basic_3innodb.test
new file mode 100644
index 00000000000..b97f1543cc3
--- /dev/null
+++ b/mysql-test/t/rpl_row_basic_3innodb.test
@@ -0,0 +1,6 @@
+-- source include/have_innodb.inc
+
+let $type= 'INNODB' ;
+let $extra_index= ;
+-- source include/rpl_row_basic.inc
+
diff --git a/mysql-test/t/rpl_row_charset.test b/mysql-test/t/rpl_row_charset.test
new file mode 100644
index 00000000000..81658fab041
--- /dev/null
+++ b/mysql-test/t/rpl_row_charset.test
@@ -0,0 +1,2 @@
+let $engine_type=myisam;
+-- source extra/rpl_tests/rpl_row_charset.test
diff --git a/mysql-test/t/rpl_row_create_table.test b/mysql-test/t/rpl_row_create_table.test
new file mode 100644
index 00000000000..faabf489bba
--- /dev/null
+++ b/mysql-test/t/rpl_row_create_table.test
@@ -0,0 +1,108 @@
+# Testing table creations for row-based replication.
+
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+
+--disable_query_log
+--disable_warnings
+DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8,t9;
+--enable_warnings
+--enable_query_log
+
+# Set the default storage engine to different values on master and
+# slave. We need to stop the slave for the server variable to take
+# effect, since the variable is only read on start-up.
+connection slave;
+--disable_query_log
+set @storage_engine = @@global.storage_engine;
+STOP SLAVE;
+SET GLOBAL storage_engine=memory;
+START SLAVE;
+--enable_query_log
+
+connection master;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT, b INT) ENGINE=Merge;
+CREATE TABLE t3 (a INT, b INT) CHARSET=utf8;
+CREATE TABLE t4 (a INT, b INT) ENGINE=Merge CHARSET=utf8;
+--replace_column 1 # 4 # 5 #
+--query_vertical SHOW BINLOG EVENTS FROM 212
+--echo **** On Master ****
+--query_vertical SHOW CREATE TABLE t1
+--query_vertical SHOW CREATE TABLE t2
+--query_vertical SHOW CREATE TABLE t3
+sync_slave_with_master;
+--echo **** On Slave ****
+--query_vertical SHOW CREATE TABLE t1
+--query_vertical SHOW CREATE TABLE t2
+--query_vertical SHOW CREATE TABLE t3
+
+connection master;
+CREATE TABLE t5 (b INT, c INT) SELECT * FROM t3;
+
+CREATE TEMPORARY TABLE tt3 (a INT, b INT);
+INSERT INTO tt3 VALUES (1,2), (2,4), (3,6), (4,2), (5,10), (6,12);
+CREATE TABLE t6 (b INT, c INT) SELECT * FROM tt3;
+--echo **** On Master ****
+--query_vertical SHOW CREATE TABLE t5
+SELECT * FROM t5 ORDER BY a,b,c;
+--query_vertical SHOW CREATE TABLE t6
+SELECT * FROM t6 ORDER BY a,b,c;
+sync_slave_with_master;
+--echo **** On Slave ****
+--query_vertical SHOW CREATE TABLE t5
+SELECT * FROM t5 ORDER BY a,b,c;
+--query_vertical SHOW CREATE TABLE t6
+SELECT * FROM t6 ORDER BY a,b,c;
+
+connection master;
+# Test for erroneous constructions
+--error 1062
+CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3;
+# Shouldn't be written to the binary log
+SHOW BINLOG EVENTS FROM 1256;
+
+# Test that INSERT-SELECT works the same way as for SBR.
+CREATE TABLE t7 (a INT, b INT UNIQUE);
+--error 1062
+INSERT INTO t7 SELECT a,b FROM tt3;
+SELECT * FROM t7 ORDER BY a,b;
+# Should be written to the binary log
+SHOW BINLOG EVENTS FROM 1256;
+sync_slave_with_master;
+SELECT * FROM t7 ORDER BY a,b;
+
+connection master;
+CREATE TEMPORARY TABLE tt4 (a INT, b INT);
+INSERT INTO tt4 VALUES (4,8), (5,10), (6,12);
+BEGIN;
+INSERT INTO t7 SELECT a,b FROM tt4;
+ROLLBACK;
+SHOW BINLOG EVENTS FROM 1452;
+SELECT * FROM t7 ORDER BY a,b;
+sync_slave_with_master;
+SELECT * FROM t7 ORDER BY a,b;
+
+connection master;
+CREATE TABLE t8 LIKE t4;
+CREATE TABLE t9 LIKE tt4;
+CREATE TEMPORARY TABLE tt5 LIKE t4;
+CREATE TEMPORARY TABLE tt6 LIKE tt4;
+--echo **** On Master ****
+--query_vertical SHOW CREATE TABLE t8
+--query_vertical SHOW CREATE TABLE t9
+SHOW BINLOG EVENTS FROM 1548;
+sync_slave_with_master;
+--echo **** On Slave ****
+--query_vertical SHOW CREATE TABLE t8
+--query_vertical SHOW CREATE TABLE t9
+
+connection master;
+--disable_query_log
+DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8,t9;
+sync_slave_with_master;
+# Here we reset the value of the default storage engine
+STOP SLAVE;
+SET GLOBAL storage_engine=@storage_engine;
+START SLAVE;
+--enable_query_log
diff --git a/mysql-test/t/rpl_row_ddl.test b/mysql-test/t/rpl_row_ddl.test
new file mode 100644
index 00000000000..2433d6a83a7
--- /dev/null
+++ b/mysql-test/t/rpl_row_ddl.test
@@ -0,0 +1,35 @@
+######################## rpl_ddl.test ########################
+# #
+# DDL statements (sometimes with implicit COMMIT) executed #
+# by the master and it's propagation into the slave #
+# #
+##############################################################
+
+#
+# NOTE, PLEASE BE CAREFUL, WHEN MODIFYING THE TESTS !!
+#
+# 1. !All! objects to be dropped, renamed, altered ... must be created
+# in AUTOCOMMIT= 1 mode before AUTOCOMMIT is set to 0 and the test
+# sequences start.
+#
+# 2. Never use a test object, which was direct or indirect affected by a
+# preceeding test sequence again.
+# Except table d1.t1 where ONLY DML is allowed.
+#
+# If one preceeding test sequence hits a (sometimes not good visible,
+# because the sql error code of the statement might be 0) bug
+# and these rules are ignored, a following test sequence might earn ugly
+# effects like failing 'sync_slave_with_master', crashes of the slave or
+# abort of the test case etc..
+#
+# 3. The assignment of the DDL command to be tested to $my_stmt can
+# be a bit difficult. "'" must be avoided, because the test
+# routine "include/rpl_stmt_seq.inc" performs a
+# eval SELECT CONCAT('######## ','$my_stmt',' ########') as "";
+#
+
+--source include/have_innodb.inc
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+let $engine_type= "InnoDB";
+-- source extra/rpl_tests/rpl_ddl.test
diff --git a/mysql-test/t/rpl_row_delayed_ins.test b/mysql-test/t/rpl_row_delayed_ins.test
new file mode 100644
index 00000000000..b898a9a120a
--- /dev/null
+++ b/mysql-test/t/rpl_row_delayed_ins.test
@@ -0,0 +1,2 @@
+let $engine_type=myisam;
+-- source extra/rpl_tests/rpl_row_delayed_ins.test
diff --git a/mysql-test/t/rpl_row_drop.test b/mysql-test/t/rpl_row_drop.test
new file mode 100644
index 00000000000..816bd108b88
--- /dev/null
+++ b/mysql-test/t/rpl_row_drop.test
@@ -0,0 +1,47 @@
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+# Bug#12415: DROP of temporary table on master stops slave
+connection master;
+--echo **** On Master ****
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TEMPORARY TABLE t2 (a int, b int);
+SHOW TABLES;
+sync_slave_with_master;
+--echo **** On Slave ****
+SHOW TABLES;
+connection master;
+--echo **** On Master ****
+DROP TABLE t2; # Dropping the temporary table
+SHOW TABLES;
+sync_slave_with_master;
+--echo **** On Slave ****
+SHOW TABLES; # There should be two tables on the slave
+
+connection master;
+--echo **** On Master ****
+CREATE TEMPORARY TABLE t2 (a int, b int);
+SHOW TABLES;
+sync_slave_with_master;
+--echo **** On Slave ****
+SHOW TABLES;
+connection master;
+--echo **** On Master ****
+# Should drop the non-temporary table t1 and the temporary table t2
+DROP TABLE t1,t2;
+let $VERSION=`select version()`;
+--replace_result $VERSION VERSION
+SHOW BINLOG EVENTS;
+SHOW TABLES;
+sync_slave_with_master;
+--echo **** On Slave ****
+SHOW TABLES;
+
+--disable_query_log
+--disable_warnings
+connection master;
+DROP TABLE IF EXISTS t2;
+sync_slave_with_master;
+--enable_warnings
+--enable_query_log
diff --git a/mysql-test/t/rpl_row_err_daisychain-master.opt b/mysql-test/t/rpl_row_err_daisychain-master.opt
new file mode 100644
index 00000000000..83ed8522e72
--- /dev/null
+++ b/mysql-test/t/rpl_row_err_daisychain-master.opt
@@ -0,0 +1 @@
+--binlog-format=row
diff --git a/mysql-test/t/rpl_row_err_daisychain-slave.opt b/mysql-test/t/rpl_row_err_daisychain-slave.opt
new file mode 100644
index 00000000000..4cb7a31da81
--- /dev/null
+++ b/mysql-test/t/rpl_row_err_daisychain-slave.opt
@@ -0,0 +1 @@
+--binlog-format=statement --log-slave-updates
diff --git a/mysql-test/t/rpl_row_flsh_tbls.test b/mysql-test/t/rpl_row_flsh_tbls.test
new file mode 100644
index 00000000000..72babb4e21f
--- /dev/null
+++ b/mysql-test/t/rpl_row_flsh_tbls.test
@@ -0,0 +1,6 @@
+# depends on the binlog output
+-- source include/have_binlog_format_row.inc
+
+let $rename_event_pos= 615;
+-- source extra/rpl_tests/rpl_flsh_tbls.test
+
diff --git a/mysql-test/t/rpl_row_func001.test b/mysql-test/t/rpl_row_func001.test
new file mode 100644
index 00000000000..6c538017911
--- /dev/null
+++ b/mysql-test/t/rpl_row_func001.test
@@ -0,0 +1,56 @@
+#############################################################################
+# This test is being created to test out the non deterministic items with #
+# row based replication. #
+# Original Author: JBM #
+# Original Date: Aug/10/2005 #
+# Update: 08/29/2005 change name to initails #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+--error 0,1305
+DROP FUNCTION test.f1;
+DROP TABLE IF EXISTS test.t1;
+
+
+--enable_warnings
+
+# Section 1 test from bug #12487 Uses stored function to insert rows to see what is replicated.
+
+create table test.t1 (a int, PRIMARY KEY(a));
+
+delimiter //;
+create function test.f1(i int) returns int
+begin
+insert into test.t1 values(i);
+return 0;
+end//
+delimiter ;//
+
+select test.f1(1);
+select test.f1(2);
+select * from test.t1;
+
+save_master_pos;
+sync_slave_with_master;
+connection slave;
+#show create table test.t1;
+select * from test.t1;
+
+connection master;
+
+#Used for debugging
+#show binlog events;
+
+# Lets cleanup
+
+DROP FUNCTION test.f1;
+DROP TABLE test.t1;
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_row_func002.test b/mysql-test/t/rpl_row_func002.test
new file mode 100644
index 00000000000..3812eac201c
--- /dev/null
+++ b/mysql-test/t/rpl_row_func002.test
@@ -0,0 +1,104 @@
+#############################################################################
+# This test is being created to test out the non deterministic items with #
+# row based replication. #
+# Original Author: JBM #
+# Original Date: Aug/10/2005 #
+# Update: 08/29/2005 Turn on diff #
+#############################################################################
+# Note: Many lines are commented out in this test case. These were used for #
+# creating the test case and debugging and are being left for #
+# debugging, but they can not be used for the regular testing as the #
+# Time changes and is not deteministic, so instead we dump both the #
+# master and slave and diff the dumps. If the dumps differ then the #
+# test case will fail. To run during diff failuers, comment out the #
+# diff. #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+--error 0,1305
+DROP FUNCTION test.f1;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+
+--enable_warnings
+
+# Section 1 test from Peter G. This test changes uses a stored function to update rows and return the timestamp. We change the value of the time stamp on the master to see what is replicated.
+
+CREATE TABLE test.t1 (a INT NOT NULL AUTO_INCREMENT, t TIMESTAMP, t2 TIMESTAMP, PRIMARY KEY(a));
+CREATE TABLE test.t2 (a INT NOT NULL AUTO_INCREMENT, t TIMESTAMP, t2 TIMESTAMP, PRIMARY KEY(a));
+
+delimiter //;
+create function test.f1() RETURNS TIMESTAMP
+BEGIN
+UPDATE test.t1 SET t = CURRENT_TIMESTAMP;
+RETURN CURRENT_TIMESTAMP;
+END//
+delimiter ;//
+
+INSERT INTO test.t2 VALUES (null,f1(),CURRENT_TIMESTAMP);
+#select * from test.t1;
+#save_master_pos;
+#sync_slave_with_master;
+#connection slave;
+#select * from test.t1;
+#connection master;
+
+
+SET TIMESTAMP=2;
+INSERT INTO test.t2 VALUES (null,f1(),CURRENT_TIMESTAMP);
+#select * from test.t1;
+#save_master_pos;
+#sync_slave_with_master;
+#connection slave;
+#select * from test.t1;
+#connection master;
+
+#sleep 3;
+SET TIMESTAMP=1;
+INSERT INTO test.t2 VALUES (null,f1(),CURRENT_TIMESTAMP);
+#select * from test.t1;
+#save_master_pos;
+#sync_slave_with_master;
+#connection slave;
+#select * from test.t1;
+#connection master;
+
+
+SET TIMESTAMP=333300000;
+INSERT INTO test.t2 VALUES (null,f1(),CURRENT_TIMESTAMP);
+
+# We need a sync to ensure that the slave has caught up before
+# dumping the database.
+sync_slave_with_master;
+
+connection master;
+#Used for debugging
+#show binlog events;
+
+# time to dump the databases and so we can see if they match
+
+--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/func002_master.sql
+--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/func002_slave.sql
+
+# First lets cleanupi
+DROP FUNCTION test.f1;
+DROP TABLE test.t1;
+
+
+# the test will show that the diff statement failed and no reject file
+# will be created. You will need to go to the mysql-test dir and diff
+# the files your self to see what is not matching :-). The files are located
+# in mysql-test/var/tmp
+
+exec diff ./var/tmp/func002_master.sql ./var/tmp/func002_slave.sql;
+
+
+# End of 5.0 test case
+
diff --git a/mysql-test/t/rpl_row_func003.test b/mysql-test/t/rpl_row_func003.test
new file mode 100644
index 00000000000..bac13698620
--- /dev/null
+++ b/mysql-test/t/rpl_row_func003.test
@@ -0,0 +1,6 @@
+###################################
+# Wrapper for rpl_row_func003.test#
+###################################
+-- source include/have_innodb.inc
+let $engine_type=INNODB;
+-- source extra/rpl_tests/rpl_row_func003.test
diff --git a/mysql-test/t/rpl_row_inexist_tbl.test b/mysql-test/t/rpl_row_inexist_tbl.test
new file mode 100644
index 00000000000..e77ea216571
--- /dev/null
+++ b/mysql-test/t/rpl_row_inexist_tbl.test
@@ -0,0 +1,27 @@
+# Test to see what slave says when master is updating a table it does
+# not have
+--source include/have_binlog_format_row.inc
+
+source include/master-slave.inc;
+
+connection master;
+create table t1 (a int not null primary key);
+sync_slave_with_master;
+drop table t1;
+
+connection master;
+insert into t1 values (1);
+insert into t1 values (2);
+
+connection slave;
+# slave should have stopped because can't find table
+wait_for_slave_to_stop;
+# see if we have a good error message:
+--replace_result $MASTER_MYPORT MASTER_MYPORT
+--replace_column 1 # 7 # 8 # 9 # 23 # 33 #
+--vertical_results
+show slave status;
+
+# cleanup
+connection master;
+drop table t1;
diff --git a/mysql-test/t/rpl_log-master.opt b/mysql-test/t/rpl_row_log-master.opt
index e0d075c3fbd..e0d075c3fbd 100644
--- a/mysql-test/t/rpl_log-master.opt
+++ b/mysql-test/t/rpl_row_log-master.opt
diff --git a/mysql-test/t/rpl_log-slave.opt b/mysql-test/t/rpl_row_log-slave.opt
index 8b137891791..8b137891791 100644
--- a/mysql-test/t/rpl_log-slave.opt
+++ b/mysql-test/t/rpl_row_log-slave.opt
diff --git a/mysql-test/t/rpl_row_log.test b/mysql-test/t/rpl_row_log.test
new file mode 100644
index 00000000000..290a08ff75a
--- /dev/null
+++ b/mysql-test/t/rpl_row_log.test
@@ -0,0 +1,4 @@
+# Requires statement logging
+-- source include/have_binlog_format_row.inc
+-- source extra/rpl_tests/rpl_log.test
+
diff --git a/mysql-test/t/rpl_row_max_relay_size.test b/mysql-test/t/rpl_row_max_relay_size.test
new file mode 100644
index 00000000000..a4b762059b3
--- /dev/null
+++ b/mysql-test/t/rpl_row_max_relay_size.test
@@ -0,0 +1,9 @@
+# Test of options max_binlog_size and max_relay_log_size and
+# how they act (if max_relay_log_size == 0, use max_binlog_size
+# for relay logs too).
+# Test of manual relay log rotation with FLUSH LOGS.
+
+# Requires statement logging
+-- source include/have_binlog_format_row.inc
+-- source extra/rpl_tests/rpl_max_relay_size.test
+
diff --git a/mysql-test/t/rpl_row_multi_update3.test b/mysql-test/t/rpl_row_multi_update3.test
new file mode 100644
index 00000000000..fc606b2f134
--- /dev/null
+++ b/mysql-test/t/rpl_row_multi_update3.test
@@ -0,0 +1,2 @@
+let $engine_type=MyISAM;
+-- source extra/rpl_tests/rpl_row_multi_update3.test
diff --git a/mysql-test/t/rpl_row_mystery22.test b/mysql-test/t/rpl_row_mystery22.test
new file mode 100644
index 00000000000..9933fec22fc
--- /dev/null
+++ b/mysql-test/t/rpl_row_mystery22.test
@@ -0,0 +1,45 @@
+# Originally taken from rpl_mystery22.test,
+# but this row-based-replication test has a totally different spirit:
+# slave will not stop because of dup key,
+# instead we test if it does overwrite the dup key
+# as expected.
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+# first, cause a duplicate key problem on the slave
+create table t1(n int auto_increment primary key, s char(10));
+sync_slave_with_master;
+insert into t1 values (2,'old');
+connection master;
+insert into t1 values(NULL,'new');
+insert into t1 values(NULL,'new');
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from t1 order by n;
+delete from t1 where n = 2;
+--disable_warnings
+start slave;
+--enable_warnings
+sync_with_master;
+stop slave;
+connection master;
+create table t2(n int);
+drop table t2;
+insert into t1 values(NULL,'new');
+# what happens when we delete a row which does not exist on slave?
+set sql_log_bin=0;
+insert into t1 values(NULL,'new');
+set sql_log_bin=1;
+delete from t1 where n=4;
+save_master_pos;
+connection slave;
+--disable_warnings
+start slave;
+--enable_warnings
+sync_with_master;
+select * from t1 order by n;
+#clean up
+connection master;
+drop table t1;
+sync_slave_with_master;
diff --git a/mysql-test/t/rpl_row_reset_slave.test b/mysql-test/t/rpl_row_reset_slave.test
new file mode 100644
index 00000000000..a970c161153
--- /dev/null
+++ b/mysql-test/t/rpl_row_reset_slave.test
@@ -0,0 +1,5 @@
+# TBF - difference in row level logging
+# Temp tables are not replicated in rbr, but it is still good to hit rbr with everthing
+-- source include/have_binlog_format_row.inc
+-- source extra/rpl_tests/rpl_reset_slave.test
+
diff --git a/mysql-test/t/rpl_rewrite_db-slave.opt b/mysql-test/t/rpl_row_rewrt_db-slave.opt
index a462ad19ba0..a462ad19ba0 100644
--- a/mysql-test/t/rpl_rewrite_db-slave.opt
+++ b/mysql-test/t/rpl_row_rewrt_db-slave.opt
diff --git a/mysql-test/t/rpl_rewrite_db.test b/mysql-test/t/rpl_row_rewrt_db.test
index 1e8e5a992d8..8781b361d87 100644
--- a/mysql-test/t/rpl_rewrite_db.test
+++ b/mysql-test/t/rpl_row_rewrt_db.test
@@ -1,4 +1,7 @@
-source include/master-slave.inc;
+# TBF - difference in row level logging
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
--disable_warnings
drop database if exists mysqltest1;
--enable_warnings
@@ -78,4 +81,3 @@ drop database rewrite;
connection master;
drop table t1;
-# End of 4.1 tests
diff --git a/mysql-test/t/rpl_sp-master.opt b/mysql-test/t/rpl_row_sp000-master.opt
index 709a224fd92..709a224fd92 100644
--- a/mysql-test/t/rpl_sp-master.opt
+++ b/mysql-test/t/rpl_row_sp000-master.opt
diff --git a/mysql-test/t/rpl_row_sp000-slave.opt b/mysql-test/t/rpl_row_sp000-slave.opt
new file mode 100644
index 00000000000..709a224fd92
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp000-slave.opt
@@ -0,0 +1 @@
+--log_bin_trust_routine_creators=0
diff --git a/mysql-test/t/rpl_row_sp000.test b/mysql-test/t/rpl_row_sp000.test
new file mode 100644
index 00000000000..e591cb054fc
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp000.test
@@ -0,0 +1,323 @@
+# row-based and statement have expected binlog difference in result files
+-- source include/have_binlog_format_row.inc
+
+# Test of replication of stored procedures in row-based replication.
+# Initially copied from the statement-based version rpl_stm_sp.test.
+
+# Note that in the .opt files we still use the old variable name
+# log-bin-trust-routine-creators so that this test checks that it's
+# still accepted (this test also checks that the new name is
+# accepted). The old name could be removed in 5.1 or 6.0.
+
+source include/master-slave.inc;
+
+# we need a db != test, where we don't have automatic grants
+--disable_warnings
+drop database if exists mysqltest1;
+--enable_warnings
+create database mysqltest1;
+use mysqltest1;
+create table t1 (a varchar(100));
+sync_slave_with_master;
+use mysqltest1;
+
+# ********************** PART 1 : STORED PROCEDURES ***************
+
+# Does the same proc as on master get inserted into mysql.proc ?
+# (all same properties)
+
+connection master;
+
+delimiter |;
+create procedure foo()
+begin
+ declare b int;
+ set b = 8;
+ insert into t1 values (b);
+ insert into t1 values (unix_timestamp());
+end|
+delimiter ;|
+
+# we replace columns having times
+# (even with fixed timestamp displayed time may changed based on TZ)
+--replace_result localhost.localdomain localhost 127.0.0.1 localhost
+--replace_column 13 # 14 #
+select * from mysql.proc where name='foo' and db='mysqltest1';
+sync_slave_with_master;
+--replace_result localhost.localdomain localhost 127.0.0.1 localhost
+--replace_column 13 # 14 #
+select * from mysql.proc where name='foo' and db='mysqltest1';
+
+connection master;
+# see if timestamp used in SP on slave is same as on master
+set timestamp=1000000000;
+call foo();
+select * from t1;
+sync_slave_with_master;
+select * from t1;
+
+# Now a SP which is not updating tables
+
+connection master;
+delete from t1;
+create procedure foo2()
+ not deterministic
+ select * from mysqltest1.t1;
+call foo2();
+
+alter procedure foo2 contains sql;
+
+# SP with definer's right
+
+drop table t1;
+create table t1 (a int);
+create table t2 (a int);
+
+create procedure foo3()
+ deterministic
+ insert into t1 values (15);
+
+# let's create a non-privileged user
+grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1;
+grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1;
+grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1;
+
+connect (con1,127.0.0.1,zedjzlcsjhd,,mysqltest1,$MASTER_MYPORT,);
+connection con1;
+
+# this routine will fail in the second INSERT because of privileges
+delimiter |;
+create procedure foo4()
+ deterministic
+ begin
+ insert into t2 values(3);
+ insert into t1 values (5);
+ end|
+
+delimiter ;|
+
+# I add ,0 so that it does not print the error in the test output,
+# because this error is hostname-dependent
+--error 1142,0
+call foo4(); # invoker has no INSERT grant on table t1 => failure
+
+connection master;
+call foo3(); # success (definer == root)
+show warnings;
+
+--error 1142,0
+call foo4(); # definer's rights => failure
+
+# we test replication of ALTER PROCEDURE
+alter procedure foo4 sql security invoker;
+call foo4(); # invoker's rights => success
+show warnings;
+
+# Note that half-failed procedure calls are ok with binlogging;
+# if we compare t2 on master and slave we see they are identical:
+
+select * from t1;
+select * from t2;
+sync_slave_with_master;
+select * from t1;
+select * from t2;
+
+# Let's check another failing-in-the-middle procedure
+connection master;
+delete from t2;
+alter table t2 add unique (a);
+
+drop procedure foo4;
+delimiter |;
+create procedure foo4()
+ deterministic
+ begin
+ insert into t2 values(20),(20);
+ end|
+
+delimiter ;|
+
+--error 1062
+call foo4();
+show warnings;
+
+select * from t2;
+sync_slave_with_master;
+# check that this failed-in-the-middle replicated right:
+select * from t2;
+
+# Test of DROP PROCEDURE
+
+--replace_result localhost.localdomain localhost 127.0.0.1 localhost
+--replace_column 13 # 14 #
+select * from mysql.proc where name="foo4" and db='mysqltest1';
+connection master;
+drop procedure foo4;
+select * from mysql.proc where name="foo4" and db='mysqltest1';
+sync_slave_with_master;
+select * from mysql.proc where name="foo4" and db='mysqltest1';
+
+# Test of a procedure and function containing UUID() is done in
+# rpl_row_UUID.
+
+
+# ********************** PART 2 : FUNCTIONS ***************
+
+connection master;
+drop procedure foo;
+drop procedure foo2;
+drop procedure foo3;
+
+delimiter |;
+create function fn1(x int)
+ returns int
+ deterministic
+begin
+ insert into t1 values (x);
+ return x+2;
+end|
+
+delimiter ;|
+delete t1,t2 from t1,t2;
+select fn1(20);
+insert into t2 values(fn1(21));
+select * from t1;
+select * from t2;
+sync_slave_with_master;
+select * from t1;
+select * from t2;
+
+connection master;
+delimiter |;
+
+drop function fn1;
+
+create function fn1()
+ returns int
+begin
+ return unix_timestamp();
+end|
+
+delimiter ;|
+# Just to test ALTER FUNCTION
+alter function fn1 no sql;
+delete from t1;
+set timestamp=1000000000;
+insert into t1 values(fn1());
+
+connection con1;
+
+delimiter |;
+create function fn2()
+ returns int
+ no sql
+begin
+ return unix_timestamp();
+end|
+delimiter ;|
+
+connection master;
+
+delimiter |;
+create function fn3()
+ returns int
+ not deterministic
+ reads sql data
+begin
+ return 0;
+end|
+delimiter ;|
+
+select fn3();
+
+--replace_result localhost.localdomain localhost 127.0.0.1 localhost
+--replace_column 13 # 14 #
+select * from mysql.proc where db='mysqltest1';
+select * from t1;
+
+sync_slave_with_master;
+use mysqltest1;
+select * from t1;
+--replace_result localhost.localdomain localhost 127.0.0.1 localhost
+--replace_column 13 # 14 #
+select * from mysql.proc where db='mysqltest1';
+
+# Let's check a failing-in-the-middle function
+connection master;
+delete from t2;
+alter table t2 add unique (a);
+
+drop function fn1;
+
+delimiter |;
+create function fn1()
+ returns int
+begin
+ insert into t2 values(20),(20);
+ return 10;
+end|
+
+delimiter ;|
+
+--error 1062
+select fn1();
+
+select * from t2;
+sync_slave_with_master;
+
+# check that this failed-in-the-middle replicated right:
+select * from t2;
+
+# ********************** PART 3 : TRIGGERS ***************
+
+connection con1;
+--error 1227
+create trigger trg before insert on t1 for each row set new.a= 10;
+
+connection master;
+delete from t1;
+# TODO: when triggers can contain an update, test that this update
+# does not go into binlog.
+# I'm not setting user vars in the trigger, because replication of user vars
+# would take care of propagating the user var's value to slave, so even if
+# the trigger was not executed on slave it would not be discovered.
+create trigger trg before insert on t1 for each row set new.a= 10;
+insert into t1 values (1);
+select * from t1;
+sync_slave_with_master;
+select * from t1;
+
+connection master;
+delete from t1;
+drop trigger trg;
+insert into t1 values (1);
+select * from t1;
+--replace_column 2 # 5 #
+show binlog events in 'master-bin.000001' from 102;
+sync_slave_with_master;
+select * from t1;
+
+
+#
+# Test for bug #13969 "Routines which are replicated from master can't be
+# executed on slave".
+#
+connection master;
+create procedure foo()
+ not deterministic
+ reads sql data
+ select * from t1;
+sync_slave_with_master;
+# This should not fail
+call foo();
+connection master;
+drop procedure foo;
+sync_slave_with_master;
+
+
+# Clean up
+connection master;
+drop function fn1;
+drop database mysqltest1;
+drop user "zedjzlcsjhd"@127.0.0.1;
+sync_slave_with_master;
diff --git a/mysql-test/t/rpl_row_sp001.test b/mysql-test/t/rpl_row_sp001.test
new file mode 100644
index 00000000000..f6ac18dc78b
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp001.test
@@ -0,0 +1,144 @@
+#############################################################################
+# This test is being created to test out the non deterministic items with #
+# row based replication. #
+# Original Author: JBM #
+# Original Date: Aug/09/2005 #
+# Updated: Aug/29/2005
+#############################################################################
+# Test: Includes two stored procedure tests. First test uses SP to insert #
+# values from RAND() and NOW() into a table. #
+# The second test uses SP with CASE structure to decide what to text #
+# to update a given table with. #
+############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+-- disable_query_log
+-- disable_result_log
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+
+-- enable_query_log
+-- enable_result_log
+
+# Begin test section 1 for non deterministic SP
+let $message=<Begin test section 1 (non deterministic SP)>;
+--source include/show_msg.inc
+
+create table test.t1 (n MEDIUMINT NOT NULL AUTO_INCREMENT, f FLOAT, d DATETIME, PRIMARY KEY(n));
+
+delimiter //;
+create procedure test.p1()
+begin
+ INSERT INTO test.t1 (f,d) VALUES (RAND(),NOW());
+end//
+delimiter ;//
+
+# show binlog events;
+
+-- disable_query_log
+-- disable_result_log
+let $1=10;
+while ($1)
+{
+ call test.p1();
+ sleep 1;
+ dec $1;
+}
+-- enable_result_log
+-- enable_query_log
+
+## Used for debugging
+#show binlog events;
+#select * from test.t1;
+#sync_slave_with_master;
+#select * from test.t1;
+#connection master;
+
+let $message=<End test section 1 (non deterministic SP)>;
+--source include/show_msg.inc
+
+
+CREATE TABLE test.t2 (a INT NOT NULL AUTO_INCREMENT, t CHAR(4), PRIMARY KEY(a));
+
+delimiter //;
+CREATE PROCEDURE test.p2(n int)
+begin
+CASE n
+WHEN 1 THEN
+ UPDATE test.t2 set t ='Tex';
+WHEN 2 THEN
+ UPDATE test.t2 set t ='SQL';
+ELSE
+ UPDATE test.t2 set t ='NONE';
+END CASE;
+end//
+delimiter ;//
+
+INSERT INTO test.t2 VALUES(NULL,'NEW'),(NULL,'NEW'),(NULL,'NEW'),(NULL,'NEW');
+
+select * from test.t2;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from test.t2;
+
+connection master;
+call test.p2(1);
+select * from test.t2;
+sync_slave_with_master;
+select * from test.t2;
+
+
+connection master;
+call test.p2(2);
+select * from test.t2;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from test.t2;
+
+connection master;
+call test.p2(3);
+select * from test.t2;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from test.t2;
+
+##Used for debugging
+#show binlog events;
+
+# time to dump the databases and so we can see if they match
+
+--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/sp001_master.sql
+--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/sp001_slave.sql
+
+# First lets cleanup
+
+DROP PROCEDURE test.p1;
+DROP PROCEDURE test.p2;
+DROP TABLE test.t1;
+DROP TABLE test.t2;
+
+# Lets compare. Note: If they match test will pass, if they do not match
+# the test will show that the diff statement failed and not reject file
+# will be created. You will need to go to the mysql-test dir and diff
+# the files your self to see what is not matching :-) Failed dump files
+# will be located in mysql-test/var/tmp
+
+--exec diff ./var/tmp/sp001_master.sql ./var/tmp/sp001_slave.sql;
+
+# If all is good, when can cleanup our dump files.
+system rm ./var/tmp/sp001_master.sql;
+system rm ./var/tmp/sp001_slave.sql;
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_row_sp002_innodb-master.opt b/mysql-test/t/rpl_row_sp002_innodb-master.opt
new file mode 100644
index 00000000000..627becdbfb5
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp002_innodb-master.opt
@@ -0,0 +1 @@
+--innodb
diff --git a/mysql-test/t/rpl_row_sp002_innodb-slave.opt b/mysql-test/t/rpl_row_sp002_innodb-slave.opt
new file mode 100644
index 00000000000..627becdbfb5
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp002_innodb-slave.opt
@@ -0,0 +1 @@
+--innodb
diff --git a/mysql-test/t/rpl_row_sp002_innodb.test b/mysql-test/t/rpl_row_sp002_innodb.test
new file mode 100644
index 00000000000..a00d9ae2327
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp002_innodb.test
@@ -0,0 +1,6 @@
+#################################
+# Wrapper for rpl_row_sp002.test#
+#################################
+-- source include/have_innodb.inc
+let $engine_type=INNODB;
+-- source extra/rpl_tests/rpl_row_sp002.test
diff --git a/mysql-test/t/rpl_row_sp003-master.opt b/mysql-test/t/rpl_row_sp003-master.opt
new file mode 100644
index 00000000000..627becdbfb5
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp003-master.opt
@@ -0,0 +1 @@
+--innodb
diff --git a/mysql-test/t/rpl_row_sp003-slave.opt b/mysql-test/t/rpl_row_sp003-slave.opt
new file mode 100644
index 00000000000..627becdbfb5
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp003-slave.opt
@@ -0,0 +1 @@
+--innodb
diff --git a/mysql-test/t/rpl_row_sp003.test b/mysql-test/t/rpl_row_sp003.test
new file mode 100644
index 00000000000..34774a227bb
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp003.test
@@ -0,0 +1,6 @@
+#################################
+# Wrapper for rpl_row_sp003.test#
+#################################
+-- source include/have_innodb.inc
+let $engine_type=INNODB;
+-- source extra/rpl_tests/rpl_row_sp003.test
diff --git a/mysql-test/t/rpl_row_sp005.test b/mysql-test/t/rpl_row_sp005.test
new file mode 100644
index 00000000000..c2cdd820eeb
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp005.test
@@ -0,0 +1,105 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/15/2005 #
+# Updated: Aug/29/2005: Removed sleeps #
+#############################################################################
+# Test: Tests SPs with cursors, flow logic, and alter sp. In addition the #
+# tests SPs with insert and update operations. #
+#############################################################################
+
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t3;
+--enable_warnings
+# End of cleanup
+
+# Begin test section 1
+CREATE TABLE IF NOT EXISTS test.t1(id INT, data CHAR(16),PRIMARY KEY(id));
+CREATE TABLE IF NOT EXISTS test.t2(id2 INT,PRIMARY KEY(id2));
+CREATE TABLE IF NOT EXISTS test.t3(id3 INT,PRIMARY KEY(id3), c CHAR(16));
+
+delimiter |;
+CREATE PROCEDURE test.p1()
+BEGIN
+DECLARE done INT DEFAULT 0;
+ DECLARE spa CHAR(16);
+ DECLARE spb,spc INT;
+ DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
+ DECLARE cur2 CURSOR FOR SELECT id2 FROM test.t2;
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
+
+ OPEN cur1;
+ OPEN cur2;
+
+ REPEAT
+ FETCH cur1 INTO spb, spa;
+ FETCH cur2 INTO spc;
+ IF NOT done THEN
+ IF spb < spc THEN
+ INSERT INTO test.t3 VALUES (spb,spa);
+ ELSE
+ INSERT INTO test.t3 VALUES (spc,spa);
+ END IF;
+ END IF;
+ UNTIL done END REPEAT;
+
+ CLOSE cur1;
+ CLOSE cur2;
+END|
+CREATE PROCEDURE test.p2()
+BEGIN
+ INSERT INTO test.t1 VALUES (4,'MySQL'),(20,'ROCKS'),(11,'Texas'),(10,'kyle');
+ INSERT INTO test.t2 VALUES (4),(2),(1),(3);
+ UPDATE test.t1 SET id=id+4 WHERE id=4;
+END|
+delimiter ;|
+
+let $message=< ---- Master selects-- >;
+--source include/show_msg.inc
+CALL test.p2();
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+
+let $message=< ---- Slave selects-- >;
+--source include/show_msg.inc
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+
+let $message=< ---- Master selects-- >;
+--source include/show_msg.inc
+connection master;
+CALL test.p1();
+sleep 6;
+SELECT * FROM test.t3;
+
+let $message=< ---- Slave selects-- >;
+--source include/show_msg.inc
+connection slave;
+SELECT * FROM test.t3;
+
+connection master;
+
+ALTER PROCEDURE test.p1 MODIFIES SQL DATA;
+#show binlog events;
+
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_row_sp006_InnoDB-slave.opt b/mysql-test/t/rpl_row_sp006_InnoDB-slave.opt
new file mode 100644
index 00000000000..627becdbfb5
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp006_InnoDB-slave.opt
@@ -0,0 +1 @@
+--innodb
diff --git a/mysql-test/t/rpl_row_sp006_InnoDB.test b/mysql-test/t/rpl_row_sp006_InnoDB.test
new file mode 100644
index 00000000000..4afa3c41aeb
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp006_InnoDB.test
@@ -0,0 +1,6 @@
+#################################
+# Wrapper for rpl_row_sp006.test#
+#################################
+-- source include/have_innodb.inc
+let $engine_type=InnoDB;
+-- source extra/rpl_tests/rpl_row_sp006.test
diff --git a/mysql-test/t/rpl_row_sp007_innodb.test b/mysql-test/t/rpl_row_sp007_innodb.test
new file mode 100644
index 00000000000..9b257e14320
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp007_innodb.test
@@ -0,0 +1,6 @@
+#################################
+# Wrapper for rpl_row_sp007.test#
+#################################
+-- source include/have_innodb.inc
+let $engine_type=INNODB;
+-- source extra/rpl_tests/rpl_row_sp007.test
diff --git a/mysql-test/t/rpl_row_sp008.test b/mysql-test/t/rpl_row_sp008.test
new file mode 100644
index 00000000000..c30339b8c7c
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp008.test
@@ -0,0 +1,58 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/15/2005 #
+# Update: 08/29/2005 Remove sleep #
+#############################################################################
+# TEST: Use SQL_CALC_FOUND_ROWS and insert results into a table inside a sp #
+#############################################################################
+
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t2;
+--enable_warnings
+# End of cleanup
+
+
+
+# Begin test section 1
+CREATE TABLE test.t1 (a INT,PRIMARY KEY(a));
+CREATE TABLE test.t2 (a INT,PRIMARY KEY(a));
+INSERT INTO test.t1 VALUES(1),(2);
+
+delimiter |;
+CREATE PROCEDURE test.p1()
+BEGIN
+ SELECT SQL_CALC_FOUND_ROWS * FROM test.t1 LIMIT 1;
+ INSERT INTO test.t2 VALUES(FOUND_ROWS());
+END|
+delimiter ;|
+
+let $message=< ---- Master selects-- >;
+--source include/show_msg.inc
+CALL test.p1();
+SELECT * FROM test.t2;
+
+let $message=< ---- Slave selects-- >;
+--source include/show_msg.inc
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t2;
+
+connection master;
+let $VERSION=`select version()`;
+--replace_result $VERSION VERSION
+show binlog events;
+
+
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_row_sp009.test b/mysql-test/t/rpl_row_sp009.test
new file mode 100644
index 00000000000..b06267df783
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp009.test
@@ -0,0 +1,105 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/18/2005 #
+# Updated: 08/29/2005 removed sleeps and added master pos save and snyc #
+#############################################################################
+#TEST: Taken and modfied from http://bugs.mysql.com/bug.php?id=12168 #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p1;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+
+
+# Begin test section 1
+CREATE TABLE test.t1 (a INT, PRIMARY KEY(a));
+INSERT INTO test.t1 VALUES (1),(2),(3),(4);
+CREATE TABLE test.t2 (a INT, PRIMARY KEY(a));
+
+delimiter |;
+CREATE PROCEDURE test.p1 (arg1 CHAR(1))
+BEGIN
+ DECLARE b, c INT;
+ IF arg1 = 'a' THEN
+ BEGIN
+ DECLARE cur1 CURSOR FOR SELECT A FROM test.t1 WHERE a % 2;
+ DECLARE continue handler for not found set b = 1;
+ SET b = 0;
+ OPEN cur1;
+ c1_repeat: REPEAT
+ FETCH cur1 INTO c;
+ IF (b = 1) THEN
+ LEAVE c1_repeat;
+ END IF;
+
+ INSERT INTO test.t2 VALUES (c);
+ UNTIL b = 1
+ END REPEAT;
+ CLOSE cur1;
+ END;
+ END IF;
+ IF arg1 = 'b' THEN
+ BEGIN
+ DECLARE cur2 CURSOR FOR SELECT a FROM test.t1 WHERE NOT a % 2;
+ DECLARE continue handler for not found set b = 1;
+ SET b = 0;
+ OPEN cur2;
+ c2_repeat: REPEAT
+ FETCH cur2 INTO c;
+ IF (b = 1) THEN
+ LEAVE c2_repeat;
+ END IF;
+
+ INSERT INTO test.t2 VALUES (c);
+ UNTIL b = 1
+ END REPEAT;
+ CLOSE cur2;
+ END;
+ END IF;
+END|
+delimiter ;|
+
+CALL test.p1('a');
+SELECT * FROM test.t2;
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t2;
+connection master;
+truncate test.t2;
+
+# this next call fails, but should not
+call test.p1('b');
+select * from test.t2;
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t2;
+
+connection master;
+truncate test.t2;
+SELECT * FROM test.t2;
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t2;
+
+
+connection master;
+#show binlog events;
+# lets cleanup
+
+DROP PROCEDURE test.p1;
+DROP TABLE test.t1;
+DROP TABLE test.t2;
+
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_row_sp010.test b/mysql-test/t/rpl_row_sp010.test
new file mode 100644
index 00000000000..8d11ca10087
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp010.test
@@ -0,0 +1,81 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/18/2005 #
+# Update: 08/29/2005 remove sleep added master pos save and sync #
+#############################################################################
+#TEST: Taken and modfied from http://bugs.mysql.com/bug.php?id=11126 #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP PROCEDURE IF EXISTS test.p4;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+
+
+# Begin test section 1
+delimiter |;
+CREATE PROCEDURE test.p1()
+BEGIN
+ INSERT INTO test.t1 VALUES(2);
+END|
+CREATE PROCEDURE test.p2()
+BEGIN
+ DROP TEMPORARY TABLE IF EXISTS test.t1;
+ CREATE TEMPORARY TABLE test.t1 (a int, PRIMARY KEY(a));
+ INSERT INTO test.t1 VALUES(1);
+ CALL test.p1();
+END|
+delimiter ;|
+CALL test.p2();
+SELECT * FROM test.t1;
+
+save_master_pos;
+connection slave;
+sync_with_master;
+show tables;
+
+connection master;
+delimiter |;
+CREATE PROCEDURE test.p3()
+BEGIN
+ INSERT INTO test.t2 VALUES(7);
+END|
+CREATE PROCEDURE test.p4()
+BEGIN
+ DROP TABLE IF EXISTS test.t2;
+ CREATE TABLE test.t2 (a int, PRIMARY KEY(a));
+ INSERT INTO test.t2 VALUES(6);
+ CALL test.p3();
+END|
+delimiter ;|
+CALL test.p4();
+SELECT * FROM test.t2;
+
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t2;
+
+connection master;
+#show binlog events;
+# lets cleanup
+
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP PROCEDURE IF EXISTS test.p4;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_row_sp011.test b/mysql-test/t/rpl_row_sp011.test
new file mode 100644
index 00000000000..8d843510b6b
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp011.test
@@ -0,0 +1,115 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/18/2005 #
+# Updated: 08/29/2005 turned on diff and commented out debug SQL statements#
+#############################################################################
+#TEST: SP to test alter table and nested SP calls #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP PROCEDURE IF EXISTS test.p4;
+DROP PROCEDURE IF EXISTS test.p5;
+DROP PROCEDURE IF EXISTS test.p6;
+DROP PROCEDURE IF EXISTS test.p7;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+
+
+# Begin test section 1
+CREATE TABLE test.t1 (a int, PRIMARY KEY(a));
+INSERT INTO test.t1 VALUES (1);
+
+delimiter |;
+CREATE PROCEDURE test.p1()
+BEGIN
+ ALTER TABLE test.t1 ADD COLUMN b CHAR(4) AFTER a;
+ UPDATE test.t1 SET b = 'rbr' WHERE a = 1;
+ CALL test.p2();
+END|
+CREATE PROCEDURE test.p2()
+BEGIN
+ ALTER TABLE test.t1 ADD COLUMN f FLOAT AFTER b;
+ UPDATE test.t1 SET f = RAND() WHERE a = 1;
+ CALL test.p3();
+END|
+CREATE PROCEDURE test.p3()
+BEGIN
+ ALTER TABLE test.t1 RENAME test.t2;
+ CALL test.p4();
+END|
+CREATE PROCEDURE test.p4()
+BEGIN
+ ALTER TABLE test.t2 ADD INDEX (f);
+ ALTER TABLE test.t2 CHANGE a a INT UNSIGNED NOT NULL AUTO_INCREMENT;
+ INSERT INTO test.t2 VALUES (NULL,'TEST',RAND());
+ CALL test.p5();
+END|
+CREATE PROCEDURE test.p5()
+BEGIN
+ ALTER TABLE test.t2 ORDER BY f;
+ INSERT INTO test.t2 VALUES (NULL,'STM',RAND());
+ CALL test.p6();
+END|
+CREATE PROCEDURE test.p6()
+BEGIN
+ ALTER TABLE test.t2 ADD COLUMN b2 CHAR(4) FIRST;
+ ALTER TABLE test.t2 ADD COLUMN to_drop BIT(8) AFTER b2;
+ INSERT INTO test.t2 VALUES ('new',1,NULL,'STM',RAND());
+ CALL test.p7();
+END|
+CREATE PROCEDURE test.p7()
+BEGIN
+ ALTER TABLE test.t2 DROP COLUMN to_drop;
+ INSERT INTO test.t2 VALUES ('gone',NULL,'STM',RAND());
+END|
+delimiter ;|
+CALL test.p1();
+
+#SELECT * FROM test.t2;
+sync_slave_with_master;
+#SELECT * FROM test.t2;
+connection master;
+
+#show binlog events;
+# lets cleanup
+
+--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/sp011_master.sql
+--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/sp011_slave.sql
+
+
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP PROCEDURE IF EXISTS test.p4;
+DROP PROCEDURE IF EXISTS test.p5;
+DROP PROCEDURE IF EXISTS test.p6;
+DROP PROCEDURE IF EXISTS test.p7;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+
+
+# First lets cleanup
+
+# Lets compare. Note: If they match test will pass, if they do not match
+# the test will show that the diff statement failed and not reject file
+# will be created. You will need to go to the mysql-test dir and diff
+# the files your self to see what is not matching :-) Failed test
+# Will leave dump files in mysql-test/var/tmp
+
+exec diff ./var/tmp/sp011_master.sql ./var/tmp/sp011_slave.sql;
+
+# If all is good, when can cleanup our dump files.
+system rm ./var/tmp/sp011_master.sql;
+system rm ./var/tmp/sp011_slave.sql;
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_row_sp012.test b/mysql-test/t/rpl_row_sp012.test
new file mode 100644
index 00000000000..2b9c07895f0
--- /dev/null
+++ b/mysql-test/t/rpl_row_sp012.test
@@ -0,0 +1,74 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/22/2005 #
+# Update: 08/29/2005 Added save pos and sync #
+#############################################################################
+#TEST: SP to test security and current_user and user #
+#############################################################################
+
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/not_embedded.inc
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+
+
+# Begin test section 1
+# Create user user1 with no particular access rights
+grant usage on *.* to user1@localhost;
+flush privileges;
+
+SELECT CURRENT_USER();
+SELECT USER();
+CREATE PROCEDURE test.p1 () SQL SECURITY INVOKER SELECT CURRENT_USER(), USER();
+CREATE PROCEDURE test.p2 () SQL SECURITY DEFINER CALL test.p1();
+CREATE PROCEDURE test.p3 () SQL SECURITY INVOKER CALL test.p1();
+GRANT EXECUTE ON PROCEDURE p1 TO user1@localhost;
+GRANT EXECUTE ON PROCEDURE p2 TO user1@localhost;
+GRANT EXECUTE ON PROCEDURE p3 TO user1@localhost;
+
+# Need to wait for the rights to be applied at the slave
+sync_slave_with_master;
+
+let $message=<******** Master user1 p3 & p2 calls *******>;
+--source include/show_msg.inc
+connect (muser1,localhost,user1,,);
+connection muser1;
+SELECT CURRENT_USER();
+SELECT USER();
+CALL test.p3();
+CALL test.p2();
+
+let $message=<******** Slave user1 p3 & p2 calls *******>;
+--source include/show_msg.inc
+connect (suser1,127.0.0.1,user1,,test,$SLAVE_MYPORT,);
+
+connection master;
+save_master_pos;
+connection suser1;
+sync_with_master;
+
+SELECT CURRENT_USER();
+SELECT USER();
+CALL test.p3();
+CALL test.p2();
+
+connection master;
+
+# lets cleanup
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p3;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+
+# End of 5.0 test case
+
diff --git a/mysql-test/t/rpl_row_stop_middle.test b/mysql-test/t/rpl_row_stop_middle.test
new file mode 100644
index 00000000000..553a026e5e7
--- /dev/null
+++ b/mysql-test/t/rpl_row_stop_middle.test
@@ -0,0 +1,44 @@
+# Test for BUG#11729: see if, when STOP SLAVE occurs while the slave
+# SQL thread has processed a Table_map_log_event but has not processed
+# the last Rows_log_event associated to it, the slave thread does not
+# forget to close its tables.
+
+# Can be run with statement-based but no interest (and long test)
+source include/have_binlog_format_row.inc;
+source include/master-slave.inc;
+
+connection master;
+create table t1 (a int not null auto_increment primary key, b int, key(b));
+sync_slave_with_master;
+stop slave;
+connection master;
+INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+INSERT INTO t1 (a) SELECT null FROM t1;
+
+connection slave;
+start slave;
+
+# hope one second is not enough for slave to reach the last
+# Rows_log_event, so that test actually tests something.
+
+real_sleep 1;
+stop slave;
+
+# see if slave hangs on DROP TABLE
+
+drop table t1;
+
+connection master; # cleanup
+drop table t1;
diff --git a/mysql-test/t/rpl_row_stop_middle_update-master.opt b/mysql-test/t/rpl_row_stop_middle_update-master.opt
new file mode 100644
index 00000000000..b7db8f97bdd
--- /dev/null
+++ b/mysql-test/t/rpl_row_stop_middle_update-master.opt
@@ -0,0 +1 @@
+--loose-binlog-row-event-max-size=256
diff --git a/mysql-test/t/rpl_row_stop_middle_update-slave.opt b/mysql-test/t/rpl_row_stop_middle_update-slave.opt
new file mode 100644
index 00000000000..ea49a27adf4
--- /dev/null
+++ b/mysql-test/t/rpl_row_stop_middle_update-slave.opt
@@ -0,0 +1 @@
+--loose-debug=d,STOP_SLAVE_after_first_Rows_event
diff --git a/mysql-test/t/rpl_row_stop_middle_update.test b/mysql-test/t/rpl_row_stop_middle_update.test
new file mode 100644
index 00000000000..82c4b1a9936
--- /dev/null
+++ b/mysql-test/t/rpl_row_stop_middle_update.test
@@ -0,0 +1,31 @@
+-- source include/have_binlog_format_row.inc
+-- source include/have_debug.inc
+-- source include/master-slave.inc
+
+# master is asked to create small Rows events: if only one event is
+# created, stopping slave at the end of that one will show no bug, we
+# need at least two (and stop after first); in this test we use three.
+
+connection master;
+create table t1 (words varchar(20)) engine=myisam;
+
+load data infile '../../std_data/words.dat' into table t1 (words);
+select count(*) from t1;
+save_master_pos;
+
+connection slave;
+
+# slave will automatically tell itself to stop thanks to the .opt
+# file; it will initiate the stop request after the first
+# Rows_log_event (out of 3) but should wait until the last one is
+# executed before stopping.
+
+wait_for_slave_to_stop;
+
+# check that we inserted all rows (waited until the last Rows event)
+select count(*) from t1;
+
+connection master;
+drop table t1;
+connection slave; # slave SQL thread is stopped
+drop table t1;
diff --git a/mysql-test/t/rpl_timezone-master.opt b/mysql-test/t/rpl_row_timezone-master.opt
index 8e43bfbbb7e..8e43bfbbb7e 100644
--- a/mysql-test/t/rpl_timezone-master.opt
+++ b/mysql-test/t/rpl_row_timezone-master.opt
diff --git a/mysql-test/t/rpl_row_timezone-slave.opt b/mysql-test/t/rpl_row_timezone-slave.opt
new file mode 100644
index 00000000000..c383fd9f17d
--- /dev/null
+++ b/mysql-test/t/rpl_row_timezone-slave.opt
@@ -0,0 +1,2 @@
+--default-time-zone=Europe/Moscow
+
diff --git a/mysql-test/t/rpl_row_timezone.test b/mysql-test/t/rpl_row_timezone.test
new file mode 100644
index 00000000000..047a458f09f
--- /dev/null
+++ b/mysql-test/t/rpl_row_timezone.test
@@ -0,0 +1,129 @@
+# TBF - difference in row level logging
+-- source include/have_binlog_format_row.inc
+
+# Test of replication of time zones.
+
+# There is currently some bug possibly in prepared statements (this
+# test fails with --ps-protocol): sys_var_thd_time_zone::value_ptr()
+# is called only at prepare time, not at execution time. So,
+# thd->time_zone_used is not equal to 1 (it is back to 0, because of
+# reset_thd_for_next_command called at execution time), so the
+# timezone used in CONVERT_TZ is not binlogged. To debug (by Guilhem
+# and possibly Konstantin).
+
+--disable_ps_protocol
+
+source include/master-slave.inc;
+
+# Some preparations
+let $VERSION=`select version()`;
+set timestamp=100000000; # for fixed output of mysqlbinlog
+create table t1 (t timestamp, n int not null auto_increment, PRIMARY KEY(n));
+create table t2 (t char(32), n int not null auto_increment, PRIMARY KEY(n));
+
+connection slave;
+select @@time_zone;
+#set time_zone='UTC';
+#select @@time_zone;
+#
+# Let us check how well replication works when we are saving datetime
+# value in TIMESTAMP field.
+#
+connection master;
+select @@time_zone;
+#set time_zone='UTC';
+#select @@time_zone;
+insert into t1 values ('20050101000000', NULL), ('20050611093902',NULL);
+insert into t1 values ('20040101000000',NULL), ('20040611093902',NULL);
+select * from t1;
+sync_slave_with_master;
+#set time_zone='UTC';
+select * from t1;
+
+# Let us check also that setting of time_zone back to default also works
+# well
+connection master;
+delete from t1;
+set time_zone='Europe/Moscow';
+insert into t1 values ('20040101000000',NULL), ('20040611093902',NULL);
+select * from t1;
+sync_slave_with_master;
+set time_zone='Europe/Moscow';
+select * from t1;
+connection master;
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
+
+# Let us check with LOAD DATA INFILE
+# (we do it after mysqlbinlog because the temp files names are not constant)
+connection master;
+delete from t1;
+set time_zone='UTC';
+load data infile '../../std_data/rpl_timezone2.dat' into table t1;
+select * from t1;
+sync_slave_with_master;
+set time_zone='UTC';
+select * from t1;
+set time_zone='Europe/Moscow';
+
+# Put back values of before the LOAD
+connection master;
+set time_zone='Europe/Moscow';
+delete from t1;
+insert into t1 values ('20040101000000',NULL), ('20040611093902',NULL);
+
+#
+# Now let us check how well we replicate statments reading TIMESTAMP fields
+# (We should see the same data on master and on slave but it should differ
+# from originally inserted)
+#
+set time_zone='MET';
+insert into t2 (select * from t1);
+select * from t1;
+sync_slave_with_master;
+select * from t2;
+
+#
+# Now let us check how well we replicate various CURRENT_* functions
+#
+connection master;
+delete from t2;
+set timestamp=1000072000;
+insert into t2 values (current_timestamp,NULL), (current_date,NULL), (current_time,NULL);
+sync_slave_with_master;
+select * from t2;
+
+#
+# At last let us check replication of FROM_UNIXTIME/UNIX_TIMESTAMP functions.
+#
+connection master;
+delete from t2;
+insert into t2 values (from_unixtime(1000000000),NULL),
+ (unix_timestamp('2001-09-09 03:46:40'),NULL);
+select * from t2;
+sync_slave_with_master;
+# We should get same result on slave as on master
+select * from t2;
+
+#
+# Let us check that we are allowing to set global time_zone with
+# replication
+#
+connection master;
+set global time_zone='MET';
+
+#
+# Let us see if CONVERT_TZ(@@time_zone) replicates
+#
+delete from t2;
+set time_zone='UTC';
+insert into t2 values(convert_tz('2004-01-01 00:00:00','MET',@@time_zone),NULL);
+insert into t2 values(convert_tz('2005-01-01 00:00:00','MET','Japan'),NULL);
+select * from t2;
+sync_slave_with_master;
+select * from t2;
+
+# Clean up
+connection master;
+drop table t1, t2;
+sync_slave_with_master;
diff --git a/mysql-test/t/rpl_row_trig001.test b/mysql-test/t/rpl_row_trig001.test
new file mode 100644
index 00000000000..e2f10ecf1fa
--- /dev/null
+++ b/mysql-test/t/rpl_row_trig001.test
@@ -0,0 +1,98 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/09/2005 #
+#############################################################################
+# TEST: Use after insert and before inset triggers and stored procdures to #
+# Update and insert data #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+-- disable_query_log
+-- disable_result_log
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p2;
+DROP PROCEDURE IF EXISTS test.p3;
+--error 0,1360
+DROP TRIGGER test.t2_ai;
+--error 0,1360
+DROP TRIGGER test.t3_bi_t2;
+--error 0,1360
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
+
+
+# test section 1, lets add a trigger to the mix. Taken from bug #12280
+let $message=<Begin test section 1 (Tiggers & SP)>;
+--source include/show_msg.inc
+
+CREATE TABLE test.t1 (n MEDIUMINT NOT NULL, d DATETIME, PRIMARY KEY(n));
+CREATE TABLE test.t2 (n MEDIUMINT NOT NULL AUTO_INCREMENT, f FLOAT, d DATETIME, PRIMARY KEY(n));
+CREATE TABLE test.t3 (n MEDIUMINT NOT NULL AUTO_INCREMENT, d DATETIME, PRIMARY KEY(n));
+
+INSERT INTO test.t1 VALUES (1,NOW());
+
+delimiter //;
+CREATE TRIGGER test.t2_ai AFTER INSERT ON test.t2 FOR EACH ROW UPDATE test.t1 SET d=NOW() where n = 1;//
+CREATE PROCEDURE test.p3()
+BEGIN
+ INSERT INTO test.t3 (d) VALUES (NOW());
+END//
+CREATE TRIGGER test.t3_bi_t2 BEFORE INSERT ON test.t2 FOR EACH ROW CALL test.p3()//
+CREATE PROCEDURE test.p2()
+BEGIN
+ INSERT INTO test.t2 (f,d) VALUES (RAND(),NOW());
+END//
+delimiter ;//
+
+-- disable_query_log
+-- disable_result_log
+let $1=10;
+while ($1)
+{
+ CALL test.p2();
+ sleep 1;
+ dec $1;
+}
+-- enable_result_log
+-- enable_query_log
+
+#show binlog events;
+#select * from test.t2;
+#select * from test.t3;
+#connection slave;
+#select * from test.t2;
+#select * from test.t3;
+
+let $message=<End test section 2 (Tiggers & SP)>;
+--source include/show_msg.inc
+
+# time to dump the databases and so we can see if they match
+
+--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/trig001_master.sql
+--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/trig001_slave.sql
+
+# First lets cleanup
+
+DROP PROCEDURE test.p2;
+DROP TRIGGER test.t2_ai;
+DROP TRIGGER test.t3_bi_t2;
+DROP TABLE test.t1;
+DROP TABLE test.t2;
+DROP TABLE test.t3;
+
+# Lets compare. Note: If they match test will pass, if they do not match
+# the test will show that the diff statement failed and not reject file
+# will be created. You will need to go to the mysql-test dir and diff
+# the files your self to see what is not matching :-) Failed tests
+# will leave dump files in mysql-test/var/tmp
+
+exec diff ./var/tmp/trig001_master.sql ./var/tmp/trig001_slave.sql;
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_row_trig002.test b/mysql-test/t/rpl_row_trig002.test
new file mode 100644
index 00000000000..2cd84009b2b
--- /dev/null
+++ b/mysql-test/t/rpl_row_trig002.test
@@ -0,0 +1,79 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/14/2005 #
+# Updated: 08/29/2005 added save master pos and sync with master #
+#############################################################################
+# TEST: Taken and modified from BUG#12048 After Insert updates replication #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+#-- disable_query_log
+#-- disable_result_log
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+--error 0,1360
+DROP TRIGGER test.t2_ai;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
+--enable_warnings
+
+# test section 1, Taken from bug #12408
+
+CREATE TABLE test.t2 (value CHAR(30),domain_id INT, mailaccount_id INT, program CHAR(30),keey CHAR(30),PRIMARY KEY(domain_id));
+
+CREATE TABLE test.t3 (value CHAR(30),domain_id INT, mailaccount_id INT, program CHAR(30),keey CHAR(30),PRIMARY KEY(domain_id));
+
+CREATE TABLE test.t1 (id INT,domain CHAR(30),PRIMARY KEY(id));
+
+delimiter |;
+CREATE TRIGGER test.t2_ai AFTER INSERT ON test.t2 FOR EACH ROW UPDATE test.t3 ms, test.t1 d SET ms.value='No' WHERE ms.domain_id = (SELECT max(id) FROM test.t1 WHERE domain='example.com') AND ms.mailaccount_id IS NULL AND ms.program='spamfilter' AND ms.keey='scan_incoming'|
+delimiter ;|
+
+INSERT INTO test.t1 VALUES (1, 'example.com'),(2, 'mysql.com'),(3, 'earthmotherwear.com'), (4, 'yahoo.com'),(5, 'example.com');
+
+select * from test.t1;
+#show binlog events;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from test.t1;
+connection master;
+
+INSERT INTO test.t3 VALUES ('Yes', 5, NULL, 'spamfilter','scan_incoming');
+INSERT INTO test.t3 VALUES ('Yes', 1, NULL, 'spamfilter','scan_incoming');
+INSERT INTO test.t2 VALUES ('Yes', 1, NULL, 'spamfilter','scan_incoming');
+
+select * from test.t2;
+select * from test.t3;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from test.t2;
+select * from test.t3;
+connection master;
+
+DELETE FROM test.t1 WHERE id = 1;
+
+select * from test.t1;
+save_master_pos;
+connection slave;
+sync_with_master;
+select * from test.t1;
+connection master;
+
+#show binlog events;
+
+# cleanup
+
+DROP TRIGGER test.t2_ai;
+DROP TABLE test.t1;
+DROP TABLE test.t2;
+DROP TABLE test.t3;
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_row_trig003.test b/mysql-test/t/rpl_row_trig003.test
new file mode 100644
index 00000000000..799c2d6c9c7
--- /dev/null
+++ b/mysql-test/t/rpl_row_trig003.test
@@ -0,0 +1,152 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/16/2005 #
+# Updated: 8/29/2005 Remove sleep calls add dump and diff #
+#############################################################################
+# TEST: This test includes all trigger types. BEFORE/AFTER INSERT, UPDATE & #
+# DELETE. In addition, includes cursor, bit, varchar, flow control, #
+# looping, ROUND(), NOW(), YEAR(), TIMESTAMP #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+#-- disable_query_log
+#-- disable_result_log
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+--error 0,1360
+DROP TRIGGER test.t1_bi;
+--error 0,1360
+DROP TRIGGER test.t2_ai;
+--error 0,1360
+DROP TRIGGER test.t1_bu;
+--error 0,1360
+DROP TRIGGER test.t2_au;
+--error 0,1360
+DROP TRIGGER test.t1_bd;
+--error 0,1360
+DROP TRIGGER test.t2_ad;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
+--enable_warnings
+
+# test section 1
+
+CREATE TABLE test.t1 (id MEDIUMINT NOT NULL AUTO_INCREMENT, b1 BIT(8), vc VARCHAR(255), bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, f FLOAT DEFAULT 0, total BIGINT UNSIGNED, y YEAR, t TIMESTAMP,PRIMARY KEY(id));
+CREATE TABLE test.t2 (id MEDIUMINT NOT NULL AUTO_INCREMENT, b1 BIT(8), vc VARCHAR(255), bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, f FLOAT DEFAULT 0, total BIGINT UNSIGNED, y YEAR, t TIMESTAMP,PRIMARY KEY(id));
+CREATE TABLE test.t3 (id MEDIUMINT NOT NULL AUTO_INCREMENT, b1 BIT(8), vc VARCHAR(255), bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, f FLOAT DEFAULT 0, total BIGINT UNSIGNED, y YEAR, t TIMESTAMP,PRIMARY KEY(id));
+
+# Note Most of these cause the slave to core or do not produce desired results. Currently commenting out the ones not working until they are fixed.
+
+delimiter |;
+CREATE TRIGGER test.t1_bi BEFORE INSERT ON test.t1 FOR EACH ROW UPDATE test.t3 SET b1=1 and y=YEAR(NOW())|
+CREATE TRIGGER test.t2_ai AFTER INSERT ON test.t2 FOR EACH ROW BEGIN
+ INSERT INTO test.t3 VALUES(NULL,0,'MySQL Replication team rocks!', 'Dark beer in prague is #1',12345.34,12.51,0,1965,NOW());
+ UPDATE test.t3 SET f = ROUND(f);
+END|
+CREATE TRIGGER test.t1_bu BEFORE UPDATE on test.t1 FOR EACH ROW BEGIN
+ UPDATE test.t3 SET y = '2000';
+ INSERT INTO test.t3 VALUES(NULL,1,'Testing MySQL databases before update ', 'Insert should work',621.43, 0105.21,0,1974,NOW());
+END|
+CREATE TRIGGER test.t2_au AFTER UPDATE on test.t2 FOR EACH ROW BEGIN
+ DECLARE done INT DEFAULT 0;
+ DECLARE a DECIMAL(10,4);
+ DECLARE b FLOAT;
+ DECLARE num MEDIUMINT;
+ DECLARE cur1 CURSOR FOR SELECT t2.id, t2.d, t2.f FROM test.t2;
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
+
+ OPEN cur1;
+
+ REPEAT
+ FETCH cur1 INTO num, a, b;
+ IF NOT done THEN
+ UPDATE test.t3 SET total =(a*b) WHERE ID = num;
+ END IF;
+ UNTIL done END REPEAT;
+ CLOSE cur1;
+END|
+CREATE TRIGGER test.t1_bd BEFORE DELETE on test.t1 FOR EACH ROW BEGIN
+ DECLARE done INT DEFAULT 0;
+ DECLARE a BIT(8);
+ DECLARE b VARCHAR(255);
+ DECLARE c CHAR(255);
+ DECLARE d DECIMAL(10,4);
+ DECLARE e FLOAT;
+ DECLARE f BIGINT UNSIGNED;
+ DECLARE g YEAR;
+ DECLARE h TIMESTAMP;
+ DECLARE cur1 CURSOR FOR SELECT t1.b1, t1.vc, t1.bc, t1.d, t1.f, t1.total, t1.y, t1.t FROM test.t1;
+ DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
+
+ OPEN cur1;
+
+ REPEAT
+ FETCH cur1 INTO a, b, c, d, e, f, g, h;
+ IF NOT done THEN
+ INSERT INTO test.t3 VALUES(NULL, a, b, c, d, e, f, g, h);
+ END IF;
+ UNTIL done END REPEAT;
+ CLOSE cur1;
+END|
+CREATE TRIGGER test.t2_ad AFTER DELETE ON test.t2 FOR EACH ROW
+ DELETE FROM test.t1|
+delimiter ;|
+
+INSERT INTO test.t1 VALUES(NULL,1,'Testing MySQL databases is a cool ', 'Must make it bug free for the customer',654321.4321,15.21,0,1965,NOW());
+INSERT INTO test.t2 VALUES(NULL,0,'Testing MySQL databases is a cool ', 'MySQL Customers ROCK!',654321.4321,1.24521,0,YEAR(NOW()),NOW());
+
+UPDATE test.t1 SET b1 = 0 WHERE b1 = 1;
+
+INSERT INTO test.t2 VALUES(NULL,1,'This is an after update test.', 'If this works, total will not be zero on the master or slave',1.4321,5.221,0,YEAR(NOW()),NOW());
+UPDATE test.t2 SET b1 = 0 WHERE b1 = 1;
+
+INSERT INTO test.t1 VALUES(NULL,1,'add some more test data test.', 'and hope for the best', 3.321,5.221,0,YEAR(NOW()),NOW());
+
+# To make sure BUG#14698 is gone, we sleep 2 seconds before calling trigger
+# (with the bug in, that caused differences in TIMESTAMP columns).
+# We just need to let the machine's clock advance, it's not
+# to do synchronization, so real_sleep is good.
+real_sleep 2;
+
+DELETE FROM test.t1 WHERE id = 1;
+
+DELETE FROM test.t2 WHERE id = 1;
+
+save_master_pos;
+connection slave;
+sync_with_master;
+connection master;
+
+# time to dump the databases and so we can see if they match
+
+--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/trg003_master.sql
+--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/trg003_slave.sql
+
+# cleanup
+--disable_warnings
+--error 0,1360
+DROP TRIGGER test.t1_bi;
+--error 0,1360
+DROP TRIGGER test.t2_ai;
+--error 0,1360
+DROP TRIGGER test.t1_bu;
+--error 0,1360
+DROP TRIGGER test.t2_au;
+--error 0,1360
+DROP TRIGGER test.t1_bd;
+--error 0,1360
+DROP TRIGGER test.t2_ad;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
+--enable_warnings
+
+exec diff ./var/tmp/trg003_master.sql ./var/tmp/trg003_slave.sql;
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_row_trig004.test b/mysql-test/t/rpl_row_trig004.test
new file mode 100644
index 00000000000..2ad0b46211b
--- /dev/null
+++ b/mysql-test/t/rpl_row_trig004.test
@@ -0,0 +1,14 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Oct/18/2005 #
+#############################################################################
+# TEST: Use before insert triggers and has the second insert fail #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/have_innodb.inc
+-- source include/master-slave.inc
+let $engine_type=INNODB;
+-- source extra/rpl_tests/rpl_trig004.test
+
diff --git a/mysql-test/t/rpl_row_until.test b/mysql-test/t/rpl_row_until.test
new file mode 100644
index 00000000000..5ddeea911a8
--- /dev/null
+++ b/mysql-test/t/rpl_row_until.test
@@ -0,0 +1,86 @@
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+# Test is dependent on binlog positions
+
+# prepare version for substitutions
+let $VERSION=`select version()`;
+
+# stop slave before he will start replication also sync with master
+# for avoiding undetermenistic behaviour
+save_master_pos;
+connection slave;
+sync_with_master;
+stop slave;
+
+connection master;
+# create some events on master
+create table t1(n int not null auto_increment primary key);
+insert into t1 values (1),(2),(3),(4);
+drop table t1;
+create table t2(n int not null auto_increment primary key);
+insert into t2 values (1),(2);
+insert into t2 values (3),(4);
+drop table t2;
+
+# try to replicate all queries until drop of t1
+connection slave;
+start slave until master_log_file='master-bin.000001', master_log_pos=311;
+sleep 2;
+wait_for_slave_to_stop;
+# here table should be still not deleted
+select * from t1;
+--replace_result $MASTER_MYPORT MASTER_MYPORT
+--replace_column 1 # 9 # 11 # 23 # 33 #
+show slave status;
+
+# this should fail right after start
+start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
+# again this table should be still not deleted
+select * from t1;
+sleep 2;
+wait_for_slave_to_stop;
+--replace_result $MASTER_MYPORT MASTER_MYPORT
+--replace_column 1 # 9 # 11 # 23 # 33 #
+show slave status;
+
+# try replicate all up to and not including the second insert to t2;
+start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728;
+sleep 2;
+wait_for_slave_to_stop;
+select * from t2;
+--replace_result $MASTER_MYPORT MASTER_MYPORT
+--replace_column 1 # 9 # 11 # 23 # 33 #
+show slave status;
+
+# clean up
+start slave;
+connection master;
+save_master_pos;
+connection slave;
+sync_with_master;
+stop slave;
+
+# this should stop immediately as we are already there
+start slave until master_log_file='master-bin.000001', master_log_pos=740;
+sleep 2;
+wait_for_slave_to_stop;
+# here the sql slave thread should be stopped
+--replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004
+--replace_column 1 # 9 # 23 # 33 #
+show slave status;
+
+#testing various error conditions
+--error 1277
+start slave until master_log_file='master-bin', master_log_pos=561;
+--error 1277
+start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12;
+--error 1277
+start slave until master_log_file='master-bin.000001';
+--error 1277
+start slave until relay_log_file='slave-relay-bin.000002';
+--error 1277
+start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=561;
+# Warning should be given for second command
+start slave sql_thread;
+start slave until master_log_file='master-bin.000001', master_log_pos=740;
diff --git a/mysql-test/t/rpl_row_user_variables.test b/mysql-test/t/rpl_row_user_variables.test
new file mode 100644
index 00000000000..2ebb668b1a8
--- /dev/null
+++ b/mysql-test/t/rpl_row_user_variables.test
@@ -0,0 +1,4 @@
+# row-based and statement binlog difference in result files
+-- source include/have_binlog_format_row.inc
+-- source extra/rpl_tests/rpl_user_variables.test
+
diff --git a/mysql-test/t/rpl_view.test b/mysql-test/t/rpl_row_view.test
index 0a0c6a6dddb..6d460d58df6 100644
--- a/mysql-test/t/rpl_view.test
+++ b/mysql-test/t/rpl_row_view.test
@@ -1,9 +1,11 @@
+# NYI - row-based cannot use CREATE ... SELECT
+--source include/have_binlog_format_row.inc
+
source include/master-slave.inc;
--disable_warnings
drop table if exists t1,v1;
drop view if exists t1,v1;
sync_slave_with_master;
-reset master;
--enable_warnings
#
@@ -43,5 +45,3 @@ select * from v1 order by a;
connection master;
drop table t1;
sync_slave_with_master;
---replace_column 2 # 5 #
-show binlog events limit 1,100;
diff --git a/mysql-test/t/rpl_row_view01.test b/mysql-test/t/rpl_row_view01.test
new file mode 100644
index 00000000000..85137e03dbf
--- /dev/null
+++ b/mysql-test/t/rpl_row_view01.test
@@ -0,0 +1,82 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/19/2005 #
+# Updated: 08/29/2005 Remove sleeps #
+#############################################################################
+#TEST: row based replication of views #
+#############################################################################
+
+# Includes
+-- source include/have_binlog_format_row.inc
+-- source include/master-slave.inc
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+create database if not exists mysqltest1;
+DROP VIEW IF EXISTS mysqltest1.v1;
+DROP VIEW IF EXISTS mysqltest1.v2;
+DROP VIEW IF EXISTS mysqltest1.v3;
+DROP VIEW IF EXISTS mysqltest1.v4;
+DROP TABLE IF EXISTS mysqltest1.t3;
+DROP TABLE IF EXISTS mysqltest1.t1;
+DROP TABLE IF EXISTS mysqltest1.t2;
+DROP TABLE IF EXISTS mysqltest1.t4;
+
+# Begin test section 1
+CREATE TABLE mysqltest1.t1 (a INT, c CHAR(6),PRIMARY KEY(a));
+CREATE TABLE mysqltest1.t2 (a INT, c CHAR(6),PRIMARY KEY(a));
+CREATE TABLE mysqltest1.t3 (a INT, c CHAR(6), c2 CHAR(6), PRIMARY KEY(a));
+CREATE TABLE mysqltest1.t4 (a INT, qty INT, price INT,PRIMARY KEY(a));
+CREATE TABLE mysqltest1.t5 (qty INT, price INT, total INT, PRIMARY KEY(qty));
+INSERT INTO mysqltest1.t1 VALUES (1,'Thank'),(2,'it'),(3,'Friday');
+INSERT INTO mysqltest1.t2 VALUES (1,'GOD'),(2,'is'),(3,'TGIF');
+INSERT INTO mysqltest1.t4 VALUES(1, 3, 50),(2, 18, 3),(4, 4, 4);
+
+
+CREATE VIEW mysqltest1.v2 AS SELECT qty, price, qty*price AS value FROM mysqltest1.t4;
+CREATE VIEW mysqltest1.v1 AS SELECT t1.a, t1.c, t2.c as c2 FROM mysqltest1.t1 as t1, mysqltest1.t2 AS t2 WHERE mysqltest1.t1.a = mysqltest1.t2.a;
+CREATE VIEW mysqltest1.v3 AS SELECT * FROM mysqltest1.t1;
+CREATE VIEW mysqltest1.v4 AS SELECT * FROM mysqltest1.v3 WHERE a > 1 WITH LOCAL CHECK OPTION;
+
+
+SELECT * FROM mysqltest1.v2;
+SELECT * FROM mysqltest1.v1;
+sync_slave_with_master;
+SELECT * FROM mysqltest1.v2;
+SELECT * FROM mysqltest1.v1;
+connection master;
+
+INSERT INTO mysqltest1.t5 SELECT * FROM mysqltest1.v2;
+INSERT INTO mysqltest1.t3 SELECT * FROM mysqltest1.v1;
+
+SELECT * FROM mysqltest1.t5;
+SELECT * FROM mysqltest1.t3;
+sync_slave_with_master;
+SELECT * FROM mysqltest1.t5;
+SELECT * FROM mysqltest1.t3;
+connection master;
+
+INSERT INTO mysqltest1.v4 VALUES (4,'TEST');
+
+SELECT * FROM mysqltest1.t1;
+SELECT * FROM mysqltest1.v4;
+sync_slave_with_master;
+SELECT * FROM mysqltest1.t1;
+SELECT * FROM mysqltest1.v4;
+
+connection master;
+
+# lets cleanup
+DROP VIEW IF EXISTS mysqltest1.v1;
+DROP VIEW IF EXISTS mysqltest1.v2;
+DROP VIEW IF EXISTS mysqltest1.v3;
+DROP VIEW IF EXISTS mysqltest1.v4;
+DROP TABLE IF EXISTS mysqltest1.t3;
+DROP TABLE IF EXISTS mysqltest1.t1;
+DROP TABLE IF EXISTS mysqltest1.t2;
+DROP TABLE IF EXISTS mysqltest1.t4;
+sync_slave_with_master;
+
+# End of 5.1 test case
+
diff --git a/mysql-test/t/rpl_server_id1.test b/mysql-test/t/rpl_server_id1.test
index 3583f05284c..71310750b60 100644
--- a/mysql-test/t/rpl_server_id1.test
+++ b/mysql-test/t/rpl_server_id1.test
@@ -13,7 +13,7 @@ stop slave;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval change master to master_port=$SLAVE_MYPORT;
--replace_result $SLAVE_MYPORT SLAVE_PORT
---replace_column 18 #
+--replace_column 16 # 18 #
show slave status;
start slave;
insert into t1 values (1);
diff --git a/mysql-test/t/rpl_sp004.test b/mysql-test/t/rpl_sp004.test
new file mode 100644
index 00000000000..6f6bd79ae82
--- /dev/null
+++ b/mysql-test/t/rpl_sp004.test
@@ -0,0 +1,97 @@
+#############################################################################
+# Original Author: JBM #
+# Original Date: Aug/14/2005 #
+#############################################################################
+# Test: This test contains two sp that create and drop tables, insert and #
+# updated data and uses the NOW() function. #
+#############################################################################
+
+
+# Includes
+-- source include/master-slave.inc
+
+
+# Begin clean up test section
+connection master;
+--disable_warnings
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t3;
+--enable_warnings
+# End of cleanup
+
+# Begin test section 1
+
+delimiter |;
+CREATE PROCEDURE test.p1()
+BEGIN
+ CREATE TABLE IF NOT EXISTS test.t1(a INT,PRIMARY KEY(a));
+ CREATE TABLE IF NOT EXISTS test.t2(a INT,PRIMARY KEY(a));
+ INSERT INTO test.t1 VALUES (4),(2),(1),(3);
+ UPDATE test.t1 SET a=a+4 WHERE a=4;
+ INSERT INTO test.t2 (a) SELECT t1.a FROM test.t1;
+ UPDATE test.t1 SET a=a+4 WHERE a=8;
+ CREATE TABLE IF NOT EXISTS test.t3(n MEDIUMINT NOT NULL AUTO_INCREMENT, f FLOAT, d DATETIME, PRIMARY KEY(n));
+END|
+CREATE PROCEDURE test.p2()
+BEGIN
+ DROP TABLE IF EXISTS test.t1;
+ DROP TABLE IF EXISTS test.t2;
+ INSERT INTO test.t3 VALUES(NULL,11111111.233333,NOW());
+END|
+delimiter ;|
+
+CALL test.p1();
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+
+connection master;
+CALL test.p2();
+USE test;
+SHOW TABLES;
+#SELECT * FROM test.t3;
+save_master_pos;
+connection slave;
+sync_with_master;
+USE test;
+SHOW TABLES;
+#SELECT * FROM test.t3;
+
+connection master;
+CALL test.p1();
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+#SELECT * FROM test.t3;
+save_master_pos;
+connection slave;
+sync_with_master;
+SELECT * FROM test.t1;
+SELECT * FROM test.t2;
+#SELECT * FROM test.t3;
+connection master;
+#show binlog events;
+
+
+# If the test fails, you will need to diff the dumps to see why.
+
+--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/sp004_master.sql
+--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > ./var/tmp/sp004_slave.sql
+
+DROP PROCEDURE IF EXISTS test.p1;
+DROP PROCEDURE IF EXISTS test.p2;
+DROP TABLE IF EXISTS test.t1;
+DROP TABLE IF EXISTS test.t2;
+DROP TABLE IF EXISTS test.t3;
+#sync_slave_with_master;
+
+-- exec diff ./var/tmp/sp004_master.sql ./var/tmp/sp004_slave.sql
+
+
+# End of 5.0 test case
diff --git a/mysql-test/t/rpl_sp_effects.test b/mysql-test/t/rpl_sp_effects.test
index 9da5723b993..1c23f956082 100644
--- a/mysql-test/t/rpl_sp_effects.test
+++ b/mysql-test/t/rpl_sp_effects.test
@@ -1,6 +1,8 @@
# Test of replication of stored procedures (WL#2146 for MySQL 5.0)
-
-source include/master-slave.inc;
+# Make this statement only until bug 13115 is corrected [jbm]
+# TODO: Remove statement include once bug 13115 is patched.
+-- source include/have_binlog_format_statement.inc
+-- source include/master-slave.inc
# ****************************************************************
connection master;
@@ -140,7 +142,6 @@ begin
end while;
end//
delimiter ;//
-
call p1(15);
select 'master:',a from t1;
sync_slave_with_master;
diff --git a/mysql-test/t/rpl_stm_000001-slave.opt b/mysql-test/t/rpl_stm_000001-slave.opt
new file mode 100644
index 00000000000..627becdbfb5
--- /dev/null
+++ b/mysql-test/t/rpl_stm_000001-slave.opt
@@ -0,0 +1 @@
+--innodb
diff --git a/mysql-test/t/rpl_stm_000001.test b/mysql-test/t/rpl_stm_000001.test
new file mode 100644
index 00000000000..aee067b2d4a
--- /dev/null
+++ b/mysql-test/t/rpl_stm_000001.test
@@ -0,0 +1,2 @@
+let $engine_type=myisam;
+-- source extra/rpl_tests/rpl_stm_000001.test
diff --git a/mysql-test/t/rpl_stm_EE_err.test b/mysql-test/t/rpl_stm_EE_err.test
new file mode 100644
index 00000000000..e883a6ce616
--- /dev/null
+++ b/mysql-test/t/rpl_stm_EE_err.test
@@ -0,0 +1,2 @@
+let $engine_type=myisam;
+-- source extra/rpl_tests/rpl_stm_EE_err.test
diff --git a/mysql-test/t/rpl_stm_charset.test b/mysql-test/t/rpl_stm_charset.test
new file mode 100644
index 00000000000..b103a47d78c
--- /dev/null
+++ b/mysql-test/t/rpl_stm_charset.test
@@ -0,0 +1,2 @@
+let $engine_type=myisam;
+-- source extra/rpl_tests/rpl_stm_charset.test
diff --git a/mysql-test/t/rpl_stm_ddl.test b/mysql-test/t/rpl_stm_ddl.test
new file mode 100644
index 00000000000..54548114f86
--- /dev/null
+++ b/mysql-test/t/rpl_stm_ddl.test
@@ -0,0 +1,35 @@
+######################## rpl_ddl.test ########################
+# #
+# DDL statements (sometimes with implicit COMMIT) executed #
+# by the master and it's propagation into the slave #
+# #
+##############################################################
+
+#
+# NOTE, PLEASE BE CAREFUL, WHEN MODIFYING THE TESTS !!
+#
+# 1. !All! objects to be dropped, renamed, altered ... must be created
+# in AUTOCOMMIT= 1 mode before AUTOCOMMIT is set to 0 and the test
+# sequences start.
+#
+# 2. Never use a test object, which was direct or indirect affected by a
+# preceeding test sequence again.
+# Except table d1.t1 where ONLY DML is allowed.
+#
+# If one preceeding test sequence hits a (sometimes not good visible,
+# because the sql error code of the statement might be 0) bug
+# and these rules are ignored, a following test sequence might earn ugly
+# effects like failing 'sync_slave_with_master', crashes of the slave or
+# abort of the test case etc..
+#
+# 3. The assignment of the DDL command to be tested to $my_stmt can
+# be a bit difficult. "'" must be avoided, because the test
+# routine "include/rpl_stmt_seq.inc" performs a
+# eval SELECT CONCAT('######## ','$my_stmt',' ########') as "";
+#
+
+--source include/have_innodb.inc
+--source include/have_binlog_format_statement.inc
+--source include/master-slave.inc
+let $engine_type= "InnoDB";
+-- source extra/rpl_tests/rpl_ddl.test
diff --git a/mysql-test/t/rpl_error_ignored_table-slave.opt b/mysql-test/t/rpl_stm_err_ignoredtable-slave.opt
index cb49119bfcb..cb49119bfcb 100644
--- a/mysql-test/t/rpl_error_ignored_table-slave.opt
+++ b/mysql-test/t/rpl_stm_err_ignoredtable-slave.opt
diff --git a/mysql-test/t/rpl_stm_err_ignoredtable.test b/mysql-test/t/rpl_stm_err_ignoredtable.test
new file mode 100644
index 00000000000..a426be27b59
--- /dev/null
+++ b/mysql-test/t/rpl_stm_err_ignoredtable.test
@@ -0,0 +1,8 @@
+# Test for
+# Bug #797: If a query is ignored on slave (replicate-ignore-table) the slave
+# still checks that it has the same error as on the master.
+
+# Requires statement logging
+-- source include/have_binlog_format_statement.inc
+-- source extra/rpl_tests/rpl_err_ignoredtable.test
+
diff --git a/mysql-test/t/rpl_stm_flsh_tbls.test b/mysql-test/t/rpl_stm_flsh_tbls.test
new file mode 100644
index 00000000000..3a6102de279
--- /dev/null
+++ b/mysql-test/t/rpl_stm_flsh_tbls.test
@@ -0,0 +1,8 @@
+# depends on the binlog output
+--source include/have_binlog_format_statement.inc
+
+let $rename_event_pos= 652;
+-- source extra/rpl_tests/rpl_flsh_tbls.test
+
+# End of 4.1 tests
+# Adding comment for force manual merge 5.0 -> wl1012. Delete me if needed.
diff --git a/mysql-test/t/rpl_loaddata_rule_s-slave.opt b/mysql-test/t/rpl_stm_loaddata_m-master.opt
index 9d4a8f0b95e..9d4a8f0b95e 100644
--- a/mysql-test/t/rpl_loaddata_rule_s-slave.opt
+++ b/mysql-test/t/rpl_stm_loaddata_m-master.opt
diff --git a/mysql-test/t/rpl_stm_loaddata_m.test b/mysql-test/t/rpl_stm_loaddata_m.test
new file mode 100644
index 00000000000..ac52a8dfb9e
--- /dev/null
+++ b/mysql-test/t/rpl_stm_loaddata_m.test
@@ -0,0 +1,10 @@
+# See if the master logs LOAD DATA INFILE correctly when binlog_*_db rules
+# exist.
+# This is for BUG#1100 (LOAD DATA INFILE was half-logged).
+
+# Requires statement logging
+-- source include/have_binlog_format_statement.inc
+-- source extra/rpl_tests/rpl_loaddata_m.test
+
+# End of 4.1 tests
+# Adding comment for force manual merge 5.0 -> wl1012: Delete me
diff --git a/mysql-test/t/rpl_stm_log-master.opt b/mysql-test/t/rpl_stm_log-master.opt
new file mode 100644
index 00000000000..e0d075c3fbd
--- /dev/null
+++ b/mysql-test/t/rpl_stm_log-master.opt
@@ -0,0 +1 @@
+--skip-external-locking
diff --git a/mysql-test/t/rpl_stm_log-slave.opt b/mysql-test/t/rpl_stm_log-slave.opt
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/mysql-test/t/rpl_stm_log-slave.opt
@@ -0,0 +1 @@
+
diff --git a/mysql-test/t/rpl_stm_log.test b/mysql-test/t/rpl_stm_log.test
new file mode 100644
index 00000000000..f5b0a7eead8
--- /dev/null
+++ b/mysql-test/t/rpl_stm_log.test
@@ -0,0 +1,7 @@
+# Requires statement logging
+-- source include/have_binlog_format_statement.inc
+-- source extra/rpl_tests/rpl_log.test
+
+
+# End of 4.1 tests
+# Adding comment for force manual merge 5.0 -> wl1012: Delete me
diff --git a/mysql-test/t/rpl_stm_max_relay_size.test b/mysql-test/t/rpl_stm_max_relay_size.test
new file mode 100644
index 00000000000..50008533388
--- /dev/null
+++ b/mysql-test/t/rpl_stm_max_relay_size.test
@@ -0,0 +1,11 @@
+# Test of options max_binlog_size and max_relay_log_size and
+# how they act (if max_relay_log_size == 0, use max_binlog_size
+# for relay logs too).
+# Test of manual relay log rotation with FLUSH LOGS.
+
+# Requires statement logging
+-- source include/have_binlog_format_statement.inc
+-- source extra/rpl_tests/rpl_max_relay_size.test
+
+# End of 4.1 tests
+#
diff --git a/mysql-test/t/rpl_stm_multi_query.test b/mysql-test/t/rpl_stm_multi_query.test
new file mode 100644
index 00000000000..97c322ac780
--- /dev/null
+++ b/mysql-test/t/rpl_stm_multi_query.test
@@ -0,0 +1,12 @@
+# Test for BUG#8436: verify that a multi-query (i.e. one query
+# containing several queries (assuming client has
+# CLIENT_MULTI_STATEMENTS) will be binlogged ONE-query-per-event (not
+# one binlog event containing all queries)
+
+# Requires statement logging
+-- source include/have_binlog_format_statement.inc
+-- source extra/rpl_tests/rpl_multi_query.test
+
+
+# End of 4.1 tests
+#
diff --git a/mysql-test/t/rpl_mystery22.test b/mysql-test/t/rpl_stm_mystery22.test
index f190968a03c..bb810ffb4ac 100644
--- a/mysql-test/t/rpl_mystery22.test
+++ b/mysql-test/t/rpl_stm_mystery22.test
@@ -1,20 +1,25 @@
+-- source include/have_binlog_format_statement.inc
+
# test case to make slave thread get ahead by 22 bytes
-source include/master-slave.inc;
+-- source include/master-slave.inc
# first, cause a duplicate key problem on the slave
-create table t1(n int auto_increment primary key);
+create table t1(n int auto_increment primary key, s char(10));
sync_slave_with_master;
-insert into t1 values (2);
+insert into t1 values (2,'old');
connection master;
-insert into t1 values(NULL);
-insert into t1 values(NULL);
+insert into t1 values(NULL,'new');
+insert into t1 values(NULL,'new');
save_master_pos;
connection slave;
-sleep 3; # there is no way around this sleep - we have to wait until
-# the slave tries to run the query, fails and aborts slave thread
+# wait until the slave tries to run the query, fails and aborts slave thread
+wait_for_slave_to_stop;
+select * from t1 order by n;
delete from t1 where n = 2;
+--disable_warnings
start slave;
+--enable_warnings
sync_with_master;
#now the buggy slave would be confused on the offset but it can replicate
#in order to make it break, we need to stop/start the slave one more time
@@ -24,14 +29,21 @@ connection master;
# events in the log
create table t2(n int);
drop table t2;
-insert into t1 values(NULL);
+insert into t1 values(NULL,'new');
+# what happens when we delete a row which does not exist on slave?
+set sql_log_bin=0;
+insert into t1 values(NULL,'new');
+set sql_log_bin=1;
+delete from t1 where n=4;
save_master_pos;
connection slave;
+--disable_warnings
start slave;
+--enable_warnings
#now the truth comes out - if the slave is buggy, it will never sync because
#the slave thread is not able to read events
sync_with_master;
-select * from t1;
+select * from t1 order by n;
#clean up
connection master;
drop table t1;
diff --git a/mysql-test/t/rpl_stm_no_op.test b/mysql-test/t/rpl_stm_no_op.test
new file mode 100644
index 00000000000..d1e0b49abe9
--- /dev/null
+++ b/mysql-test/t/rpl_stm_no_op.test
@@ -0,0 +1,93 @@
+# It's true only in statement-based replication that a statement which
+# updates no rows (UPDATE/DELETE) is binlogged; in row-based
+# replication, as we log modified rows, nothing is binlogged in this
+# case. So this test is meaningul only in statement-based (and if it was
+# enabled in row-based, it would fail as expected).
+
+-- source include/have_binlog_format_statement.inc
+
+source include/master-slave.inc;
+
+# see if DROP DATABASE is binlogged even if no effect
+connection slave;
+create database mysqltest;
+connection master;
+drop database if exists mysqltest;
+sync_slave_with_master;
+# can't read dir
+--replace_result "Errcode: 1" "Errcode: X" "Errcode: 2" "Errcode: X" \\ /
+--error 1049
+show tables from mysqltest;
+
+# see if DROP TABLE is binlogged even if no effect
+connection slave;
+create table t1 (a int);
+connection master;
+drop table if exists t1;
+sync_slave_with_master;
+# table does not exist
+--error 1146
+select * from t1;
+
+# see if single-table DELETE is binlogged even if no effect
+connection master;
+create table t1 (a int, b int);
+sync_slave_with_master;
+insert into t1 values(1,1);
+connection master;
+delete from t1;
+sync_slave_with_master;
+select * from t1;
+
+# see if single-table UPDATE is binlogged even if no effect
+insert into t1 values(1,1);
+connection master;
+insert into t1 values(2,1);
+update t1 set a=2;
+sync_slave_with_master;
+select * from t1;
+
+# End of 4.1 tests
+
+# see if multi-table UPDATE is binlogged even if no effect (BUG#13348)
+
+connection master;
+create table t2 (a int, b int);
+delete from t1;
+insert into t1 values(1,1);
+insert into t2 values(1,1);
+
+sync_slave_with_master;
+# force a difference to see if master's multi-UPDATE will correct it
+update t1 set a=2;
+
+connection master;
+UPDATE t1, t2 SET t1.a = t2.a;
+
+sync_slave_with_master;
+select * from t1;
+select * from t2;
+
+# See if multi-table DELETE is binlogged even if no effect
+
+connection master;
+delete from t1;
+delete from t2;
+
+sync_slave_with_master;
+# force a difference to see if master's multi-DELETE will correct it
+insert into t1 values(1,1);
+insert into t2 values(1,1);
+
+connection master;
+DELETE t1.*, t2.* from t1, t2;
+
+sync_slave_with_master;
+select * from t1;
+select * from t2;
+
+
+# cleanup
+connection master;
+drop table t1;
+sync_slave_with_master;
diff --git a/mysql-test/t/rpl_stm_reset_slave.test b/mysql-test/t/rpl_stm_reset_slave.test
new file mode 100644
index 00000000000..282033bf6d1
--- /dev/null
+++ b/mysql-test/t/rpl_stm_reset_slave.test
@@ -0,0 +1,6 @@
+# TBF - difference in row level logging
+-- source include/have_binlog_format_statement.inc
+-- source extra/rpl_tests/rpl_reset_slave.test
+
+# End of 4.1 tests
+#
diff --git a/mysql-test/t/rpl_stm_rewrt_db-slave.opt b/mysql-test/t/rpl_stm_rewrt_db-slave.opt
new file mode 100644
index 00000000000..a462ad19ba0
--- /dev/null
+++ b/mysql-test/t/rpl_stm_rewrt_db-slave.opt
@@ -0,0 +1 @@
+"--replicate-rewrite-db=test->rewrite" "--replicate-rewrite-db=mysqltest1->test"
diff --git a/mysql-test/t/rpl_stm_rewrt_db.test b/mysql-test/t/rpl_stm_rewrt_db.test
new file mode 100644
index 00000000000..c66ced46717
--- /dev/null
+++ b/mysql-test/t/rpl_stm_rewrt_db.test
@@ -0,0 +1,84 @@
+# TBF - difference in row level logging
+-- source include/have_binlog_format_statement.inc
+-- source include/master-slave.inc
+
+--disable_warnings
+drop database if exists mysqltest1;
+--enable_warnings
+create database mysqltest1;
+
+use mysqltest1;
+create table t1 (a int);
+insert into t1 values(9);
+select * from mysqltest1.t1;
+sync_slave_with_master;
+show databases like 'mysqltest1'; # should be empty
+select * from test.t1;
+# cleanup
+connection master;
+drop table t1;
+drop database mysqltest1;
+sync_slave_with_master;
+
+#
+# BUG#6353:
+# Option --replicate-rewrite-db should work together with LOAD DATA INFILE
+#
+
+connection slave;
+--disable_warnings
+drop database if exists rewrite;
+--enable_warnings
+create database rewrite;
+
+connection master;
+use test;
+create table t1 (a date, b date, c date not null, d date);
+load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',';
+load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' IGNORE 2 LINES;
+sync_slave_with_master;
+
+connection slave;
+select * from rewrite.t1;
+
+connection master;
+truncate table t1;
+load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' LINES STARTING BY ',' (b,c,d);
+sync_slave_with_master;
+
+connection slave;
+select * from rewrite.t1;
+
+connection master;
+drop table t1;
+create table t1 (a text, b text);
+load data infile '../../std_data/loaddata2.dat' into table t1 fields terminated by ',' enclosed by '''';
+sync_slave_with_master;
+
+connection slave;
+select concat('|',a,'|'), concat('|',b,'|') from rewrite.t1;
+
+connection master;
+drop table t1;
+create table t1 (a int, b char(10));
+load data infile '../../std_data/loaddata3.dat' into table t1 fields terminated by '' enclosed by '' ignore 1 lines;
+sync_slave_with_master;
+
+connection slave;
+select * from rewrite.t1;
+
+connection master;
+truncate table t1;
+load data infile '../../std_data/loaddata4.dat' into table t1 fields terminated by '' enclosed by '' lines terminated by '' ignore 1 lines;
+sync_slave_with_master;
+
+connection slave;
+# The empty line last comes from the end line field in the file
+select * from rewrite.t1;
+
+drop database rewrite;
+
+connection master;
+drop table t1;
+
+# End of 4.1 tests
diff --git a/mysql-test/t/rpl_stm_sp-master.opt b/mysql-test/t/rpl_stm_sp-master.opt
new file mode 100644
index 00000000000..709a224fd92
--- /dev/null
+++ b/mysql-test/t/rpl_stm_sp-master.opt
@@ -0,0 +1 @@
+--log_bin_trust_routine_creators=0
diff --git a/mysql-test/t/rpl_sp-slave.opt b/mysql-test/t/rpl_stm_sp-slave.opt
index 611ee1f33be..611ee1f33be 100644
--- a/mysql-test/t/rpl_sp-slave.opt
+++ b/mysql-test/t/rpl_stm_sp-slave.opt
diff --git a/mysql-test/t/rpl_sp.test b/mysql-test/t/rpl_stm_sp.test
index 386582f8f1b..95c4543c952 100644
--- a/mysql-test/t/rpl_sp.test
+++ b/mysql-test/t/rpl_stm_sp.test
@@ -1,3 +1,6 @@
+# row-based and statement have expected binlog difference in result files
+-- source include/have_binlog_format_statement.inc
+
# Test of replication of stored procedures (WL#2146 for MySQL 5.0)
# Modified by WL#2971.
@@ -333,7 +336,7 @@ drop trigger trg;
insert into t1 values (1);
select * from t1;
--replace_column 2 # 5 #
-show binlog events in 'master-bin.000001' from 98;
+show binlog events in 'master-bin.000001' from 102;
sync_slave_with_master;
select * from t1;
diff --git a/mysql-test/t/rpl_stm_timezone-master.opt b/mysql-test/t/rpl_stm_timezone-master.opt
new file mode 100644
index 00000000000..8e43bfbbb7e
--- /dev/null
+++ b/mysql-test/t/rpl_stm_timezone-master.opt
@@ -0,0 +1 @@
+--default-time-zone=Europe/Moscow
diff --git a/mysql-test/t/rpl_timezone-slave.opt b/mysql-test/t/rpl_stm_timezone-slave.opt
index 191182c329c..191182c329c 100644
--- a/mysql-test/t/rpl_timezone-slave.opt
+++ b/mysql-test/t/rpl_stm_timezone-slave.opt
diff --git a/mysql-test/t/rpl_timezone.test b/mysql-test/t/rpl_stm_timezone.test
index 2e9883141d8..0cd6dbf5d89 100644
--- a/mysql-test/t/rpl_timezone.test
+++ b/mysql-test/t/rpl_stm_timezone.test
@@ -1,3 +1,6 @@
+# TBF - difference in row level logging
+-- source include/have_binlog_format_statement.inc
+
# Test of replication of time zones.
# There is currently some bug possibly in prepared statements (this
diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_stm_until.test
index e0ecf981fea..1bd87db88cb 100644
--- a/mysql-test/t/rpl_until.test
+++ b/mysql-test/t/rpl_stm_until.test
@@ -1,4 +1,7 @@
-source include/master-slave.inc;
+-- source include/have_binlog_format_statement.inc
+-- source include/master-slave.inc
+
+# Test is dependent on binlog positions
# prepare version for substitutions
let $VERSION=`select version()`;
@@ -19,12 +22,10 @@ create table t2(n int not null auto_increment primary key);
insert into t2 values (1),(2);
insert into t2 values (3),(4);
drop table t2;
---replace_result $VERSION VERSION
-show binlog events;
# try to replicate all queries until drop of t1
connection slave;
-start slave until master_log_file='master-bin.000001', master_log_pos=319;
+start slave until master_log_file='master-bin.000001', master_log_pos=323;
sleep 2;
wait_for_slave_to_stop;
# here table should be still not deleted
@@ -43,7 +44,7 @@ wait_for_slave_to_stop;
--replace_column 1 # 9 # 11 # 23 # 33 #
show slave status;
-# try replicate all until second insert to t2;
+# try replicate all up to and not including the second insert to t2;
start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=746;
sleep 2;
wait_for_slave_to_stop;
diff --git a/mysql-test/t/rpl_stm_user_variables.test b/mysql-test/t/rpl_stm_user_variables.test
new file mode 100644
index 00000000000..af4e46cdace
--- /dev/null
+++ b/mysql-test/t/rpl_stm_user_variables.test
@@ -0,0 +1,5 @@
+# row-based and statement binlog difference in result files
+-- source include/have_binlog_format_statement.inc
+-- source extra/rpl_tests/rpl_user_variables.test
+
+# End of 4.1 tests
diff --git a/mysql-test/t/rpl_stm_view.test b/mysql-test/t/rpl_stm_view.test
new file mode 100644
index 00000000000..39f39705f77
--- /dev/null
+++ b/mysql-test/t/rpl_stm_view.test
@@ -0,0 +1,50 @@
+# NYI - row-based cannot use CREATE ... SELECT
+--source include/have_binlog_format_statement.inc
+
+source include/master-slave.inc;
+--disable_warnings
+drop table if exists t1,v1;
+drop view if exists t1,v1;
+sync_slave_with_master;
+reset master;
+--enable_warnings
+
+#
+# Check that createion drop of view is replicated, also check replication of
+# updating of view
+#
+connection master;
+create table t1 (a int);
+insert into t1 values (1);
+create view v1 as select a from t1;
+insert into v1 values (2);
+select * from v1 order by a;
+sync_slave_with_master;
+# view already have to be on slave
+select * from v1 order by a;
+connection master;
+update v1 set a=3 where a=1;
+select * from v1 order by a;
+sync_slave_with_master;
+select * from v1 order by a;
+connection master;
+delete from v1 where a=2;
+select * from v1 order by a;
+sync_slave_with_master;
+select * from v1 order by a;
+connection master;
+# 'alter view' internally maped to creation, but still check that it works
+alter view v1 as select a as b from t1;
+sync_slave_with_master;
+select * from v1 order by 1;
+connection master;
+drop view v1;
+sync_slave_with_master;
+#error, because view have to be removed from slave
+-- error 1146
+select * from v1 order by a;
+connection master;
+drop table t1;
+sync_slave_with_master;
+--replace_column 2 # 5 #
+show binlog events limit 1,100;
diff --git a/mysql-test/t/rpl_temporary.test b/mysql-test/t/rpl_temporary.test
index fcb2391a9d8..0eb5d4074d8 100644
--- a/mysql-test/t/rpl_temporary.test
+++ b/mysql-test/t/rpl_temporary.test
@@ -1,4 +1,4 @@
-source include/master-slave.inc;
+-- source include/master-slave.inc
# Clean up old slave's binlogs.
# The slave is started with --log-slave-updates
@@ -81,9 +81,10 @@ drop temporary table t3;
select * from t2;
---replace_result $VERSION VERSION
---replace_column 2 # 5 #
-show binlog events;
+# Commented out 8/30/2005 to make compatable with both sbr and rbr
+#--replace_result $VERSION VERSION
+#--replace_column 2 # 5 #
+#show binlog events;
drop table t1, t2;
@@ -130,5 +131,3 @@ create temporary table t3 (f int);
sync_with_master;
# The server will now close done
-
-# End of 4.1 tests
diff --git a/mysql-test/t/rpl_trigger.test b/mysql-test/t/rpl_trigger.test
index fa6054372c7..0eca7308adc 100644
--- a/mysql-test/t/rpl_trigger.test
+++ b/mysql-test/t/rpl_trigger.test
@@ -1,7 +1,8 @@
#
# Test of triggers with replication
-#
-
+# Adding statement include due to Bug 12574
+# TODO: Remove statement include once 12574 is patched
+--source include/have_binlog_format_statement.inc
source include/master-slave.inc;
#
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index f73288f04ba..91973da6c22 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -4132,9 +4132,13 @@ end|
--error 1062
select bug12379()|
select 1|
+# statement-based binlogging will show warning which row-based won't;
+# so we hide it (this warning is already tested in rpl_stm_sp.test)
+--disable_warnings
call bug12379_1()|
select 2|
call bug12379_2()|
+--enable_warnings
select 3|
--error 1062
call bug12379_3()|
diff --git a/mysql-test/t/user_var-binlog.test b/mysql-test/t/user_var-binlog.test
index 004154339b2..a3128064c91 100644
--- a/mysql-test/t/user_var-binlog.test
+++ b/mysql-test/t/user_var-binlog.test
@@ -1,3 +1,6 @@
+# Requires statement logging
+-- source include/have_binlog_format_statement.inc
+# TODO: Create row based version once $MYSQL_BINLOG has new RB version
# Embedded server does not support binlogging
--source include/not_embedded.inc
@@ -10,7 +13,8 @@ INSERT INTO t1 VALUES(@`a b`);
set @var1= "';aaa";
SET @var2=char(ascii('a'));
insert into t1 values (@var1),(@var2);
-show binlog events from 98;
+--replace_column 2 # 5 #
+show binlog events from 102;
# more important than SHOW BINLOG EVENTS, mysqlbinlog (where we
# absolutely need variables names to be quoted and strings to be
# escaped).
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index a54bc550228..4d6c0d1e189 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -35,6 +35,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
mf_tempdir.c my_lock.c mf_brkhant.c my_alarm.c \
my_malloc.c my_realloc.c my_once.c mulalloc.c \
my_alloc.c safemalloc.c my_new.cc \
+ my_vle.c \
my_fopen.c my_fstream.c my_getsystime.c \
my_error.c errors.c my_div.c my_messnc.c \
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
diff --git a/mysys/base64.c b/mysys/base64.c
index b29c8ff8360..60218993c42 100644
--- a/mysys/base64.c
+++ b/mysys/base64.c
@@ -16,6 +16,7 @@
#include <base64.h>
#include <m_string.h> /* strchr() */
+#include <m_ctype.h> /* my_isspace() */
#ifndef MAIN
@@ -115,7 +116,6 @@ pos(unsigned char c)
} \
if (i == size) \
{ \
- i= size + 1; \
break; \
} \
}
diff --git a/mysys/my_vle.c b/mysys/my_vle.c
new file mode 100644
index 00000000000..3ddc1e4c6e0
--- /dev/null
+++ b/mysys/my_vle.c
@@ -0,0 +1,113 @@
+/*
+ Copyright (C) 2005 MySQL AB
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+*/
+
+/*
+ Variable length encoding.
+
+ A method to store an arbitrary-size non-negative integer. We let the
+ most significant bit of the number indicate that the next byte
+ should be contatenated to form the real number.
+*/
+
+#include "my_vle.h"
+
+/*
+ Function to encode an unsigned long as VLE. The bytes for the VLE
+ will be written to the location pointed to by 'out'. The maximum
+ number of bytes written will be 'max'.
+
+ PARAMETERS
+
+ out Pointer to beginning of where to store VLE bytes.
+ max Maximum number of bytes to write.
+ n Number to encode.
+
+ RETURN VALUE
+ On success, one past the end of the array containing the VLE
+ bytes. On failure, the 'out' pointer is returned.
+*/
+
+byte*
+my_vle_encode(byte* out, my_size_t max, ulong n)
+{
+ byte buf[my_vle_sizeof(n)];
+ byte *ptr= buf;
+ my_size_t len;
+
+ do
+ {
+ *ptr++= (n & 0x7F);
+ n>>= 7;
+ }
+ while (n > 0);
+
+ len= ptr - buf;
+
+ if (len <= max)
+ {
+ /*
+ The bytes are stored in reverse order in 'buf'. Let's write them
+ in correct order to the output buffer and set the MSB at the
+ same time.
+ */
+ while (ptr-- > buf)
+ {
+ byte v= *ptr;
+ if (ptr > buf)
+ v|= 0x80;
+ *out++= v;
+ }
+ }
+
+ return out;
+}
+
+/*
+ Function to decode a VLE representation of an integral value.
+
+
+ PARAMETERS
+
+ result_ptr Pointer to an unsigned long where the value will be written.
+ vle Pointer to the VLE bytes.
+
+ RETURN VALUE
+
+ One-past the end of the VLE bytes. The routine will never read
+ more than sizeof(*result_ptr) + 1 bytes.
+*/
+
+byte const*
+my_vle_decode(ulong *result_ptr, byte const *vle)
+{
+ ulong result= 0;
+ my_size_t cnt= 1;
+
+ do
+ {
+ result<<= 7;
+ result|= (*vle & 0x7F);
+ }
+ while ((*vle++ & 0x80) && ++cnt <= sizeof(*result_ptr) + 1);
+
+ if (cnt <= sizeof(*result_ptr) + 1)
+ *result_ptr= result;
+
+ return vle;
+}
diff --git a/sql/Makefile.am b/sql/Makefile.am
index a4f761fdc16..a9a0449fbb6 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -53,7 +53,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
sql_manager.h sql_map.h sql_string.h unireg.h \
sql_error.h field.h handler.h mysqld_suffix.h \
ha_heap.h ha_myisam.h ha_myisammrg.h ha_partition.h \
- opt_range.h protocol.h \
+ opt_range.h protocol.h rpl_tblmap.h \
sql_select.h structs.h table.h sql_udf.h hash_filo.h\
lex.h lex_symbol.h sql_acl.h sql_crypt.h \
log_event.h sql_repl.h slave.h rpl_filter.h \
@@ -87,7 +87,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \
sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
- slave.cc sql_repl.cc rpl_filter.cc \
+ slave.cc sql_repl.cc rpl_filter.cc rpl_tblmap.cc \
sql_union.cc sql_derived.cc \
client.c sql_client.cc mini_client_errors.c pack.c\
stacktrace.c repl_failsafe.h repl_failsafe.cc \
@@ -96,7 +96,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
tztime.cc my_time.c my_decimal.cc\
sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \
sp_cache.cc parse_file.cc sql_trigger.cc \
- sql_plugin.cc\
+ sql_plugin.cc sql_binlog.cc \
handlerton.cc
EXTRA_mysqld_SOURCES = ha_innodb.cc ha_berkeley.cc ha_archive.cc \
ha_innodb.h ha_berkeley.h ha_archive.h \
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 8b0cbe87562..d978327f2ce 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -827,6 +827,7 @@ ha_innobase::ha_innobase(TABLE_SHARE *table_arg)
HA_CAN_INDEX_BLOBS |
HA_CAN_SQL_HANDLER |
HA_NOT_EXACT_COUNT |
+ HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS |
HA_PRIMARY_KEY_IN_READ_INDEX |
HA_CAN_GEOMETRY |
HA_TABLE_SCAN_ON_INDEX),
@@ -3052,6 +3053,9 @@ ha_innobase::store_key_val_for_row(
continue;
}
+ /* In a column prefix index, we may need to truncate
+ the stored value: */
+
cs = key_part->field->charset();
src_start = record + key_part->offset;
@@ -3068,7 +3072,11 @@ ha_innobase::store_key_val_for_row(
memcpy(buff, src_start, len);
buff+=len;
- /* Pad the unused space with spaces */
+ /* Pad the unused space with spaces. Note that no
+ padding is ever needed for UCS-2 because in MySQL,
+ all UCS2 characters are 2 bytes, as MySQL does not
+ support surrogate pairs, which are needed to represent
+ characters in the range U+10000 to U+10FFFF. */
if (len < key_part->length) {
len = key_part->length - len;
@@ -3791,9 +3799,9 @@ ha_innobase::delete_row(
}
/**************************************************************************
-Removes a new lock set on a row. This can be called after a row has been read
-in the processing of an UPDATE or a DELETE query, if the option
-innodb_locks_unsafe_for_binlog is set. */
+Removes a new lock set on a row, if it was not read optimistically. This can
+be called after a row has been read in the processing of an UPDATE or a DELETE
+query, if the option innodb_locks_unsafe_for_binlog is set. */
void
ha_innobase::unlock_row(void)
@@ -3803,7 +3811,7 @@ ha_innobase::unlock_row(void)
DBUG_ENTER("ha_innobase::unlock_row");
- if (last_query_id != user_thd->query_id) {
+ if (UNIV_UNLIKELY(last_query_id != user_thd->query_id)) {
ut_print_timestamp(stderr);
sql_print_error("last_query_id is %lu != user_thd_query_id is "
"%lu", (ulong) last_query_id,
@@ -3811,9 +3819,45 @@ ha_innobase::unlock_row(void)
mem_analyze_corruption((byte *) prebuilt->trx);
ut_error;
}
-
- if (srv_locks_unsafe_for_binlog) {
+
+ switch (prebuilt->row_read_type) {
+ case ROW_READ_WITH_LOCKS:
+ if (!srv_locks_unsafe_for_binlog) {
+ break;
+ }
+ /* fall through */
+ case ROW_READ_TRY_SEMI_CONSISTENT:
row_unlock_for_mysql(prebuilt, FALSE);
+ break;
+ case ROW_READ_DID_SEMI_CONSISTENT:
+ prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
+ break;
+ }
+
+ DBUG_VOID_RETURN;
+}
+
+/* See handler.h and row0mysql.h for docs on this function. */
+bool
+ha_innobase::was_semi_consistent_read(void)
+/*=======================================*/
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+
+ return(prebuilt->row_read_type == ROW_READ_DID_SEMI_CONSISTENT);
+}
+
+/* See handler.h and row0mysql.h for docs on this function. */
+void
+ha_innobase::try_semi_consistent_read(bool yes)
+/*===========================================*/
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+
+ if (yes && srv_locks_unsafe_for_binlog) {
+ prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
+ } else {
+ prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
}
}
@@ -4328,6 +4372,13 @@ ha_innobase::rnd_init(
err = change_active_index(primary_key);
}
+ /* Don't use semi-consistent read in random row reads (by position).
+ This means we must disable semi_consistent_read if scan is false */
+
+ if (!scan) {
+ try_semi_consistent_read(0);
+ }
+
start_of_scan = 1;
return(err);
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index f9a185bd885..fd0d3aa7e8c 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -122,6 +122,8 @@ class ha_innobase: public handler
int write_row(byte * buf);
int update_row(const byte * old_data, byte * new_data);
int delete_row(const byte * buf);
+ bool was_semi_consistent_read();
+ void try_semi_consistent_read(bool yes);
void unlock_row();
int index_init(uint index, bool sorted);
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 8b4e0d9cfee..f20fb7304ba 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -647,7 +647,7 @@ bool ha_partition::create_handler_file(const char *name)
if (!m_is_sub_partitioned)
{
name_buffer_ptr= strmov(name_buffer_ptr, part_elem->partition_name)+1;
- *engine_array= (uchar) part_elem->engine_type;
+ *engine_array= (uchar) ha_legacy_type(part_elem->engine_type);
DBUG_PRINT("info", ("engine: %u", *engine_array));
engine_array++;
}
@@ -660,7 +660,7 @@ bool ha_partition::create_handler_file(const char *name)
name_buffer_ptr+= name_add(name_buffer_ptr,
part_elem->partition_name,
subpart_elem->partition_name);
- *engine_array= (uchar) part_elem->engine_type;
+ *engine_array= (uchar) ha_legacy_type(part_elem->engine_type);
engine_array++;
}
}
diff --git a/sql/handler.cc b/sql/handler.cc
index bcccdf2e2b0..59445a1b2f1 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -22,6 +22,7 @@
#endif
#include "mysql_priv.h"
+#include "rpl_filter.h"
#include "ha_heap.h"
#include "ha_myisam.h"
#include "ha_myisammrg.h"
@@ -29,7 +30,7 @@
#include <myisampack.h>
#include <errno.h>
-
+
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
#define NDB_MAX_ATTRIBUTES_IN_TABLE 128
#include "ha_ndbcluster.h"
@@ -37,12 +38,15 @@
#ifdef WITH_PARTITION_STORAGE_ENGINE
#include "ha_partition.h"
#endif
+
#ifdef WITH_INNOBASE_STORAGE_ENGINE
#include "ha_innodb.h"
#endif
extern handlerton *sys_table_types[];
+#define BITMAP_STACKBUF_SIZE (128/8)
+
/* static functions defined in this file */
static handler *create_default(TABLE_SHARE *table);
@@ -1937,6 +1941,9 @@ void handler::print_error(int error, myf errflag)
my_error(ER_NO_SUCH_TABLE, MYF(0), table_share->db.str,
table_share->table_name.str);
break;
+ case HA_ERR_RBR_LOGGING_FAILED:
+ textno= ER_BINLOG_ROW_LOGGING_FAILED;
+ break;
default:
{
/* The error was "unknown" to this function.
@@ -2721,6 +2728,7 @@ TYPELIB *ha_known_exts(void)
return &known_extensions;
}
+
static bool stat_print(THD *thd, const char *type, uint type_len,
const char *file, uint file_len,
const char *status, uint status_len)
@@ -2781,6 +2789,106 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat)
return result;
}
+/*
+ Function to check if the conditions for row-based binlogging is
+ correct for the table.
+
+ A row in the given table should be replicated if:
+ - Row-based replication is on
+ - It is not a temporary table
+ - The binlog is enabled
+ - The table shall be binlogged (binlog_*_db rules) [Seems disabled /Matz]
+*/
+
+#ifdef HAVE_ROW_BASED_REPLICATION
+static bool check_table_binlog_row_based(THD *thd, TABLE *table)
+{
+ return
+ binlog_row_based &&
+ thd && (thd->options & OPTION_BIN_LOG) &&
+ (table->s->tmp_table == NO_TMP_TABLE);
+}
+
+template<class RowsEventT> int binlog_log_row(TABLE* table,
+ const byte *before_record,
+ const byte *after_record)
+{
+ bool error= 0;
+ THD *const thd= current_thd;
+
+ if (check_table_binlog_row_based(thd, table))
+ {
+ MY_BITMAP cols;
+ /* Potential buffer on the stack for the bitmap */
+ uint32 bitbuf[BITMAP_STACKBUF_SIZE/sizeof(uint32)];
+ uint n_fields= table->s->fields;
+ my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8;
+ if (likely(!(error= bitmap_init(&cols,
+ use_bitbuf ? bitbuf : NULL,
+ (n_fields + 7) & ~7UL,
+ false))))
+ {
+ bitmap_set_all(&cols);
+ error=
+ RowsEventT::binlog_row_logging_function(thd, table,
+ table->file->has_transactions(),
+ &cols, table->s->fields,
+ before_record, after_record);
+ if (!use_bitbuf)
+ bitmap_free(&cols);
+ }
+ }
+ return error ? HA_ERR_RBR_LOGGING_FAILED : 0;
+}
+
+
+/*
+ Instantiate the versions we need for the above template function, because we
+ have -fno-implicit-template as compiling option.
+*/
+
+template int binlog_log_row<Write_rows_log_event>(TABLE *, const byte *, const byte *);
+template int binlog_log_row<Delete_rows_log_event>(TABLE *, const byte *, const byte *);
+template int binlog_log_row<Update_rows_log_event>(TABLE *, const byte *, const byte *);
+
+#endif /* HAVE_ROW_BASED_REPLICATION */
+
+int handler::ha_write_row(byte *buf)
+{
+ int error;
+ if (likely(!(error= write_row(buf))))
+ {
+#ifdef HAVE_ROW_BASED_REPLICATION
+ error= binlog_log_row<Write_rows_log_event>(table, 0, buf);
+#endif
+ }
+ return error;
+}
+
+int handler::ha_update_row(const byte *old_data, byte *new_data)
+{
+ int error;
+ if (likely(!(error= update_row(old_data, new_data))))
+ {
+#ifdef HAVE_ROW_BASED_REPLICATION
+ error= binlog_log_row<Update_rows_log_event>(table, old_data, new_data);
+#endif
+ }
+ return error;
+}
+
+int handler::ha_delete_row(const byte *buf)
+{
+ int error;
+ if (likely(!(error= delete_row(buf))))
+ {
+#ifdef HAVE_ROW_BASED_REPLICATION
+ error= binlog_log_row<Delete_rows_log_event>(table, buf, 0);
+#endif
+ }
+ return error;
+}
+
#ifdef HAVE_REPLICATION
/*
diff --git a/sql/handler.h b/sql/handler.h
index ff81a259a73..27b3ed3fab1 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -74,6 +74,13 @@
*/
#define HA_CAN_INSERT_DELAYED (1 << 14)
#define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
+/*
+ If HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS is set, it means that the engine can
+ do this: the position of an arbitrary record can be retrieved using
+ position() when the table has a primary key, effectively allowing random
+ access on the table based on a given record.
+*/
+#define HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS (1 << 16)
#define HA_NOT_DELETE_WITH_CACHE (1 << 18)
#define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
#define HA_CAN_FULLTEXT (1 << 21)
@@ -1054,11 +1061,9 @@ public:
uint get_index(void) const { return active_index; }
virtual int open(const char *name, int mode, uint test_if_locked)=0;
virtual int close(void)=0;
- virtual int write_row(byte * buf) { return HA_ERR_WRONG_COMMAND; }
- virtual int update_row(const byte * old_data, byte * new_data)
- { return HA_ERR_WRONG_COMMAND; }
- virtual int delete_row(const byte * buf)
- { return HA_ERR_WRONG_COMMAND; }
+ virtual int ha_write_row(byte * buf);
+ virtual int ha_update_row(const byte * old_data, byte * new_data);
+ virtual int ha_delete_row(const byte * buf);
/*
SYNOPSIS
start_bulk_update()
@@ -1189,6 +1194,26 @@ public:
virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
{ return extra(operation); }
virtual int external_lock(THD *thd, int lock_type) { return 0; }
+ /*
+ In an UPDATE or DELETE, if the row under the cursor was locked by another
+ transaction, and the engine used an optimistic read of the last
+ committed row value under the cursor, then the engine returns 1 from this
+ function. MySQL must NOT try to update this optimistic value. If the
+ optimistic value does not match the WHERE condition, MySQL can decide to
+ skip over this row. Currently only works for InnoDB. This can be used to
+ avoid unnecessary lock waits.
+
+ If this method returns nonzero, it will also signal the storage
+ engine that the next read will be a locking re-read of the row.
+ */
+ virtual bool was_semi_consistent_read() { return 0; }
+ /*
+ Tell the engine whether it should avoid unnecessary lock waits.
+ If yes, in an UPDATE or DELETE, if the row under the cursor was locked
+ by another transaction, the engine may try an optimistic read of
+ the last committed row value under the cursor.
+ */
+ virtual void try_semi_consistent_read(bool) {}
virtual void unlock_row() {}
virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
/*
@@ -1405,6 +1430,31 @@ public:
virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes)
{ return COMPATIBLE_DATA_NO; }
+
+private:
+
+ /*
+ Row-level primitives for storage engines.
+ These should be overridden by the storage engine class. To call
+ these methods, use the corresponding 'ha_*' method above.
+ */
+ friend int ndb_add_binlog_index(THD *, void *);
+
+ virtual int write_row(byte *buf __attribute__((unused)))
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+
+ virtual int update_row(const byte *old_data __attribute__((unused)),
+ byte *new_data __attribute__((unused)))
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+
+ virtual int delete_row(const byte *buf __attribute__((unused)))
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
};
/* Some extern variables used with handlers */
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index a8163a1758d..dc1cf6cc8b7 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -2662,7 +2662,7 @@ bool Item_sum_count_distinct::add()
*/
return tree->unique_add(table->record[0] + table->s->null_bytes);
}
- if ((error= table->file->write_row(table->record[0])) &&
+ if ((error= table->file->ha_write_row(table->record[0])) &&
error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE)
return TRUE;
diff --git a/sql/log.cc b/sql/log.cc
index d30cf3266f9..44d3869e9d5 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -47,6 +47,19 @@ static int binlog_commit(THD *thd, bool all);
static int binlog_rollback(THD *thd, bool all);
static int binlog_prepare(THD *thd, bool all);
+/*
+ This is a POD. Please keep it that way!
+
+ Don't add constructors, destructors, or virtual functions.
+*/
+struct binlog_trx_data {
+ bool empty() const {
+ return pending == NULL && my_b_tell(&trans_log) == 0;
+ }
+ IO_CACHE trans_log; // The transaction cache
+ Rows_log_event *pending; // The pending binrows event
+};
+
handlerton binlog_hton = {
MYSQL_HANDLERTON_INTERFACE_VERSION,
"binlog",
@@ -92,19 +105,45 @@ bool binlog_init()
static int binlog_close_connection(THD *thd)
{
- IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
- DBUG_ASSERT(mysql_bin_log.is_open() && !my_b_tell(trans_log));
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd->ha_data[binlog_hton.slot];
+ IO_CACHE *trans_log= &trx_data->trans_log;
+ DBUG_ASSERT(mysql_bin_log.is_open() && trx_data->empty());
close_cached_file(trans_log);
- my_free((gptr)trans_log, MYF(0));
+ thd->ha_data[binlog_hton.slot]= 0;
+ my_free((gptr)trx_data, MYF(0));
return 0;
}
-static int binlog_end_trans(THD *thd, IO_CACHE *trans_log, Log_event *end_ev)
+static int
+binlog_end_trans(THD *thd, binlog_trx_data *trx_data, Log_event *end_ev)
{
- int error=0;
DBUG_ENTER("binlog_end_trans");
+ int error=0;
+ IO_CACHE *trans_log= &trx_data->trans_log;
+
if (end_ev)
+ {
+ thd->binlog_flush_pending_rows_event(true);
error= mysql_bin_log.write(thd, trans_log, end_ev);
+ }
+ else
+ {
+ thd->binlog_delete_pending_rows_event();
+ }
+
+ /*
+ We need to step the table map version both after writing the
+ entire transaction to the log file and after rolling back the
+ transaction.
+
+ We need to step the table map version after writing the
+ transaction cache to disk. In addition, we need to step the table
+ map version on a rollback to ensure that a new table map event is
+ generated instead of the one that was written to the thrown-away
+ transaction cache.
+ */
+ ++mysql_bin_log.m_table_map_version;
statistic_increment(binlog_cache_use, &LOCK_status);
if (trans_log->disk_writes != 0)
@@ -130,32 +169,36 @@ static int binlog_prepare(THD *thd, bool all)
static int binlog_commit(THD *thd, bool all)
{
- IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
DBUG_ENTER("binlog_commit");
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd->ha_data[binlog_hton.slot];
+ IO_CACHE *trans_log= &trx_data->trans_log;
DBUG_ASSERT(mysql_bin_log.is_open() &&
(all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))));
- if (!my_b_tell(trans_log))
+ if (trx_data->empty())
{
// we're here because trans_log was flushed in MYSQL_LOG::log()
DBUG_RETURN(0);
}
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
- DBUG_RETURN(binlog_end_trans(thd, trans_log, &qev));
+ DBUG_RETURN(binlog_end_trans(thd, trx_data, &qev));
}
static int binlog_rollback(THD *thd, bool all)
{
- int error=0;
- IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
DBUG_ENTER("binlog_rollback");
+ int error=0;
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd->ha_data[binlog_hton.slot];
+ IO_CACHE *trans_log= &trx_data->trans_log;
/*
First assert is guaranteed - see trans_register_ha() call below.
The second must be true. If it is not, we're registering
unnecessary, doing extra work. The cause should be found and eliminated
*/
DBUG_ASSERT(all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)));
- DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log));
+ DBUG_ASSERT(mysql_bin_log.is_open() && !trx_data->empty());
/*
Update the binary log with a BEGIN/ROLLBACK block if we have
cached some queries and we updated some non-transactional
@@ -165,10 +208,10 @@ static int binlog_rollback(THD *thd, bool all)
if (unlikely(thd->options & OPTION_STATUS_NO_TRANS_UPDATE))
{
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE);
- error= binlog_end_trans(thd, trans_log, &qev);
+ error= binlog_end_trans(thd, trx_data, &qev);
}
else
- error= binlog_end_trans(thd, trans_log, 0);
+ error= binlog_end_trans(thd, trx_data, 0);
DBUG_RETURN(error);
}
@@ -195,8 +238,10 @@ static int binlog_rollback(THD *thd, bool all)
static int binlog_savepoint_set(THD *thd, void *sv)
{
- IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
DBUG_ENTER("binlog_savepoint_set");
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd->ha_data[binlog_hton.slot];
+ IO_CACHE *trans_log= &trx_data->trans_log;
DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log));
*(my_off_t *)sv= my_b_tell(trans_log);
@@ -207,8 +252,10 @@ static int binlog_savepoint_set(THD *thd, void *sv)
static int binlog_savepoint_rollback(THD *thd, void *sv)
{
- IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
DBUG_ENTER("binlog_savepoint_rollback");
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd->ha_data[binlog_hton.slot];
+ IO_CACHE *trans_log= &trx_data->trans_log;
DBUG_ASSERT(mysql_bin_log.is_open() && my_b_tell(trans_log));
/*
@@ -367,6 +414,7 @@ MYSQL_LOG::MYSQL_LOG()
:bytes_written(0), last_time(0), query_start(0), name(0),
prepared_xids(0), log_type(LOG_CLOSED), file_id(1), open_count(1),
write_error(FALSE), inited(FALSE), need_start_event(TRUE),
+ m_table_map_version(0),
description_event_for_exec(0), description_event_for_queue(0)
{
/*
@@ -1363,7 +1411,7 @@ void MYSQL_LOG::new_file(bool need_lock)
to change base names at some point.
*/
THD *thd = current_thd; /* may be 0 if we are reacting to SIGHUP */
- Rotate_log_event r(thd,new_name+dirname_length(new_name),
+ Rotate_log_event r(new_name+dirname_length(new_name),
0, LOG_EVENT_OFFSET, 0);
r.write(&log_file);
bytes_written += r.data_written;
@@ -1589,6 +1637,162 @@ bool MYSQL_LOG::is_query_in_union(THD *thd, query_id_t query_id_param)
query_id_param >= thd->binlog_evt_union.first_query_id);
}
+
+/*
+ These functions are placed in this file since they need access to
+ binlog_hton, which has internal linkage.
+*/
+
+int THD::binlog_setup_trx_data()
+{
+ DBUG_ENTER("THD::binlog_setup_trx_data");
+ binlog_trx_data *trx_data=
+ (binlog_trx_data*) ha_data[binlog_hton.slot];
+
+ if (trx_data)
+ DBUG_RETURN(0); // Already set up
+
+ ha_data[binlog_hton.slot]= trx_data=
+ (binlog_trx_data*) my_malloc(sizeof(binlog_trx_data), MYF(MY_ZEROFILL));
+ if (!trx_data ||
+ open_cached_file(&trx_data->trans_log, mysql_tmpdir,
+ LOG_PREFIX, binlog_cache_size, MYF(MY_WME)))
+ {
+ my_free((gptr)trx_data, MYF(MY_ALLOW_ZERO_PTR));
+ ha_data[binlog_hton.slot]= 0;
+ DBUG_RETURN(1); // Didn't manage to set it up
+ }
+ trx_data->trans_log.end_of_file= max_binlog_cache_size;
+ DBUG_RETURN(0);
+}
+
+Rows_log_event*
+THD::binlog_get_pending_rows_event() const
+{
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) ha_data[binlog_hton.slot];
+ /*
+ This is less than ideal, but here's the story: If there is no
+ trx_data, prepare_pending_rows_event() has never been called
+ (since the trx_data is set up there). In that case, we just return
+ NULL.
+ */
+ return trx_data ? trx_data->pending : NULL;
+}
+
+void
+THD::binlog_set_pending_rows_event(Rows_log_event* ev)
+{
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) ha_data[binlog_hton.slot];
+ DBUG_ASSERT(trx_data);
+ trx_data->pending= ev;
+}
+
+
+/*
+ Moves the last bunch of rows from the pending Rows event to the binlog
+ (either cached binlog if transaction, or disk binlog). Sets a new pending
+ event.
+*/
+int MYSQL_LOG::flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event)
+{
+ DBUG_ENTER("MYSQL_LOG::flush_and_set_pending_rows_event(event)");
+ DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
+ DBUG_PRINT("enter", ("event=%p", event));
+
+ int error= 0;
+
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd->ha_data[binlog_hton.slot];
+
+ DBUG_ASSERT(trx_data);
+
+ if (Rows_log_event* pending= trx_data->pending)
+ {
+ IO_CACHE *file= &log_file;
+
+ /*
+ Decide if we should write to the log file directly or to the
+ transaction log.
+ */
+ if (pending->get_cache_stmt() || my_b_tell(&trx_data->trans_log))
+ file= &trx_data->trans_log;
+
+ /*
+ If we are writing to the log file directly, we could avoid
+ locking the log. This does not work since we need to step the
+ m_table_map_version below, and that change has to be protected
+ by the LOCK_log mutex.
+ */
+ pthread_mutex_lock(&LOCK_log);
+
+ /*
+ Write a table map if necessary
+ */
+ if (pending->maybe_write_table_map(thd, file, this))
+ {
+ pthread_mutex_unlock(&LOCK_log);
+ DBUG_RETURN(2);
+ }
+
+ /*
+ Write pending event to log file or transaction cache
+ */
+ if (pending->write(file))
+ {
+ pthread_mutex_unlock(&LOCK_log);
+ DBUG_RETURN(1);
+ }
+
+ /*
+ We step the table map version if we are writing an event
+ representing the end of a statement. We do this regardless of
+ wheather we write to the transaction cache or to directly to the
+ file.
+
+ In an ideal world, we could avoid stepping the table map version
+ if we were writing to a transaction cache, since we could then
+ reuse the table map that was written earlier in the transaction
+ cache. This does not work since STMT_END_F implies closing all
+ table mappings on the slave side.
+
+ TODO: Find a solution so that table maps does not have to be
+ written several times within a transaction.
+ */
+ if (pending->get_flags(Rows_log_event::STMT_END_F))
+ ++m_table_map_version;
+
+ delete pending;
+
+ if (file == &log_file)
+ {
+ error= flush_and_sync();
+ if (!error)
+ {
+ signal_update();
+ rotate_and_purge(RP_LOCK_LOG_IS_ALREADY_LOCKED);
+ }
+ }
+
+ pthread_mutex_unlock(&LOCK_log);
+ }
+ else if (event && event->get_cache_stmt()) /* && pending == 0 */
+ {
+ /*
+ If we are setting a non-null event for a table that is
+ transactional, we start a transaction here as well.
+ */
+ trans_register_ha(thd,
+ thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN),
+ &binlog_hton);
+ }
+
+ trx_data->pending= event;
+
+ DBUG_RETURN(error);
+}
+
/*
Write an event to the binary log
*/
@@ -1609,7 +1813,29 @@ bool MYSQL_LOG::write(Log_event *event_info)
thd->binlog_evt_union.unioned_events_trans |= event_info->cache_stmt;
DBUG_RETURN(0);
}
-
+
+ /*
+ Flush the pending rows event to the transaction cache or to the
+ log file. Since this function potentially aquire the LOCK_log
+ mutex, we do this before aquiring the LOCK_log mutex in this
+ function.
+
+ This is not optimal, but necessary in the current implementation
+ since there is code that writes rows to system tables without
+ using some way to flush the pending event (e.g., binlog_query()).
+
+ TODO: There shall be no writes to any system table after calling
+ binlog_query(), so these writes has to be moved to before the call
+ of binlog_query() for correct functioning.
+
+ This is necessesary not only for RBR, but the master might crash
+ after binlogging the query but before changing the system tables.
+ This means that the slave and the master are not in the same state
+ (after the master has restarted), so therefore we have to
+ eliminate this problem.
+ */
+ thd->binlog_flush_pending_rows_event(true);
+
pthread_mutex_lock(&LOCK_log);
/*
@@ -1649,37 +1875,26 @@ bool MYSQL_LOG::write(Log_event *event_info)
*/
if (opt_using_transactions && thd)
{
- IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
+ if (thd->binlog_setup_trx_data())
+ goto err;
- if (event_info->get_cache_stmt())
- {
- if (!trans_log)
- {
- thd->ha_data[binlog_hton.slot]= trans_log= (IO_CACHE *)
- my_malloc(sizeof(IO_CACHE), MYF(MY_ZEROFILL));
- if (!trans_log || open_cached_file(trans_log, mysql_tmpdir,
- LOG_PREFIX,
- binlog_cache_size, MYF(MY_WME)))
- {
- my_free((gptr)trans_log, MYF(MY_ALLOW_ZERO_PTR));
- thd->ha_data[binlog_hton.slot]= trans_log= 0;
- goto err;
- }
- trans_log->end_of_file= max_binlog_cache_size;
- trans_register_ha(thd,
- thd->options & (OPTION_NOT_AUTOCOMMIT |
- OPTION_BEGIN),
- &binlog_hton);
- }
- else if (!my_b_tell(trans_log))
- trans_register_ha(thd,
- thd->options & (OPTION_NOT_AUTOCOMMIT |
- OPTION_BEGIN),
- &binlog_hton);
- file= trans_log;
- }
- else if (trans_log && my_b_tell(trans_log))
+ binlog_trx_data *const trx_data=
+ (binlog_trx_data*) thd->ha_data[binlog_hton.slot];
+ IO_CACHE *trans_log= &trx_data->trans_log;
+
+ if (event_info->get_cache_stmt() && !my_b_tell(trans_log))
+ trans_register_ha(thd,
+ thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN),
+ &binlog_hton);
+
+ if (event_info->get_cache_stmt() || my_b_tell(trans_log))
file= trans_log;
+ /*
+ Note: as Mats suggested, for all the cases above where we write to
+ trans_log, it sounds unnecessary to lock LOCK_log. We should rather
+ test first if we want to write to trans_log, and if not, lock
+ LOCK_log. TODO.
+ */
}
#endif
DBUG_PRINT("info",("event type=%d",event_info->get_type_code()));
@@ -1694,42 +1909,49 @@ bool MYSQL_LOG::write(Log_event *event_info)
of the SQL command
*/
+ /*
+ If row-based binlogging, Insert_id, Rand and other kind of "setting
+ context" events are not needed.
+ */
if (thd)
{
- if (thd->last_insert_id_used)
+ if (!binlog_row_based)
{
- Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
- thd->current_insert_id);
- if (e.write(file))
- goto err;
- }
- if (thd->insert_id_used)
- {
- Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,thd->last_insert_id);
- if (e.write(file))
- goto err;
- }
- if (thd->rand_used)
- {
- Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
- if (e.write(file))
- goto err;
- }
- if (thd->user_var_events.elements)
- {
- for (uint i= 0; i < thd->user_var_events.elements; i++)
- {
- BINLOG_USER_VAR_EVENT *user_var_event;
- get_dynamic(&thd->user_var_events,(gptr) &user_var_event, i);
- User_var_log_event e(thd, user_var_event->user_var_event->name.str,
- user_var_event->user_var_event->name.length,
- user_var_event->value,
- user_var_event->length,
- user_var_event->type,
- user_var_event->charset_number);
- if (e.write(file))
- goto err;
- }
+ if (thd->last_insert_id_used)
+ {
+ Intvar_log_event e(thd,(uchar) LAST_INSERT_ID_EVENT,
+ thd->current_insert_id);
+ if (e.write(file))
+ goto err;
+ }
+ if (thd->insert_id_used)
+ {
+ Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,thd->last_insert_id);
+ if (e.write(file))
+ goto err;
+ }
+ if (thd->rand_used)
+ {
+ Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
+ if (e.write(file))
+ goto err;
+ }
+ if (thd->user_var_events.elements)
+ {
+ for (uint i= 0; i < thd->user_var_events.elements; i++)
+ {
+ BINLOG_USER_VAR_EVENT *user_var_event;
+ get_dynamic(&thd->user_var_events,(gptr) &user_var_event, i);
+ User_var_log_event e(thd, user_var_event->user_var_event->name.str,
+ user_var_event->user_var_event->name.length,
+ user_var_event->value,
+ user_var_event->length,
+ user_var_event->type,
+ user_var_event->charset_number);
+ if (e.write(file))
+ goto err;
+ }
+ }
}
}
@@ -1760,6 +1982,9 @@ err:
}
}
+ if (event_info->flags & LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F)
+ ++m_table_map_version;
+
pthread_mutex_unlock(&LOCK_log);
DBUG_RETURN(error);
}
@@ -2307,6 +2532,44 @@ void MYSQL_LOG::signal_update()
DBUG_VOID_RETURN;
}
+#ifndef MYSQL_CLIENT
+bool MYSQL_LOG::write_table_map(THD *thd, IO_CACHE *file, TABLE* table,
+ bool is_transactional)
+{
+ DBUG_ENTER("MYSQL_LOG::write_table_map()");
+ DBUG_PRINT("enter", ("table=%p (%s: %u)",
+ table, table->s->table_name, table->s->table_map_id));
+
+ /* Pre-conditions */
+ DBUG_ASSERT(binlog_row_based && is_open());
+ DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
+
+#ifndef DBUG_OFF
+ /*
+ We only need to execute under the LOCK_log mutex if we are writing
+ to the log file; otherwise, we are writing to a thread-specific
+ transaction cache and there is no need to serialize this event
+ with events in other threads.
+ */
+ if (file == &log_file)
+ safe_mutex_assert_owner(&LOCK_log);
+#endif
+
+ Table_map_log_event::flag_set const
+ flags= Table_map_log_event::NO_FLAGS;
+
+ Table_map_log_event
+ the_event(thd, table, table->s->table_map_id, is_transactional, flags);
+
+ if (the_event.write(file))
+ DBUG_RETURN(1);
+
+ table->s->table_map_version= m_table_map_version;
+ DBUG_RETURN(0);
+}
+#endif /* !defined(MYSQL_CLIENT) */
+
+
#ifdef __NT__
void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
uint length, int buffLen)
@@ -3013,9 +3276,11 @@ void TC_LOG_BINLOG::close()
*/
int TC_LOG_BINLOG::log(THD *thd, my_xid xid)
{
+ DBUG_ENTER("TC_LOG_BINLOG::log");
Xid_log_event xle(thd, xid);
- IO_CACHE *trans_log= (IO_CACHE*)thd->ha_data[binlog_hton.slot];
- return !binlog_end_trans(thd, trans_log, &xle); // invert return value
+ binlog_trx_data *trx_data=
+ (binlog_trx_data*) thd->ha_data[binlog_hton.slot];
+ DBUG_RETURN(!binlog_end_trans(thd, trx_data, &xle)); // invert return value
}
void TC_LOG_BINLOG::unlog(ulong cookie, my_xid xid)
diff --git a/sql/log.h b/sql/log.h
new file mode 100644
index 00000000000..ea2946c2d86
--- /dev/null
+++ b/sql/log.h
@@ -0,0 +1,332 @@
+/* Copyright (C) 2005 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef LOG_H
+#define LOG_H
+
+struct st_relay_log_info;
+
+class Format_description_log_event;
+
+/*
+ Transaction Coordinator log - a base abstract class
+ for two different implementations
+*/
+class TC_LOG
+{
+ public:
+ int using_heuristic_recover();
+ TC_LOG() {}
+ virtual ~TC_LOG() {}
+
+ virtual int open(const char *opt_name)=0;
+ virtual void close()=0;
+ virtual int log(THD *thd, my_xid xid)=0;
+ virtual void unlog(ulong cookie, my_xid xid)=0;
+};
+
+class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
+{
+ public:
+ int open(const char *opt_name) { return 0; }
+ void close() { }
+ int log(THD *thd, my_xid xid) { return 1; }
+ void unlog(ulong cookie, my_xid xid) { }
+};
+
+#ifdef HAVE_MMAP
+class TC_LOG_MMAP: public TC_LOG
+{
+ public: // only to keep Sun Forte on sol9x86 happy
+ typedef enum {
+ POOL, // page is in pool
+ ERROR, // last sync failed
+ DIRTY // new xids added since last sync
+ } PAGE_STATE;
+
+ private:
+ typedef struct st_page {
+ struct st_page *next; // page a linked in a fifo queue
+ my_xid *start, *end; // usable area of a page
+ my_xid *ptr; // next xid will be written here
+ int size, free; // max and current number of free xid slots on the page
+ int waiters; // number of waiters on condition
+ PAGE_STATE state; // see above
+ pthread_mutex_t lock; // to access page data or control structure
+ pthread_cond_t cond; // to wait for a sync
+ } PAGE;
+
+ char logname[FN_REFLEN];
+ File fd;
+ my_off_t file_length;
+ uint npages, inited;
+ uchar *data;
+ struct st_page *pages, *syncing, *active, *pool, *pool_last;
+ /*
+ note that, e.g. LOCK_active is only used to protect
+ 'active' pointer, to protect the content of the active page
+ one has to use active->lock.
+ Same for LOCK_pool and LOCK_sync
+ */
+ pthread_mutex_t LOCK_active, LOCK_pool, LOCK_sync;
+ pthread_cond_t COND_pool, COND_active;
+
+ public:
+ TC_LOG_MMAP(): inited(0) {}
+ int open(const char *opt_name);
+ void close();
+ int log(THD *thd, my_xid xid);
+ void unlog(ulong cookie, my_xid xid);
+ int recover();
+
+ private:
+ void get_active_from_pool();
+ int sync();
+ int overflow();
+};
+#else
+#define TC_LOG_MMAP TC_LOG_DUMMY
+#endif
+
+extern TC_LOG *tc_log;
+extern TC_LOG_MMAP tc_log_mmap;
+extern TC_LOG_DUMMY tc_log_dummy;
+
+/* log info errors */
+#define LOG_INFO_EOF -1
+#define LOG_INFO_IO -2
+#define LOG_INFO_INVALID -3
+#define LOG_INFO_SEEK -4
+#define LOG_INFO_MEM -6
+#define LOG_INFO_FATAL -7
+#define LOG_INFO_IN_USE -8
+
+/* bitmap to SQL_LOG::close() */
+#define LOG_CLOSE_INDEX 1
+#define LOG_CLOSE_TO_BE_OPENED 2
+#define LOG_CLOSE_STOP_EVENT 4
+
+struct st_relay_log_info;
+
+typedef struct st_log_info
+{
+ char log_file_name[FN_REFLEN];
+ my_off_t index_file_offset, index_file_start_offset;
+ my_off_t pos;
+ bool fatal; // if the purge happens to give us a negative offset
+ pthread_mutex_t lock;
+ st_log_info():fatal(0) { pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);}
+ ~st_log_info() { pthread_mutex_destroy(&lock);}
+} LOG_INFO;
+
+class Log_event;
+class Rows_log_event;
+
+enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN};
+
+/*
+ TODO split MYSQL_LOG into base MYSQL_LOG and
+ MYSQL_QUERY_LOG, MYSQL_SLOW_LOG, MYSQL_BIN_LOG
+ most of the code from MYSQL_LOG should be in the MYSQL_BIN_LOG
+ only (TC_LOG included)
+
+ TODO use mmap instead of IO_CACHE for binlog
+ (mmap+fsync is two times faster than write+fsync)
+*/
+
+class MYSQL_LOG: public TC_LOG
+{
+ private:
+ /* LOCK_log and LOCK_index are inited by init_pthread_objects() */
+ pthread_mutex_t LOCK_log, LOCK_index;
+ pthread_mutex_t LOCK_prep_xids;
+ pthread_cond_t COND_prep_xids;
+ pthread_cond_t update_cond;
+ ulonglong bytes_written;
+ time_t last_time,query_start;
+ IO_CACHE log_file;
+ IO_CACHE index_file;
+ char *name;
+ char time_buff[20],db[NAME_LEN+1];
+ char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
+ /*
+ The max size before rotation (usable only if log_type == LOG_BIN: binary
+ logs and relay logs).
+ For a binlog, max_size should be max_binlog_size.
+ For a relay log, it should be max_relay_log_size if this is non-zero,
+ max_binlog_size otherwise.
+ max_size is set in init(), and dynamically changed (when one does SET
+ GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and
+ fix_max_relay_log_size).
+ */
+ ulong max_size;
+ ulong prepared_xids; /* for tc log - number of xids to remember */
+ volatile enum_log_type log_type;
+ enum cache_type io_cache_type;
+ // current file sequence number for load data infile binary logging
+ uint file_id;
+ uint open_count; // For replication
+ int readers_count;
+ bool write_error, inited;
+ bool need_start_event;
+ /*
+ no_auto_events means we don't want any of these automatic events :
+ Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't
+ want a Rotate_log event to be written to the relay log. When we start a
+ relay log etc. So in 4.x this is 1 for relay logs, 0 for binlogs.
+ In 5.0 it's 0 for relay logs too!
+ */
+ bool no_auto_events;
+ friend class Log_event;
+
+public:
+ ulonglong m_table_map_version;
+
+ /*
+ These describe the log's format. This is used only for relay logs.
+ _for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
+ necessary to have 2 distinct objects, because the I/O thread may be reading
+ events in a different format from what the SQL thread is reading (consider
+ the case of a master which has been upgraded from 5.0 to 5.1 without doing
+ RESET MASTER, or from 4.x to 5.0).
+ */
+ Format_description_log_event *description_event_for_exec,
+ *description_event_for_queue;
+
+ MYSQL_LOG();
+ /*
+ note that there's no destructor ~MYSQL_LOG() !
+ The reason is that we don't want it to be automatically called
+ on exit() - but only during the correct shutdown process
+ */
+
+ int open(const char *opt_name);
+ void close();
+ int log(THD *thd, my_xid xid);
+ void unlog(ulong cookie, my_xid xid);
+ int recover(IO_CACHE *log, Format_description_log_event *fdle);
+#if !defined(MYSQL_CLIENT)
+ bool is_table_mapped(TABLE *table) const
+ {
+ return table->s->table_map_version == m_table_map_version;
+ }
+
+ int flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event);
+
+#endif /* !defined(MYSQL_CLIENT) */
+ void reset_bytes_written()
+ {
+ bytes_written = 0;
+ }
+ void harvest_bytes_written(ulonglong* counter)
+ {
+#ifndef DBUG_OFF
+ char buf1[22],buf2[22];
+#endif
+ DBUG_ENTER("harvest_bytes_written");
+ (*counter)+=bytes_written;
+ DBUG_PRINT("info",("counter: %s bytes_written: %s", llstr(*counter,buf1),
+ llstr(bytes_written,buf2)));
+ bytes_written=0;
+ DBUG_VOID_RETURN;
+ }
+ void set_max_size(ulong max_size_arg);
+ void signal_update();
+ void wait_for_update(THD* thd, bool master_or_slave);
+ void set_need_start_event() { need_start_event = 1; }
+ void init(enum_log_type log_type_arg,
+ enum cache_type io_cache_type_arg,
+ bool no_auto_events_arg, ulong max_size);
+ void init_pthread_objects();
+ void cleanup();
+ bool open(const char *log_name,
+ enum_log_type log_type,
+ const char *new_name,
+ enum cache_type io_cache_type_arg,
+ bool no_auto_events_arg, ulong max_size,
+ bool null_created);
+ const char *generate_name(const char *log_name, const char *suffix,
+ bool strip_ext, char *buff);
+ /* simplified open_xxx wrappers for the gigantic open above */
+ bool open_query_log(const char *log_name)
+ {
+ char buf[FN_REFLEN];
+ return open(generate_name(log_name, ".log", 0, buf),
+ LOG_NORMAL, 0, WRITE_CACHE, 0, 0, 0);
+ }
+ bool open_slow_log(const char *log_name)
+ {
+ char buf[FN_REFLEN];
+ return open(generate_name(log_name, "-slow.log", 0, buf),
+ LOG_NORMAL, 0, WRITE_CACHE, 0, 0, 0);
+ }
+ bool open_index_file(const char *index_file_name_arg,
+ const char *log_name);
+ void new_file(bool need_lock);
+ bool write(THD *thd, enum enum_server_command command,
+ const char *format,...);
+ bool write(THD *thd, const char *query, uint query_length,
+ time_t query_start=0);
+ bool write(Log_event* event_info); // binary log write
+ bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event);
+
+ bool write_table_map(THD *thd, IO_CACHE *cache, TABLE *table, bool is_trans);
+
+ void start_union_events(THD *thd);
+ void stop_union_events(THD *thd);
+ bool is_query_in_union(THD *thd, query_id_t query_id_param);
+
+ /*
+ v stands for vector
+ invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
+ */
+ bool appendv(const char* buf,uint len,...);
+ bool append(Log_event* ev);
+
+ int generate_new_name(char *new_name,const char *old_name);
+ void make_log_name(char* buf, const char* log_ident);
+ bool is_active(const char* log_file_name);
+ int update_log_index(LOG_INFO* linfo, bool need_update_threads);
+ void rotate_and_purge(uint flags);
+ bool flush_and_sync();
+ int purge_logs(const char *to_log, bool included,
+ bool need_mutex, bool need_update_threads,
+ ulonglong *decrease_log_space);
+ int purge_logs_before_date(time_t purge_time);
+ int purge_first_log(struct st_relay_log_info* rli, bool included);
+ bool reset_logs(THD* thd);
+ void close(uint exiting);
+
+ // iterating through the log index file
+ int find_log_pos(LOG_INFO* linfo, const char* log_name,
+ bool need_mutex);
+ int find_next_log(LOG_INFO* linfo, bool need_mutex);
+ int get_current_log(LOG_INFO* linfo);
+ uint next_file_id();
+ inline bool is_open() { return log_type != LOG_CLOSED; }
+ inline char* get_index_fname() { return index_file_name;}
+ inline char* get_log_fname() { return log_file_name; }
+ inline char* get_name() { return name; }
+ inline pthread_mutex_t* get_log_lock() { return &LOCK_log; }
+ inline IO_CACHE* get_log_file() { return &log_file; }
+
+ inline void lock_index() { pthread_mutex_lock(&LOCK_index);}
+ inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
+ inline IO_CACHE *get_index_file() { return &index_file;}
+ inline uint32 get_open_count() { return open_count; }
+};
+
+#endif /* LOG_H */
diff --git a/sql/log_event.cc b/sql/log_event.cc
index c8f8ff40700..6e256a0c295 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -21,11 +21,14 @@
#pragma implementation // gcc: Class implementation
#endif
-#include "mysql_priv.h"
+#include "mysql_priv.h"
#include "slave.h"
#include "rpl_filter.h"
#include <my_dir.h>
#endif /* MYSQL_CLIENT */
+#include <base64.h>
+#include <my_bitmap.h>
+#include <my_vle.h>
#define log_cs &my_charset_latin1
@@ -232,6 +235,7 @@ char *str_to_hex(char *to, const char *from, uint len)
commands just before it prints a query.
*/
+#ifdef MYSQL_CLIENT
static void print_set_option(FILE* file, uint32 bits_changed, uint32 option,
uint32 flags, const char* name, bool* need_comma)
{
@@ -243,6 +247,7 @@ static void print_set_option(FILE* file, uint32 bits_changed, uint32 option,
*need_comma= 1;
}
}
+#endif
/**************************************************************************
Log_event methods (= the parent class of all events)
@@ -271,6 +276,10 @@ const char* Log_event::get_type_str()
case XID_EVENT: return "Xid";
case USER_VAR_EVENT: return "User var";
case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
+ case TABLE_MAP_EVENT: return "Table_map";
+ case WRITE_ROWS_EVENT: return "Write_rows";
+ case UPDATE_ROWS_EVENT: return "Update_rows";
+ case DELETE_ROWS_EVENT: return "Delete_rows";
case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
default: return "Unknown"; /* impossible */
@@ -778,6 +787,9 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
}
+ /* To check the integrity of the Log_event_type enumeration */
+ DBUG_ASSERT(buf[EVENT_TYPE_OFFSET] < ENUM_END_EVENT);
+
switch(buf[EVENT_TYPE_OFFSET]) {
case QUERY_EVENT:
ev = new Query_log_event(buf, event_len, description_event, QUERY_EVENT);
@@ -829,6 +841,20 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
case FORMAT_DESCRIPTION_EVENT:
ev = new Format_description_log_event(buf, event_len, description_event);
break;
+#if defined(HAVE_REPLICATION) && defined(HAVE_ROW_BASED_REPLICATION)
+ case WRITE_ROWS_EVENT:
+ ev = new Write_rows_log_event(buf, event_len, description_event);
+ break;
+ case UPDATE_ROWS_EVENT:
+ ev = new Update_rows_log_event(buf, event_len, description_event);
+ break;
+ case DELETE_ROWS_EVENT:
+ ev = new Delete_rows_log_event(buf, event_len, description_event);
+ break;
+ case TABLE_MAP_EVENT:
+ ev = new Table_map_log_event(buf, event_len, description_event);
+ break;
+#endif
case BEGIN_LOAD_QUERY_EVENT:
ev = new Begin_load_query_log_event(buf, event_len, description_event);
break;
@@ -952,6 +978,24 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
}
+void Log_event::print_base64(FILE* file, PRINT_EVENT_INFO* print_event_info)
+{
+ uchar *ptr= (uchar*)temp_buf;
+ my_off_t size= uint4korr(ptr + EVENT_LEN_OFFSET);
+
+ char *tmp_str=
+ (char *) my_malloc(base64_needed_encoded_length(size), MYF(MY_WME));
+ if (!tmp_str) {
+ fprintf(stderr, "\nError: Out of memory. "
+ "Could not print correct binlog event.\n");
+ return;
+ }
+ int res= base64_encode(ptr, size, tmp_str);
+ fprintf(file, "\nBINLOG '\n%s\n';\n", tmp_str);
+ my_free(tmp_str, MYF(0));
+}
+
+
/*
Log_event::print_timestamp()
*/
@@ -1714,7 +1758,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli, const char *query
clear_all_errors(thd, rli); /* Can ignore query */
else
{
- slave_print_error(rli,expected_error,
+ slave_print_msg(ERROR_LEVEL, rli, expected_error,
"\
Query partially completed on the master (error on master: %d) \
and was aborted. There is a chance that your master is inconsistent at this \
@@ -1743,16 +1787,16 @@ compare_errors:
!ignored_error_code(actual_error) &&
!ignored_error_code(expected_error))
{
- slave_print_error(rli, 0,
- "\
-Query caused different errors on master and slave. \
+ slave_print_msg(ERROR_LEVEL, rli, 0,
+ "\
+Query caused different errors on master and slave. \
Error on master: '%s' (%d), Error on slave: '%s' (%d). \
Default database: '%s'. Query: '%s'",
- ER_SAFE(expected_error),
- expected_error,
- actual_error ? thd->net.last_error: "no error",
- actual_error,
- print_slave_db_safe(db), query_arg);
+ ER_SAFE(expected_error),
+ expected_error,
+ actual_error ? thd->net.last_error: "no error",
+ actual_error,
+ print_slave_db_safe(db), query_arg);
thd->query_error= 1;
}
/*
@@ -1769,11 +1813,11 @@ Default database: '%s'. Query: '%s'",
*/
else if (thd->query_error || thd->is_fatal_error)
{
- slave_print_error(rli,actual_error,
- "Error '%s' on query. Default database: '%s'. Query: '%s'",
- (actual_error ? thd->net.last_error :
- "unexpected success or fatal error"),
- print_slave_db_safe(thd->db), query_arg);
+ slave_print_msg(ERROR_LEVEL, rli, actual_error,
+ "Error '%s' on query. Default database: '%s'. Query: '%s'",
+ (actual_error ? thd->net.last_error :
+ "unexpected success or fatal error"),
+ print_slave_db_safe(thd->db), query_arg);
thd->query_error= 1;
}
@@ -2055,6 +2099,25 @@ Format_description_log_event(uint8 binlog_ver, const char* server_ver)
post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
+ post_header_len[TABLE_MAP_EVENT-1]= TABLE_MAP_HEADER_LEN;
+ post_header_len[WRITE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
+ post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
+ post_header_len[DELETE_ROWS_EVENT-1]= ROWS_HEADER_LEN;
+ /*
+ We here have the possibility to simulate a master of before we changed
+ the table map id to be stored in 6 bytes: when it was stored in 4
+ bytes (=> post_header_len was 6). This is used to test backward
+ compatibility.
+ This code can be removed after a few months (today is Dec 21st 2005),
+ when we know that the 4-byte masters are not deployed anymore (check
+ with Tomas Ulin first!), and the accompanying test (rpl_row_4_bytes)
+ too.
+ */
+ DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
+ post_header_len[TABLE_MAP_EVENT-1]=
+ post_header_len[WRITE_ROWS_EVENT-1]=
+ post_header_len[UPDATE_ROWS_EVENT-1]=
+ post_header_len[DELETE_ROWS_EVENT-1]= 6;);
post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= post_header_len[APPEND_BLOCK_EVENT-1];
post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
}
@@ -2189,10 +2252,8 @@ int Format_description_log_event::exec_event(struct st_relay_log_info* rli)
As a transaction NEVER spans on 2 or more binlogs:
if we have an active transaction at this point, the master died
while writing the transaction to the binary log, i.e. while
- flushing the binlog cache to the binlog. As the write was started,
- the transaction had been committed on the master, so we lack of
- information to replay this transaction on the slave; all we can do
- is stop with error.
+ flushing the binlog cache to the binlog. XA guarantees that master has
+ rolled back. So we roll back.
Note: this event could be sent by the master to inform us of the
format of its binlog; in other words maybe it is not at its
original place when it comes to us; we'll know this by checking
@@ -2200,11 +2261,13 @@ int Format_description_log_event::exec_event(struct st_relay_log_info* rli)
*/
if (!artificial_event && created && thd->transaction.all.nht)
{
- slave_print_error(rli, 0, "Rolling back unfinished transaction (no "
- "COMMIT or ROLLBACK) from relay log. A probable cause "
- "is that the master died while writing the transaction "
- "to its binary log.");
- end_trans(thd, ROLLBACK);
+ /* This is not an error (XA is safe), just an information */
+ slave_print_msg(INFORMATION_LEVEL, rli, 0,
+ "Rolling back unfinished transaction (no COMMIT "
+ "or ROLLBACK in relay log). A probable cause is that "
+ "the master died while writing the transaction to "
+ "its binary log, thus rolled back too.");
+ rli->cleanup_context(thd, 1);
}
#endif
/*
@@ -2751,6 +2814,9 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli,
thd->query_length= 0; // Should not be needed
thd->query_error= 0;
clear_all_errors(thd, rli);
+
+ /* see Query_log_event::exec_event() and BUG#13360 */
+ DBUG_ASSERT(!rli->m_table_map.count());
/*
Usually mysql_init_query() is called by mysql_parse(), but we need it here
as the present method does not call mysql_parse().
@@ -2962,9 +3028,9 @@ error:
sql_errno=ER_UNKNOWN_ERROR;
err=ER(sql_errno);
}
- slave_print_error(rli,sql_errno,"\
+ slave_print_msg(ERROR_LEVEL, rli, sql_errno,"\
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
- err, (char*)table_name, print_slave_db_safe(save_db));
+ err, (char*)table_name, print_slave_db_safe(save_db));
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
return 1;
}
@@ -2972,9 +3038,9 @@ Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
if (thd->is_fatal_error)
{
- slave_print_error(rli,ER_UNKNOWN_ERROR, "\
+ slave_print_msg(ERROR_LEVEL, rli, ER_UNKNOWN_ERROR, "\
Fatal error running LOAD DATA INFILE on table '%s'. Default database: '%s'",
- (char*)table_name, print_slave_db_safe(save_db));
+ (char*)table_name, print_slave_db_safe(save_db));
return 1;
}
@@ -3035,8 +3101,7 @@ void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
#ifndef MYSQL_CLIENT
-Rotate_log_event::Rotate_log_event(THD* thd_arg,
- const char* new_log_ident_arg,
+Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
uint ident_len_arg, ulonglong pos_arg,
uint flags_arg)
:Log_event(), new_log_ident(new_log_ident_arg),
@@ -3045,7 +3110,7 @@ Rotate_log_event::Rotate_log_event(THD* thd_arg,
{
#ifndef DBUG_OFF
char buff[22];
- DBUG_ENTER("Rotate_log_event::Rotate_log_event(THD*,...)");
+ DBUG_ENTER("Rotate_log_event::Rotate_log_event(...,flags)");
DBUG_PRINT("enter",("new_log_ident %s pos %s flags %lu", new_log_ident_arg,
llstr(pos_arg, buff), flags));
#endif
@@ -3353,12 +3418,24 @@ int Rand_log_event::exec_event(struct st_relay_log_info* rli)
Xid_log_event methods
**************************************************************************/
+#if !defined(DBUG_OFF) && !defined(MYSQL_CLIENT)
+/*
+ This static class member could be removed when mysqltest is made to support
+ a --replace-regex command: then tests which have XIDs in their output can
+ use this command to suppress non-deterministic XID values.
+*/
+my_bool Xid_log_event::show_xid;
+#endif
+
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
void Xid_log_event::pack_info(Protocol *protocol)
{
char buf[128], *pos;
pos= strmov(buf, "COMMIT /* xid=");
- pos= longlong10_to_str(xid, pos, 10);
+#if !defined(DBUG_OFF) && !defined(MYSQL_CLIENT)
+ if (show_xid)
+#endif
+ pos= longlong10_to_str(xid, pos, 10);
pos= strmov(pos, " */");
protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
}
@@ -4179,7 +4256,8 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
MYF(MY_WME|MY_NABP)))
{
- slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf);
+ slave_print_msg(ERROR_LEVEL, rli, my_errno, "Error in Create_file event: "
+ "could not open file '%s'", fname_buf);
goto err;
}
@@ -4190,9 +4268,9 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
if (write_base(&file))
{
strmov(p, ".info"); // to have it right in the error message
- slave_print_error(rli,my_errno,
- "Error in Create_file event: could not write to file '%s'",
- fname_buf);
+ slave_print_msg(ERROR_LEVEL, rli, my_errno,
+ "Error in Create_file event: could not write to file '%s'",
+ fname_buf);
goto err;
}
end_io_cache(&file);
@@ -4204,12 +4282,14 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
MYF(MY_WME))) < 0)
{
- slave_print_error(rli,my_errno, "Error in Create_file event: could not open file '%s'", fname_buf);
+ slave_print_msg(ERROR_LEVEL, rli, my_errno, "Error in Create_file event: "
+ "could not open file '%s'", fname_buf);
goto err;
}
if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP)))
{
- slave_print_error(rli,my_errno, "Error in Create_file event: write to '%s' failed", fname_buf);
+ slave_print_msg(ERROR_LEVEL, rli, my_errno, "Error in Create_file event: "
+ "write to '%s' failed", fname_buf);
goto err;
}
error=0; // Everything is ok
@@ -4348,25 +4428,25 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
MYF(MY_WME))) < 0)
{
- slave_print_error(rli, my_errno,
- "Error in %s event: could not create file '%s'",
- get_type_str(), fname);
+ slave_print_msg(ERROR_LEVEL, rli, my_errno,
+ "Error in %s event: could not create file '%s'",
+ get_type_str(), fname);
goto err;
}
}
else if ((fd = my_open(fname, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
MYF(MY_WME))) < 0)
{
- slave_print_error(rli, my_errno,
- "Error in %s event: could not open file '%s'",
- get_type_str(), fname);
+ slave_print_msg(ERROR_LEVEL, rli, my_errno,
+ "Error in %s event: could not open file '%s'",
+ get_type_str(), fname);
goto err;
}
if (my_write(fd, (byte*) block, block_len, MYF(MY_WME+MY_NABP)))
{
- slave_print_error(rli, my_errno,
- "Error in %s event: write to '%s' failed",
- get_type_str(), fname);
+ slave_print_msg(ERROR_LEVEL, rli, my_errno,
+ "Error in %s event: write to '%s' failed",
+ get_type_str(), fname);
goto err;
}
error=0;
@@ -4573,7 +4653,8 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
MYF(MY_WME|MY_NABP)))
{
- slave_print_error(rli,my_errno, "Error in Exec_load event: could not open file '%s'", fname);
+ slave_print_msg(ERROR_LEVEL, rli, my_errno, "Error in Exec_load event: "
+ "could not open file '%s'", fname);
goto err;
}
if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,
@@ -4581,7 +4662,8 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
rli->relay_log.description_event_for_exec)) ||
lev->get_type_code() != NEW_LOAD_EVENT)
{
- slave_print_error(rli,0, "Error in Exec_load event: file '%s' appears corrupted", fname);
+ slave_print_msg(ERROR_LEVEL, rli, 0, "Error in Exec_load event: "
+ "file '%s' appears corrupted", fname);
goto err;
}
@@ -4607,10 +4689,10 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli)
char *tmp= my_strdup(rli->last_slave_error,MYF(MY_WME));
if (tmp)
{
- slave_print_error(rli,
- rli->last_slave_errno, /* ok to re-use error code */
- "%s. Failed executing load from '%s'",
- tmp, fname);
+ slave_print_msg(ERROR_LEVEL, rli,
+ rli->last_slave_errno, /* ok to re-use error code */
+ "%s. Failed executing load from '%s'",
+ tmp, fname);
my_free(tmp,MYF(0));
}
goto err;
@@ -4816,7 +4898,7 @@ Execute_load_query_log_event::exec_event(struct st_relay_log_info* rli)
if (!(buf = my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
(FN_REFLEN + 10) + 10 + 8 + 5, MYF(MY_WME))))
{
- slave_print_error(rli, my_errno, "Not enough memory");
+ slave_print_msg(ERROR_LEVEL, rli, my_errno, "Not enough memory");
return 1;
}
@@ -4942,3 +5024,1727 @@ char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format)
}
return buf;
}
+
+
+#ifdef HAVE_ROW_BASED_REPLICATION
+
+/**************************************************************************
+ Rows_log_event member functions
+**************************************************************************/
+
+#ifndef MYSQL_CLIENT
+Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
+ MY_BITMAP const *cols, bool is_transactional)
+ : Log_event(thd_arg, 0, is_transactional),
+ m_table(tbl_arg),
+ m_table_id(tid),
+ m_width(tbl_arg->s->fields),
+ m_rows_buf(my_malloc(opt_binlog_rows_event_max_size * sizeof(*m_rows_buf), MYF(MY_WME))),
+ m_rows_cur(m_rows_buf),
+ m_rows_end(m_rows_buf + opt_binlog_rows_event_max_size),
+ m_flags(0)
+{
+ DBUG_ASSERT(m_table && m_table->s);
+ DBUG_ASSERT(m_table_id != ULONG_MAX);
+
+ if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
+ set_flags(NO_FOREIGN_KEY_CHECKS_F);
+ if (thd_arg->options & OPTION_RELAXED_UNIQUE_CHECKS)
+ set_flags(RELAXED_UNIQUE_CHECKS_F);
+ /* if bitmap_init fails, catched in is_valid() */
+ if (likely(!bitmap_init(&m_cols,
+ m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
+ (m_width + 7) & ~7UL,
+ false)))
+ memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
+ else
+ m_cols.bitmap= 0; // to not free it
+}
+#endif
+
+Rows_log_event::Rows_log_event(const char *buf, uint event_len,
+ Log_event_type event_type,
+ const Format_description_log_event
+ *description_event)
+ : Log_event(buf, description_event),
+ m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
+{
+ DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
+ uint8 const common_header_len= description_event->common_header_len;
+ uint8 const post_header_len= description_event->post_header_len[event_type-1];
+
+ DBUG_PRINT("enter",("event_len=%ld, common_header_len=%d, "
+ "post_header_len=%d",
+ event_len, common_header_len,
+ post_header_len));
+
+ const char *post_start= buf + common_header_len;
+ post_start+= RW_MAPID_OFFSET;
+ if (post_header_len == 6)
+ {
+ /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
+ m_table_id= uint4korr(post_start);
+ post_start+= 4;
+ }
+ else
+ {
+ m_table_id= uint6korr(post_start);
+ post_start+= RW_FLAGS_OFFSET;
+ }
+
+ DBUG_ASSERT(m_table_id != ULONG_MAX);
+
+ m_flags= uint2korr(post_start);
+
+ byte const *const var_start= buf + common_header_len + post_header_len;
+ byte const *const ptr_width= var_start;
+ byte const *const ptr_after_width= my_vle_decode(&m_width, ptr_width);
+
+ const uint byte_count= (m_width + 7) / 8;
+ const char* const ptr_rows_data= var_start + byte_count + 1;
+
+ my_size_t const data_size= event_len - (ptr_rows_data - buf);
+ DBUG_PRINT("info",("m_table_id=%lu, m_flags=%d, m_width=%u, data_size=%lu",
+ m_table_id, m_flags, m_width, data_size));
+
+ m_rows_buf= my_malloc(data_size, MYF(MY_WME));
+ if (likely((bool)m_rows_buf))
+ {
+ /* if bitmap_init fails, catched in is_valid() */
+ if (likely(!bitmap_init(&m_cols,
+ m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
+ (m_width + 7) & ~7UL,
+ false)))
+ memcpy(m_cols.bitmap, ptr_after_width, byte_count);
+ m_rows_end= m_rows_buf + data_size;
+ m_rows_cur= m_rows_end;
+ memcpy(m_rows_buf, ptr_rows_data, data_size);
+ }
+ else
+ m_cols.bitmap= 0; // to not free it
+
+ DBUG_VOID_RETURN;
+}
+
+Rows_log_event::~Rows_log_event()
+{
+ if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
+ m_cols.bitmap= 0; // so no my_free in bitmap_free
+ bitmap_free(&m_cols); // To pair with bitmap_init().
+ my_free(m_rows_buf, MYF(MY_ALLOW_ZERO_PTR));
+}
+
+#ifndef MYSQL_CLIENT
+int Rows_log_event::do_add_row_data(byte *const row_data,
+ my_size_t const length)
+{
+ /*
+ When the table has a primary key, we would probably want, by default, to
+ log only the primary key value instead of the entire "before image". This
+ would save binlog space. TODO
+ */
+ DBUG_ENTER("Rows_log_event::do_add_row_data(byte *data, my_size_t length)");
+ DBUG_PRINT("enter", ("row_data= %p, length= %lu", row_data, length));
+ DBUG_DUMP("row_data", row_data, min(length, 32));
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+ DBUG_ASSERT(m_rows_buf < m_rows_end);
+ DBUG_ASSERT(m_rows_cur <= m_rows_end);
+
+ /* The cast will always work since m_rows_cur <= m_rows_end */
+ if (static_cast<my_size_t>(m_rows_end - m_rows_cur) < length)
+ {
+ my_size_t const block_size= 1024;
+ my_ptrdiff_t const old_alloc= m_rows_end - m_rows_buf;
+ my_ptrdiff_t const new_alloc=
+ old_alloc + block_size * (length / block_size + block_size - 1);
+ my_ptrdiff_t const cur_size= m_rows_cur - m_rows_buf;
+
+ byte* const new_buf= my_realloc(m_rows_buf, new_alloc, MYF(MY_WME));
+ if (unlikely(!new_buf))
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+
+ /* If the memory moved, we need to move the pointers */
+ if (new_buf != m_rows_buf)
+ {
+ m_rows_buf= new_buf;
+ m_rows_cur= m_rows_buf + cur_size;
+ }
+
+ /*
+ The end pointer should always be changed to point to the end of
+ the allocated memory.
+ */
+ m_rows_end= m_rows_buf + new_alloc;
+ }
+
+ DBUG_ASSERT(m_rows_cur + length < m_rows_end);
+ memcpy(m_rows_cur, row_data, length);
+ m_rows_cur+= length;
+ DBUG_RETURN(0);
+}
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+/*
+ Unpack a row into a record. The row is assumed to only consist of the fields
+ for which the bitset represented by 'arr' and 'bits'; the other parts of the
+ record are left alone.
+ */
+static char const *unpack_row(TABLE *table,
+ char *record, char const *row,
+ MY_BITMAP const *cols)
+{
+ DBUG_ASSERT(record && row);
+
+ MY_BITMAP *write_set= table->file->write_set;
+ my_size_t const n_null_bytes= table->s->null_bytes;
+ my_ptrdiff_t const offset= record - (byte*) table->record[0];
+
+ memcpy(record, row, n_null_bytes);
+ char const *ptr= row + n_null_bytes;
+
+ bitmap_set_all(write_set);
+ Field **const begin_ptr = table->field;
+ for (Field **field_ptr= begin_ptr ; *field_ptr ; ++field_ptr)
+ {
+ Field *const f= *field_ptr;
+
+ if (bitmap_is_set(cols, field_ptr - begin_ptr))
+ {
+ /* Field...::unpack() cannot return 0 */
+ ptr= f->unpack(f->ptr + offset, ptr);
+ }
+ else
+ bitmap_clear_bit(write_set, (field_ptr - begin_ptr) + 1);
+ }
+ return ptr;
+}
+
+int Rows_log_event::exec_event(st_relay_log_info *rli)
+{
+ DBUG_ENTER("Rows_log_event::exec_event(st_relay_log_info*)");
+ DBUG_ASSERT(m_table_id != ULONG_MAX);
+ int error= 0;
+ char const *row_start= m_rows_buf;
+ TABLE* table= rli->m_table_map.get_table(m_table_id);
+
+ /*
+ 'thd' has been set by exec_relay_log_event(), just before calling
+ exec_event(). We still check here to prevent future coding errors.
+ */
+ DBUG_ASSERT(rli->sql_thd == thd);
+
+ /*
+ lock_tables() reads the contents of thd->lex, so they must be
+ initialized, so we should call lex_start(); to be even safer, we call
+ mysql_init_query() which does a more complete set of inits.
+ */
+ mysql_init_query(thd, NULL, 0);
+
+ if (table)
+ {
+ /*
+ table == NULL means that this table should not be
+ replicated (this was set up by Table_map_log_event::exec_event() which
+ tested replicate-* rules).
+ */
+ TABLE_LIST table_list;
+ bool need_reopen;
+ uint count= 1;
+ bzero(&table_list, sizeof(table_list));
+ table_list.lock_type= TL_WRITE;
+ table_list.next_global= table_list.next_local= 0;
+ table_list.table= table;
+
+ for ( ; ; )
+ {
+ table_list.db= const_cast<char*>(table->s->db.str);
+ table_list.alias= table_list.table_name=
+ const_cast<char*>(table->s->table_name.str);
+
+ if ((error= lock_tables(thd, &table_list, count, &need_reopen)) == 0)
+ break;
+ if (!need_reopen)
+ {
+ slave_print_msg(ERROR_LEVEL, rli, error,
+ "Error in %s event: error during table %s.%s lock",
+ get_type_str(), table->s->db, table->s->table_name);
+ DBUG_RETURN(error);
+ }
+ /*
+ we need to store a local copy of the table names since the table object
+ will become invalid after close_tables_for_reopen
+ */
+ char *db= my_strdup(table->s->db.str, MYF(MY_WME));
+ char *table_name= my_strdup(table->s->table_name.str, MYF(MY_WME));
+
+ if (db == 0 || table_name == 0)
+ {
+ /*
+ Since the lock_tables() failed, the table is not locked, so
+ we don't need to unlock them.
+ */
+ DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+ }
+
+ /*
+ We also needs to flush the pending RBR event, since it keeps a
+ pointer to an open table.
+
+ ALTERNATIVE SOLUTION: Extract a pointer to the pending RBR
+ event and reset the table pointer after the tables has been
+ reopened.
+ */
+ thd->binlog_flush_pending_rows_event(false);
+
+ close_tables_for_reopen(thd, &table_list);
+
+ /* open the table again, same as in Table_map_event::exec_event */
+ table_list.db= const_cast<char*>(db);
+ table_list.alias= table_list.table_name= const_cast<char*>(table_name);
+ table_list.updating= 1;
+ TABLE_LIST *tables= &table_list;
+ if ((error= open_tables(thd, &tables, &count, 0)) == 0)
+ {
+ /* reset some variables for the table list*/
+ table_list.updating= 0;
+ /* retrieve the new table reference and update the table map */
+ table= table_list.table;
+ error= rli->m_table_map.set_table(m_table_id, table);
+ }
+ else /* error in open_tables */
+ {
+ if (thd->query_error || thd->is_fatal_error)
+ {
+ /*
+ Error reporting borrowed from Query_log_event with many excessive
+ simplifications (we don't honour --slave-skip-errors)
+ */
+ uint actual_error= thd->net.last_errno;
+ slave_print_msg(ERROR_LEVEL, rli, actual_error,
+ "Error '%s' on reopening table `%s`.`%s`",
+ (actual_error ? thd->net.last_error :
+ "unexpected success or fatal error"),
+ db, table_name);
+ thd->query_error= 1;
+ }
+ }
+ my_free((char*) db, MYF(MY_ALLOW_ZERO_PTR));
+ my_free((char*) table_name, MYF(MY_ALLOW_ZERO_PTR));
+
+ if (error)
+ DBUG_RETURN(error);
+ }
+
+ /*
+ It's not needed to set_time() but
+ 1) it continues the property that "Time" in SHOW PROCESSLIST shows how
+ much slave is behind
+ 2) it will be needed when we allow replication from a table with no
+ TIMESTAMP column to a table with one.
+ So we call set_time(), like in SBR. Presently it changes nothing.
+ */
+ thd->set_time((time_t)when);
+ /*
+ There are a few flags that are replicated with each row event.
+ Make sure to set/clear them before executing the main body of
+ the event.
+ */
+ if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
+ thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
+ else
+ thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
+
+ if (get_flags(RELAXED_UNIQUE_CHECKS_F))
+ thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
+ else
+ thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
+ /* A small test to verify that objects have consistent types */
+ DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
+
+ error= do_before_row_operations(table);
+ while (error == 0 && row_start < m_rows_end) {
+ char const *row_end= do_prepare_row(thd, table, row_start);
+ DBUG_ASSERT(row_end != NULL); // cannot happen
+ DBUG_ASSERT(row_end <= m_rows_end);
+
+ /* in_use can have been set to NULL in close_tables_for_reopen */
+ THD* old_thd= table->in_use;
+ if (!table->in_use)
+ table->in_use= thd;
+ error= do_exec_row(table);
+ table->in_use = old_thd;
+ switch (error)
+ {
+ /* Some recoverable errors */
+ case HA_ERR_RECORD_CHANGED:
+ case HA_ERR_KEY_NOT_FOUND: /* Idempotency support: OK if
+ tuple does not exist */
+ error= 0;
+ case 0:
+ break;
+
+ default:
+ slave_print_msg(ERROR_LEVEL, rli, error,
+ "Error in %s event: row application failed",
+ get_type_str());
+ thd->query_error= 1;
+ break;
+ }
+
+ row_start= row_end;
+ }
+ DBUG_EXECUTE_IF("STOP_SLAVE_after_first_Rows_event",
+ rli->abort_slave=1;);
+ error= do_after_row_operations(table, error);
+ if (!cache_stmt)
+ thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
+
+ }
+
+ if (error)
+ { /* error has occured during the transaction */
+ /*
+ If one day we honour --skip-slave-errors in row-based replication, and
+ the error should be skipped, then we would clear mappings, rollback,
+ close tables, but the slave SQL thread would not stop and then may
+ assume the mapping is still available, the tables are still open...
+ So then we should clear mappings/rollback/close here only if this is a
+ STMT_END_F.
+ For now we code, knowing that error is not skippable and so slave SQL
+ thread is certainly going to stop.
+ */
+ rli->cleanup_context(thd, 1);
+ thd->query_error= 1;
+ DBUG_RETURN(error);
+ }
+
+ if (get_flags(STMT_END_F))
+ {
+ /*
+ This is the end of a statement or transaction, so close (and
+ unlock) the tables we opened when processing the
+ Table_map_log_event starting the statement.
+
+ OBSERVER. This will clear *all* mappings, not only those that
+ are open for the table. There is not good handle for on-close
+ actions for tables.
+
+ NOTE. Even if we have no table ('table' == 0) we still need to be
+ here, so that we increase the group relay log position. If we didn't, we
+ could have a group relay log position which lags behind "forever"
+ (assume the last master's transaction is ignored by the slave because of
+ replicate-ignore rules).
+ */
+ thd->binlog_flush_pending_rows_event(true);
+ /*
+ If this event is not in a transaction, the call below will, if some
+ transactional storage engines are involved, commit the statement into
+ them and flush the pending event to binlog.
+ If this event is in a transaction, the call will do nothing, but a
+ Xid_log_event will come next which will, if some transactional engines
+ are involved, commit the transaction and flush the pending event to the
+ binlog.
+ */
+ error= ha_autocommit_or_rollback(thd, 0);
+ /*
+ Now what if this is not a transactional engine? we still need to
+ flush the pending event to the binlog; we did it with
+ thd->binlog_flush_pending_rows_event(). Note that we imitate
+ what is done for real queries: a call to
+ ha_autocommit_or_rollback() (sometimes only if involves a
+ transactional engine), and a call to be sure to have the pending
+ event flushed.
+ */
+
+ rli->cleanup_context(thd, 0);
+ rli->transaction_end(thd);
+
+ if (error == 0)
+ {
+ /*
+ Clear any errors pushed in thd->net.last_err* if for example "no key
+ found" (as this is allowed). This is a safety measure; apparently
+ those errors (e.g. when executing a Delete_rows_log_event of a
+ non-existing row, like in rpl_row_mystery22.test,
+ thd->net.last_error = "Can't find record in 't1'" and last_errno=1032)
+ do not become visible. We still prefer to wipe them out.
+ */
+ thd->clear_error();
+ error= Log_event::exec_event(rli);
+ }
+ else
+ slave_print_msg(ERROR_LEVEL, rli, error,
+ "Error in %s event: commit of row events failed, "
+ "table `%s`.`%s`",
+ get_type_str(), table->s->db, table->s->table_name);
+ DBUG_RETURN(error);
+ }
+
+ if (table)
+ {
+ /*
+ As "table" is not NULL, we did a successful lock_tables(), without any
+ prior LOCK TABLES and are not in prelocked mode, so this assertion should
+ be true.
+ */
+ DBUG_ASSERT(thd->lock);
+ /*
+ If we are here, there are more events to come which may use our mappings
+ and our table. So don't clear mappings or close tables, just unlock
+ tables.
+ Why don't we lock the table once for all in
+ Table_map_log_event::exec_event() ? Because we could have in binlog:
+ BEGIN;
+ Table_map t1 -> 1
+ Write_rows to id 1
+ Table_map t2 -> 2
+ Write_rows to id 2
+ Xid_log_event
+ So we cannot lock t1 when executing the first Table_map, because at that
+ moment we don't know we'll also have to lock t2, and all tables must be
+ locked at once in MySQL.
+ */
+ mysql_unlock_tables(thd, thd->lock);
+ thd->lock= 0;
+ if ((table->s->primary_key == MAX_KEY) &&
+ !cache_stmt)
+ {
+ /*
+ ------------ Temporary fix until WL#2975 is implemented ---------
+ This event is not the last one (no STMT_END_F). If we stop now (in
+ case of terminate_slave_thread()), how will we restart? We have to
+ restart from Table_map_log_event, but as this table is not
+ transactional, the rows already inserted will still be present, and
+ idempotency is not guaranteed (no PK) so we risk that repeating leads
+ to double insert. So we desperately try to continue, hope we'll
+ eventually leave this buggy situation (by executing the final
+ Rows_log_event). If we are in a hopeless wait (reached end of last
+ relay log and nothing gets appended there), we timeout after one
+ minute, and notify DBA about the problem.
+ When WL#2975 is implemented, just remove the member
+ st_relay_log_info::unsafe_to_stop_at and all its occurences.
+ */
+ rli->unsafe_to_stop_at= time(0);
+ }
+ }
+
+ DBUG_ASSERT(error == 0);
+ thd->clear_error();
+ rli->inc_event_relay_log_pos();
+
+ DBUG_RETURN(0);
+}
+#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
+
+#ifndef MYSQL_CLIENT
+bool Rows_log_event::write_data_header(IO_CACHE *file)
+{
+ DBUG_ASSERT(m_table_id != ULONG_MAX);
+ byte buf[ROWS_HEADER_LEN]; // No need to init the buffer
+ DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
+ {
+ int4store(buf + 0, m_table_id);
+ int2store(buf + 4, m_flags);
+ return (my_b_safe_write(file, buf, 6));
+ });
+ int6store(buf + RW_MAPID_OFFSET, (ulonglong)m_table_id);
+ int2store(buf + RW_FLAGS_OFFSET, m_flags);
+ return (my_b_safe_write(file, buf, ROWS_HEADER_LEN));
+}
+
+bool Rows_log_event::write_data_body(IO_CACHE*file)
+{
+ /*
+ Note that this should be the number of *bits*, not the number of
+ bytes.
+ */
+ byte sbuf[my_vle_sizeof(m_width)];
+ my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
+
+ char *const sbuf_end= my_vle_encode(sbuf, sizeof(sbuf), m_width);
+ DBUG_ASSERT(static_cast<my_size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
+
+ return (my_b_safe_write(file, sbuf, sbuf_end - sbuf) ||
+ my_b_safe_write(file, reinterpret_cast<byte*>(m_cols.bitmap),
+ no_bytes_in_map(&m_cols)) ||
+ my_b_safe_write(file, m_rows_buf, data_size));
+}
+#endif
+
+#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) && defined(DBUG_RBR)
+void Rows_log_event::pack_info(Protocol *protocol)
+{
+ char buf[256];
+ char const *const flagstr= get_flags(STMT_END_F) ? "STMT_END_F" : "";
+ char const *const dbnam= m_table->s->db;
+ char const *const tblnam= m_table->s->table_name;
+ my_size_t bytes= snprintf(buf, sizeof(buf),
+ "%s.%s - %s", dbnam, tblnam, flagstr);
+ protocol->store(buf, bytes, &my_charset_bin);
+}
+#endif
+
+/**************************************************************************
+ Table_map_log_event member functions
+**************************************************************************/
+
+/*
+ Constructor used to build an event for writing to the binary log.
+ Mats says tbl->s lives longer than this event so it's ok to copy pointers
+ (tbl->s->db etc) and not pointer content.
+ */
+#if !defined(MYSQL_CLIENT)
+Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
+ bool is_transactional, uint16 flags)
+ : Log_event(thd, 0, is_transactional),
+ m_table(tbl),
+ m_dbnam(tbl->s->db.str),
+ m_dblen(m_dbnam ? tbl->s->db.length : 0),
+ m_tblnam(tbl->s->table_name.str),
+ m_tbllen(tbl->s->table_name.length),
+ m_colcnt(tbl->s->fields), m_coltype(0),
+ m_table_id(tid),
+ m_flags(flags)
+{
+ DBUG_ASSERT(m_table_id != ULONG_MAX);
+ /*
+ In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
+ table.cc / alloc_table_share():
+ Use the fact the key is db/0/table_name/0
+ As we rely on this let's assert it.
+ */
+ DBUG_ASSERT((tbl->s->db.str == 0) ||
+ (tbl->s->db.str[tbl->s->db.length] == 0));
+ DBUG_ASSERT(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
+
+
+ m_data_size= TABLE_MAP_HEADER_LEN;
+ DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;)
+ m_data_size+= m_dblen + 2; // Include length and terminating \0
+ m_data_size+= m_tbllen + 2; // Include length and terminating \0
+ m_data_size+= 1 + m_colcnt; // COLCNT and column types
+
+ /* If malloc fails, catched in is_valid() */
+ if ((m_memory= my_malloc(m_colcnt, MYF(MY_WME))))
+ {
+ m_coltype= reinterpret_cast<unsigned char*>(m_memory);
+ for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
+ m_coltype[i]= m_table->field[i]->type();
+ }
+}
+#endif /* !defined(MYSQL_CLIENT) */
+
+/*
+ Constructor used by slave to read the event from the binary log.
+ */
+#if defined(HAVE_REPLICATION)
+Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
+ const Format_description_log_event
+ *description_event)
+
+ : Log_event(buf, description_event),
+#ifndef MYSQL_CLIENT
+ m_table(NULL),
+#endif
+ m_memory(NULL)
+{
+ DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
+
+ uint8 common_header_len= description_event->common_header_len;
+ uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
+ DBUG_PRINT("info",("event_len=%ld, common_header_len=%d, post_header_len=%d",
+ event_len, common_header_len, post_header_len));
+
+ DBUG_DUMP("event buffer", buf, event_len);
+
+ /* Read the post-header */
+ const char *post_start= buf + common_header_len;
+
+ post_start+= TM_MAPID_OFFSET;
+ if (post_header_len == 6)
+ {
+ /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
+ m_table_id= uint4korr(post_start);
+ post_start+= 4;
+ }
+ else
+ {
+ DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN);
+ m_table_id= uint6korr(post_start);
+ post_start+= TM_FLAGS_OFFSET;
+ }
+
+ DBUG_ASSERT(m_table_id != ULONG_MAX);
+
+ m_flags= uint2korr(post_start);
+
+ /* Read the variable part of the event */
+ const char *const vpart= buf + common_header_len + post_header_len;
+
+ /* Extract the length of the various parts from the buffer */
+ byte const* const ptr_dblen= vpart + 0;
+ m_dblen= *(unsigned char*) ptr_dblen;
+
+ /* Length of database name + counter + terminating null */
+ byte const* const ptr_tbllen= ptr_dblen + m_dblen + 2;
+ m_tbllen= *(unsigned char*) ptr_tbllen;
+
+ /* Length of table name + counter + terminating null */
+ byte const* const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
+ byte const* const ptr_after_colcnt= my_vle_decode(&m_colcnt, ptr_colcnt);
+
+ DBUG_PRINT("info",("m_dblen=%d off=%d m_tbllen=%d off=%d m_colcnt=%d off=%d",
+ m_dblen, ptr_dblen-vpart, m_tbllen, ptr_tbllen-vpart,
+ m_colcnt, ptr_colcnt-vpart));
+
+ /* Allocate mem for all fields in one go. If fails, catched in is_valid() */
+ m_memory= my_multi_malloc(MYF(MY_WME),
+ &m_dbnam, m_dblen + 1,
+ &m_tblnam, m_tbllen + 1,
+ &m_coltype, m_colcnt,
+ NULL);
+
+ if (m_memory)
+ {
+ /* Copy the different parts into their memory */
+ strncpy(const_cast<char*>(m_dbnam), ptr_dblen + 1, m_dblen + 1);
+ strncpy(const_cast<char*>(m_tblnam), ptr_tbllen + 1, m_tbllen + 1);
+ memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
+ }
+
+ DBUG_VOID_RETURN;
+}
+#endif
+
+Table_map_log_event::~Table_map_log_event()
+{
+ my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
+}
+
+/*
+ Find a table based on database name and table name.
+
+ DESCRIPTION
+
+ Currently, only the first table of the 'table_list' is located. If the
+ table is found in the list of open tables for the thread, the 'table'
+ field of 'table_list' is filled in.
+
+ PARAMETERS
+
+ thd Thread structure
+ table_list List of tables to locate in the thd->open_tables list.
+ count Pointer to a variable that will be set to the number of
+ tables found. If the pointer is NULL, nothing will be stored.
+
+ RETURN VALUE
+
+ The number of tables found.
+
+ TO DO
+
+ Replace the list of table searches with a hash based on the combined
+ database and table name. The handler_tables_hash is inappropriate since
+ it hashes on the table alias. At the same time, the function can be
+ extended to handle a full list of table names, in the same spirit as
+ open_tables() and lock_tables().
+*/
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+static uint find_tables(THD *thd, TABLE_LIST *table_list, uint *count)
+{
+ uint result= 0;
+
+ /* we verify that the caller knows our limitation */
+ DBUG_ASSERT(table_list->next_global == 0);
+ for (TABLE *table= thd->open_tables; table ; table= table->next)
+ {
+ if (strcmp(table->s->db.str, table_list->db) == 0
+ && strcmp(table->s->table_name.str, table_list->table_name) == 0)
+ {
+ /* Copy the table pointer into the table list. */
+ table_list->table= table;
+ result= 1;
+ break;
+ }
+ }
+
+ if (count)
+ *count= result;
+ return result;
+}
+#endif
+
+/*
+ Return value is an error code, one of:
+
+ -1 Failure to open table [from open_tables()]
+ 0 Success
+ 1 No room for more tables [from set_table()]
+ 2 Out of memory [from set_table()]
+ 3 Wrong table definition
+ 4 Daisy-chaining RBR with SBR not possible
+ */
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+int Table_map_log_event::exec_event(st_relay_log_info *rli)
+{
+ DBUG_ENTER("Table_map_log_event::exec_event(st_relay_log_info*)");
+
+ DBUG_ASSERT(rli->sql_thd == thd);
+
+ /* Step the query id to mark what columns that are actually used. */
+ pthread_mutex_lock(&LOCK_thread_count);
+ thd->query_id= next_query_id();
+ pthread_mutex_unlock(&LOCK_thread_count);
+
+ TABLE_LIST table_list;
+ uint32 dummy_len;
+ bzero(&table_list, sizeof(table_list));
+ table_list.db= const_cast<char *>
+ (rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
+ table_list.alias= table_list.table_name= const_cast<char*>(m_tblnam);
+ table_list.lock_type= TL_WRITE;
+ table_list.next_global= table_list.next_local= 0;
+ table_list.updating= 1;
+
+ int error= 0;
+
+ if (rpl_filter->db_ok(table_list.db) &&
+ (!rpl_filter->is_on() || rpl_filter->tables_ok("", &table_list)))
+ {
+ /*
+ Check if the slave is set to use SBR. If so, the slave should
+ stop immediately since it is not possible to daisy-chain from
+ RBR to SBR. Once RBR is used, the rest of the chain has to use
+ RBR.
+ */
+ if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG) &&
+ !binlog_row_based)
+ {
+ slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_RBR_TO_SBR,
+ "It is not possible to use statement-based binlogging "
+ "on a slave that replicates row-based. Please use "
+ "--binrow-format=row on slave if you want to use "
+ "--log-slave-updates and read row-based binlog events.");
+ DBUG_RETURN(ERR_RBR_TO_SBR);
+ }
+
+ /*
+ Open the table if it is not already open and add the table to table map.
+ If the table should not be replicated, we don't bother to do anything.
+ The table map will return NULL and the row-level event will effectively
+ be a no-op.
+ */
+ uint count;
+ if (find_tables(thd, &table_list, &count) == 0)
+ {
+ /*
+ open_tables() reads the contents of thd->lex, so they must be
+ initialized, so we should call lex_start(); to be even safer, we call
+ mysql_init_query() which does a more complete set of inits.
+ */
+ mysql_init_query(thd, NULL, 0);
+ TABLE_LIST *tables= &table_list;
+ if ((error= open_tables(thd, &tables, &count, 0)))
+ {
+ if (thd->query_error || thd->is_fatal_error)
+ {
+ /*
+ Error reporting borrowed from Query_log_event with many excessive
+ simplifications (we don't honour --slave-skip-errors)
+ */
+ uint actual_error= thd->net.last_errno;
+ slave_print_msg(ERROR_LEVEL, rli, actual_error,
+ "Error '%s' on opening table `%s`.`%s`",
+ (actual_error ? thd->net.last_error :
+ "unexpected success or fatal error"),
+ table_list.db, table_list.table_name);
+ thd->query_error= 1;
+ }
+ DBUG_RETURN(error);
+ }
+ }
+
+ m_table= table_list.table;
+
+ /*
+ This will fail later otherwise, the 'in_use' field should be
+ set to the current thread.
+ */
+ DBUG_ASSERT(m_table->in_use);
+
+ /*
+ Check that the number of columns and the field types in the
+ event match the number of columns and field types in the opened
+ table.
+ */
+ uint col= m_table->s->fields;
+
+ if (col == m_colcnt)
+ {
+ while (col-- > 0)
+ if (m_table->field[col]->type() != m_coltype[col])
+ break;
+ }
+
+ TABLE_SHARE const *const tsh= m_table->s;
+
+ /*
+ Check the following termination conditions:
+
+ (col == m_table->s->fields)
+ ==> (m_table->s->fields != m_colcnt)
+ (0 <= col < m_table->s->fields)
+ ==> (m_table->field[col]->type() != m_coltype[col])
+
+ Logically, A ==> B is equivalent to !A || B
+
+ Since col is unsigned, is suffices to check that col <=
+ tsh->fields. If col wrapped (by decreasing col when it is 0),
+ the number will be UINT_MAX, which is greater than tsh->fields.
+ */
+ DBUG_ASSERT(!(col == tsh->fields) || tsh->fields != m_colcnt);
+ DBUG_ASSERT(!(col < tsh->fields) ||
+ (m_table->field[col]->type() != m_coltype[col]));
+
+ if (col <= tsh->fields)
+ {
+ /*
+ If we get here, the number of columns in the event didn't
+ match the number of columns in the table on the slave, *or*
+ there were a column in the table on the slave that did not
+ have the same type as given in the event.
+
+ If 'col' has the value that was assigned to it, it was a
+ mismatch between the number of columns on the master and the
+ slave.
+ */
+ if (col == tsh->fields)
+ {
+ DBUG_ASSERT(tsh->db.str && tsh->table_name.str);
+ slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_WRONG_TABLE_DEF,
+ "Table width mismatch - "
+ "received %u columns, %s.%s has %u columns",
+ m_colcnt, tsh->db.str, tsh->table_name.str, tsh->fields);
+ }
+ else
+ {
+ DBUG_ASSERT(col < m_colcnt && col < tsh->fields);
+ DBUG_ASSERT(tsh->db.str && tsh->table_name.str);
+ slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_WRONG_TABLE_DEF,
+ "Column %d type mismatch - "
+ "received type %d, %s.%s has type %d",
+ col, m_coltype[col], tsh->db.str, tsh->table_name.str,
+ m_table->field[col]->type());
+ }
+
+ thd->query_error= 1;
+ DBUG_RETURN(ERR_BAD_TABLE_DEF);
+ }
+
+ /*
+ We record in the slave's information that the number m_table_id is
+ mapped to the m_table object
+ */
+ if (!error)
+ error= rli->m_table_map.set_table(m_table_id, m_table);
+
+ /*
+ Tell the RLI that we are touching a table.
+
+ TODO: Maybe we can combine this with the previous operation?
+ */
+ if (!error)
+ rli->touching_table(m_dbnam, m_tblnam, m_table_id);
+ }
+
+ /*
+ We explicitly do not call Log_event::exec_event() here since we do not
+ want the relay log position to be flushed to disk. The flushing will be
+ done by the last Rows_log_event that either ends a statement (outside a
+ transaction) or a transaction.
+
+ A table map event can *never* end a transaction or a statement, so we
+ just step the relay log position.
+ */
+
+ if (likely(!error))
+ rli->inc_event_relay_log_pos();
+
+ DBUG_RETURN(error);
+}
+#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
+
+#ifndef MYSQL_CLIENT
+bool Table_map_log_event::write_data_header(IO_CACHE *file)
+{
+ DBUG_ASSERT(m_table_id != ULONG_MAX);
+ byte buf[TABLE_MAP_HEADER_LEN];
+ DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
+ {
+ int4store(buf + 0, m_table_id);
+ int2store(buf + 4, m_flags);
+ return (my_b_safe_write(file, buf, 6));
+ });
+ int6store(buf + TM_MAPID_OFFSET, (ulonglong)m_table_id);
+ int2store(buf + TM_FLAGS_OFFSET, m_flags);
+ return (my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
+}
+
+bool Table_map_log_event::write_data_body(IO_CACHE *file)
+{
+ DBUG_ASSERT(m_dbnam != NULL);
+ DBUG_ASSERT(m_tblnam != NULL);
+ /* We use only one byte per length for storage in event: */
+ DBUG_ASSERT(m_dblen < 128);
+ DBUG_ASSERT(m_tbllen < 128);
+
+ byte const dbuf[]= { m_dblen };
+ byte const tbuf[]= { m_tbllen };
+
+ byte cbuf[my_vle_sizeof(m_colcnt)];
+ byte *const cbuf_end= my_vle_encode(cbuf, sizeof(cbuf), m_colcnt);
+ DBUG_ASSERT(static_cast<my_size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
+
+ return (my_b_safe_write(file, dbuf, sizeof(dbuf)) ||
+ my_b_safe_write(file, m_dbnam, m_dblen+1) ||
+ my_b_safe_write(file, tbuf, sizeof(tbuf)) ||
+ my_b_safe_write(file, m_tblnam, m_tbllen+1) ||
+ my_b_safe_write(file, cbuf, cbuf_end - cbuf) ||
+ my_b_safe_write(file, reinterpret_cast<char*>(m_coltype), m_colcnt));
+ }
+#endif
+
+#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+
+/*
+ Print some useful information for the SHOW BINARY LOG information
+ field.
+ */
+
+void Table_map_log_event::pack_info(Protocol *protocol)
+{
+ char buf[256];
+ my_size_t bytes= snprintf(buf, sizeof(buf), "%s.%s", m_dbnam, m_tblnam);
+ protocol->store(buf, bytes, &my_charset_bin);
+}
+
+#endif
+
+
+#ifdef MYSQL_CLIENT
+void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
+{
+ if (!print_event_info->short_form)
+ {
+ print_header(file, print_event_info);
+ fprintf(file, "\tTable_map: `%s`.`%s` mapped to number %lu\n",
+ m_dbnam, m_tblnam, m_table_id);
+ print_base64(file, print_event_info);
+ }
+}
+#endif
+
+/**************************************************************************
+ Write_rows_log_event member functions
+**************************************************************************/
+
+/*
+ Constructor used to build an event for writing to the binary log.
+ */
+#if !defined(MYSQL_CLIENT)
+Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
+ ulong tid_arg,
+ MY_BITMAP const *cols,
+ bool is_transactional)
+ : Rows_log_event(thd_arg, tbl_arg, tid_arg, cols, is_transactional)
+{
+}
+#endif
+
+/*
+ Constructor used by slave to read the event from the binary log.
+ */
+#ifdef HAVE_REPLICATION
+Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
+ const Format_description_log_event
+ *description_event)
+: Rows_log_event(buf, event_len, WRITE_ROWS_EVENT, description_event)
+{
+}
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+int Write_rows_log_event::do_before_row_operations(TABLE *table)
+{
+ int error= 0;
+
+ /*
+ We are using REPLACE semantics and not INSERT IGNORE semantics
+ when writing rows, that is: new rows replace old rows. We need to
+ inform the storage engine that it should use this behaviour.
+ */
+
+ /* Tell the storage engine that we are using REPLACE semantics. */
+ thd->lex->duplicates= DUP_REPLACE;
+
+ /*
+ Pretend we're executing a REPLACE command: this is needed for
+ InnoDB and NDB Cluster since they are not (properly) checking the
+ lex->duplicates flag.
+ */
+ thd->lex->sql_command= SQLCOM_REPLACE;
+
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); // needed for ndbcluster
+ /*
+ TODO: the cluster team (Tomas?) says that it's better if the engine knows
+ how many rows are going to be inserted, then it can allocate needed memory
+ from the start.
+ */
+ table->file->start_bulk_insert(0);
+ /*
+ We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill
+ any TIMESTAMP column with data from the row but instead will use
+ the event's current time.
+ As we replicate from TIMESTAMP to TIMESTAMP and slave has no extra
+ columns, we know that all TIMESTAMP columns on slave will receive explicit
+ data from the row, so TIMESTAMP_NO_AUTO_SET is ok.
+ When we allow a table without TIMESTAMP to be replicated to a table having
+ more columns including a TIMESTAMP column, or when we allow a TIMESTAMP
+ column to be replicated into a BIGINT column and the slave's table has a
+ TIMESTAMP column, then the slave's TIMESTAMP column will take its value
+ from set_time() which we called earlier (consistent with SBR). And then in
+ some cases we won't want TIMESTAMP_NO_AUTO_SET (will require some code to
+ analyze if explicit data is provided for slave's TIMESTAMP columns).
+ */
+ table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
+ return error;
+}
+
+int Write_rows_log_event::do_after_row_operations(TABLE *table, int error)
+{
+ if (error == 0)
+ error= table->file->end_bulk_insert();
+ return error;
+}
+
+char const *Write_rows_log_event::do_prepare_row(THD *thd, TABLE *table,
+ char const *row_start)
+{
+ char const *ptr= row_start;
+ DBUG_ASSERT(table != NULL);
+ /*
+ This assertion actually checks that there is at least as many
+ columns on the slave as on the master.
+ */
+ DBUG_ASSERT(table->s->fields >= m_width);
+ DBUG_ASSERT(ptr);
+ ptr= unpack_row(table, table->record[0], ptr, &m_cols);
+ return ptr;
+}
+
+/*
+ Check if there are more UNIQUE keys after the given key.
+*/
+static int
+last_uniq_key(TABLE *table, uint keyno)
+{
+ while (++keyno < table->s->keys)
+ if (table->key_info[keyno].flags & HA_NOSAME)
+ return 0;
+ return 1;
+}
+
+/* Anonymous namespace for template functions/classes */
+namespace {
+
+ /*
+ Smart pointer that will automatically call my_afree (a macro) when
+ the pointer goes out of scope. This is used so that I do not have
+ to remember to call my_afree() before each return. There is no
+ overhead associated with this, since all functions are inline.
+
+ I (Matz) would prefer to use the free function as a template
+ parameter, but that is not possible when the "function" is a
+ macro.
+ */
+ template <class Obj>
+ class auto_afree_ptr
+ {
+ Obj* m_ptr;
+ public:
+ auto_afree_ptr(Obj* ptr) : m_ptr(ptr) { }
+ ~auto_afree_ptr() { if (m_ptr) my_afree(m_ptr); }
+ void assign(Obj* ptr) {
+ /* Only to be called if it hasn't been given a value before. */
+ DBUG_ASSERT(m_ptr == NULL);
+ m_ptr= ptr;
+ }
+ Obj* get() { return m_ptr; }
+ };
+
+}
+
+
+/*
+ Replace the provided record in the database.
+
+ Similar to how it is done in <code>mysql_insert()</code>, we first
+ try to do a <code>ha_write_row()</code> and of that fails due to
+ duplicated keys (or indices), we do an <code>ha_update_row()</code>
+ or a <code>ha_delete_row()</code> instead.
+
+ @param thd Thread context for writing the record.
+ @param table Table to which record should be written.
+
+ @return Error code on failure, 0 on success.
+ */
+static int
+replace_record(THD *thd, TABLE *table)
+{
+ DBUG_ASSERT(table != NULL && thd != NULL);
+
+ int error;
+ int keynum;
+ auto_afree_ptr<char> key(NULL);
+
+ while ((error= table->file->ha_write_row(table->record[0])))
+ {
+ if ((keynum= table->file->get_dup_key(error)) < 0)
+ {
+ /* We failed to retrieve the duplicate key */
+ return HA_ERR_FOUND_DUPP_KEY;
+ }
+
+ /*
+ We need to retrieve the old row into record[1] to be able to
+ either update or delete the offending record. We either:
+
+ - use rnd_pos() with a row-id (available as dupp_row) to the
+ offending row, if that is possible (MyISAM and Blackhole), or else
+
+ - use index_read_idx() with the key that is duplicated, to
+ retrieve the offending row.
+ */
+ if (table->file->table_flags() & HA_DUPP_POS)
+ {
+ error= table->file->rnd_pos(table->record[1], table->file->dupp_ref);
+ if (error)
+ return error;
+ }
+ else
+ {
+ if (table->file->extra(HA_EXTRA_FLUSH_CACHE))
+ {
+ return my_errno;
+ }
+
+ if (key.get() == NULL)
+ {
+ key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length)));
+ if (key.get() == NULL)
+ return ENOMEM;
+ }
+
+ key_copy(key.get(), table->record[0], table->key_info + keynum, 0);
+ error= table->file->index_read_idx(table->record[1], keynum, key.get(),
+ table->key_info[keynum].key_length,
+ HA_READ_KEY_EXACT);
+ if (error)
+ return error;
+ }
+
+ /*
+ Now, table->record[1] should contain the offending row. That
+ will enable us to update it or, alternatively, delete it (so
+ that we can insert the new row afterwards).
+
+ REPLACE is defined as either INSERT or DELETE + INSERT. If
+ possible, we can replace it with an UPDATE, but that will not
+ work on InnoDB if FOREIGN KEY checks are necessary.
+
+ I (Matz) am not sure of the reason for the last_uniq_key()
+ check as, but I'm guessing that it's something along the
+ following lines.
+
+ Suppose that we got the duplicate key to be a key that is not
+ the last unique key for the table and we perform an update:
+ then there might be another key for which the unique check will
+ fail, so we're better off just deleting the row and inserting
+ the correct row.
+ */
+ if (last_uniq_key(table, keynum) &&
+ !table->file->referenced_by_foreign_key())
+ {
+ error=table->file->ha_update_row(table->record[1],
+ table->record[0]);
+ return error;
+ }
+ else
+ {
+ if ((error= table->file->ha_delete_row(table->record[1])))
+ return error;
+ /* Will retry ha_write_row() with the offending row removed. */
+ }
+ }
+ return error;
+}
+
+int Write_rows_log_event::do_exec_row(TABLE *table)
+{
+ DBUG_ASSERT(table != NULL);
+ int error= replace_record(thd, table);
+ return error;
+}
+#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
+
+#ifdef MYSQL_CLIENT
+void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
+{
+ if (!print_event_info->short_form)
+ {
+ print_header(file, print_event_info);
+ fprintf(file, "\tWrite_rows: table id %lu", m_table_id);
+ print_base64(file, print_event_info);
+ }
+}
+#endif
+
+/**************************************************************************
+ Delete_rows_log_event member functions
+**************************************************************************/
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+static int record_compare(TABLE *table, byte const *a, byte const *b)
+{
+ for (my_size_t i= 0 ; i < table->s->fields ; ++i)
+ {
+ uint const off= table->field[i]->offset();
+ uint const res= table->field[i]->cmp_binary(a + off, b + off);
+ if (res != 0) {
+ return res;
+ }
+ }
+ return 0;
+}
+
+
+/*
+ Find the row given by 'key', if the table has keys, or else use a table scan
+ to find (and fetch) the row. If the engine allows random access of the
+ records, a combination of position() and rnd_pos() will be used.
+
+ The 'record_buf' will be used as buffer for records while locating the
+ correct row.
+ */
+static int find_and_fetch_row(TABLE *table, byte *key, byte *record_buf)
+{
+ DBUG_ENTER("find_and_fetch_row(TABLE *table, byte *key, byte *record)");
+ DBUG_PRINT("enter", ("table=%p, key=%p, record=%p",
+ table, key, record_buf));
+
+ DBUG_ASSERT(table->in_use != NULL);
+
+ if ((table->file->table_flags() & HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS)
+ && table->s->primary_key < MAX_KEY)
+ {
+ /*
+ Use a more efficient method to fetch the record given by
+ table->record[0] if the engine allows it. We first compute a
+ row reference using the position() member function (it will be
+ stored in table->file->ref) and the use rnd_pos() to position
+ the "cursor" at the correct row.
+ */
+ table->file->position(table->record[0]);
+ DBUG_RETURN(table->file->rnd_pos(table->record[0], table->file->ref));
+ }
+
+ DBUG_ASSERT(record_buf);
+
+ if (table->s->keys > 0)
+ {
+ int error;
+ if ((error= table->file->index_read_idx(record_buf, 0, key,
+ table->key_info->key_length,
+ HA_READ_KEY_EXACT)))
+ {
+ table->file->print_error(error, MYF(0));
+ DBUG_RETURN(error);
+ }
+
+ /*
+ Below is a minor "optimization". If the key (i.e., key number
+ 0) has the HA_NOSAME flag set, we know that we have found the
+ correct record (since there can be no duplicates); otherwise, we
+ have to compare the record with the one found to see if it is
+ the correct one.
+
+ CAVEAT! This behaviour is essential for the replication of,
+ e.g., the mysql.proc table since the correct record *shall* be
+ found using the primary key *only*. There shall be no
+ comparison of non-PK columns to decide if the correct record is
+ found. I can see no scenario where it would be incorrect to
+ chose the row to change only using a PK or an UNNI.
+ */
+ if (table->key_info->flags & HA_NOSAME)
+ DBUG_RETURN(0);
+
+ while (record_compare(table, table->record[0], record_buf) != 0)
+ {
+ int error;
+ if ((error= table->file->index_next(record_buf)))
+ {
+ table->file->print_error(error, MYF(0));
+ DBUG_RETURN(error);
+ }
+ }
+ }
+ else
+ {
+ /* Continue until we find the right record or have made a full loop */
+ int restart_count= 0; // Number of times scanning has restarted from top
+ int error= 0;
+ do
+ {
+ error= table->file->rnd_next(record_buf);
+ switch (error)
+ {
+ case 0:
+ case HA_ERR_RECORD_DELETED:
+ break;
+
+ case HA_ERR_END_OF_FILE:
+ if (++restart_count < 2)
+ table->file->ha_rnd_init(1);
+ break;
+
+ default:
+ table->file->print_error(error, MYF(0));
+ DBUG_RETURN(error);
+ }
+ }
+ while (restart_count < 2 &&
+ record_compare(table, table->record[0], record_buf) != 0);
+
+ DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == 0);
+ DBUG_RETURN(error);
+ }
+
+ DBUG_RETURN(0);
+}
+#endif
+
+/*
+ Constructor used to build an event for writing to the binary log.
+ */
+
+#ifndef MYSQL_CLIENT
+Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
+ ulong tid, MY_BITMAP const *cols,
+ bool is_transactional)
+ : Rows_log_event(thd_arg, tbl_arg, tid, cols, is_transactional)
+#ifdef HAVE_REPLICATION
+ ,m_memory(NULL), m_key(NULL), m_search_record(NULL)
+#endif
+{
+}
+#endif /* #if !defined(MYSQL_CLIENT) */
+
+/*
+ Constructor used by slave to read the event from the binary log.
+ */
+#ifdef HAVE_REPLICATION
+Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
+ const Format_description_log_event
+ *description_event)
+#if defined(MYSQL_CLIENT)
+ : Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event)
+#else
+ : Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event),
+ m_memory(NULL), m_key(NULL), m_search_record(NULL)
+#endif
+{
+}
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+int Delete_rows_log_event::do_before_row_operations(TABLE *table)
+{
+ DBUG_ASSERT(m_memory == NULL);
+
+ if ((table->file->table_flags() & HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS) &&
+ table->s->primary_key < MAX_KEY)
+ {
+ /*
+ We don't need to allocate any memory for m_search_record and
+ m_key since they are not used.
+ */
+ return 0;
+ }
+
+ int error= 0;
+
+ if (table->s->keys > 0)
+ {
+ m_memory=
+ my_multi_malloc(MYF(MY_WME),
+ &m_search_record, table->s->reclength,
+ &m_key, table->key_info->key_length,
+ NULL);
+ }
+ else
+ {
+ m_memory= m_search_record= my_malloc(table->s->reclength, MYF(MY_WME));
+ m_key= NULL;
+ }
+ if (!m_memory)
+ return HA_ERR_OUT_OF_MEM;
+
+ if (table->s->keys > 0)
+ {
+ /* We have a key: search the table using the index */
+ if (!table->file->inited)
+ error= table->file->ha_index_init(0, FALSE);
+ }
+ else
+ {
+ /* We doesn't have a key: search the table using rnd_next() */
+ error= table->file->ha_rnd_init(1);
+ }
+
+ return error;
+}
+
+int Delete_rows_log_event::do_after_row_operations(TABLE *table, int error)
+{
+ /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
+ table->file->ha_index_or_rnd_end();
+ my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR)); // Free for multi_malloc
+ m_memory= m_search_record= m_key= NULL;
+
+ return error;
+}
+
+char const *Delete_rows_log_event::do_prepare_row(THD *thd, TABLE *table,
+ char const *row_start)
+{
+ char const *ptr= row_start;
+ DBUG_ASSERT(ptr);
+ /*
+ This assertion actually checks that there is at least as many
+ columns on the slave as on the master.
+ */
+ DBUG_ASSERT(table->s->fields >= m_width);
+
+ DBUG_ASSERT(ptr != NULL);
+ ptr= unpack_row(table, table->record[0], ptr, &m_cols);
+
+ /*
+ If we will access rows using the random access method, m_key will
+ be set to NULL, so we do not need to make a key copy in that case.
+ */
+ if (m_key)
+ {
+ KEY *const key_info= table->key_info;
+
+ key_copy(m_key, table->record[0], key_info, 0);
+ }
+
+ return ptr;
+}
+
+int Delete_rows_log_event::do_exec_row(TABLE *table)
+{
+ DBUG_ASSERT(table != NULL);
+
+ int error= find_and_fetch_row(table, m_key, m_search_record);
+ if (error)
+ return error;
+
+ /*
+ Now we should have the right row to delete. We are using
+ record[0] since it is guaranteed to point to a record with the
+ correct value.
+ */
+ error= table->file->ha_delete_row(table->record[0]);
+
+ return error;
+}
+
+#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
+
+#ifdef MYSQL_CLIENT
+void Delete_rows_log_event::print(FILE *file,
+ PRINT_EVENT_INFO* print_event_info)
+{
+ if (!print_event_info->short_form)
+ {
+ print_header(file, print_event_info);
+ fprintf(file, "\tDelete_rows: table id %lu", m_table_id);
+ print_base64(file, print_event_info);
+ }
+}
+#endif
+
+
+/**************************************************************************
+ Update_rows_log_event member functions
+**************************************************************************/
+
+/*
+ Constructor used to build an event for writing to the binary log.
+ */
+#if !defined(MYSQL_CLIENT)
+Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
+ ulong tid, MY_BITMAP const *cols,
+ bool is_transactional)
+: Rows_log_event(thd_arg, tbl_arg, tid, cols, is_transactional)
+#ifdef HAVE_REPLICATION
+ , m_memory(NULL), m_key(NULL)
+#endif
+{
+}
+#endif /* !defined(MYSQL_CLIENT) */
+
+/*
+ Constructor used by slave to read the event from the binary log.
+ */
+#ifdef HAVE_REPLICATION
+Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
+ const
+ Format_description_log_event
+ *description_event)
+#if defined(MYSQL_CLIENT)
+ : Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event)
+#else
+ : Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event),
+ m_memory(NULL), m_key(NULL)
+#endif
+{
+}
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+int Update_rows_log_event::do_before_row_operations(TABLE *table)
+{
+ DBUG_ASSERT(m_memory == NULL);
+
+ if ((table->file->table_flags() & HA_PRIMARY_KEY_ALLOW_RANDOM_ACCESS) &&
+ table->s->primary_key < MAX_KEY)
+ {
+ /*
+ We don't need to allocate any memory for m_search_record and
+ m_key since they are not used.
+ */
+ return 0;
+ }
+
+ int error= 0;
+
+ if (table->s->keys > 0)
+ {
+ m_memory=
+ my_multi_malloc(MYF(MY_WME),
+ &m_search_record, table->s->reclength,
+ &m_key, table->key_info->key_length,
+ NULL);
+ }
+ else
+ {
+ m_memory= m_search_record= my_malloc(table->s->reclength, MYF(MY_WME));
+ m_key= NULL;
+ }
+ if (!m_memory)
+ return HA_ERR_OUT_OF_MEM;
+
+ if (table->s->keys > 0)
+ {
+ /* We have a key: search the table using the index */
+ if (!table->file->inited)
+ error= table->file->ha_index_init(0, FALSE);
+ }
+ else
+ {
+ /* We doesn't have a key: search the table using rnd_next() */
+ error= table->file->ha_rnd_init(1);
+ }
+ table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
+
+ return error;
+}
+
+int Update_rows_log_event::do_after_row_operations(TABLE *table, int error)
+{
+ /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
+ table->file->ha_index_or_rnd_end();
+ my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
+ m_memory= m_search_record= m_key= NULL;
+
+ return error;
+}
+
+char const *Update_rows_log_event::do_prepare_row(THD *thd, TABLE *table,
+ char const *row_start)
+{
+ char const *ptr= row_start;
+ DBUG_ASSERT(ptr);
+ /*
+ This assertion actually checks that there is at least as many
+ columns on the slave as on the master.
+ */
+ DBUG_ASSERT(table->s->fields >= m_width);
+
+ /* record[0] is the before image for the update */
+ ptr= unpack_row(table, table->record[0], ptr, &m_cols);
+ DBUG_ASSERT(ptr != NULL);
+ /* record[1] is the after image for the update */
+ ptr= unpack_row(table, table->record[1], ptr, &m_cols);
+
+ /*
+ If we will access rows using the random access method, m_key will
+ be set to NULL, so we do not need to make a key copy in that case.
+ */
+ if (m_key)
+ {
+ KEY *const key_info= table->key_info;
+
+ key_copy(m_key, table->record[0], key_info, 0);
+ }
+
+ return ptr;
+}
+
+int Update_rows_log_event::do_exec_row(TABLE *table)
+{
+ DBUG_ASSERT(table != NULL);
+
+ int error= find_and_fetch_row(table, m_key, m_search_record);
+ if (error)
+ return error;
+
+ /*
+ Now we should have the right row to update. The record that has
+ been fetched is guaranteed to be in record[0], so we use that.
+ */
+ error= table->file->ha_update_row(table->record[0], table->record[1]);
+
+ return error;
+}
+#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
+
+#ifdef MYSQL_CLIENT
+void Update_rows_log_event::print(FILE *file,
+ PRINT_EVENT_INFO* print_event_info)
+{
+ if (!print_event_info->short_form)
+ {
+ print_header(file, print_event_info);
+ fprintf(file, "\tUpdate_rows: table id %lu", m_table_id);
+ print_base64(file, print_event_info);
+ }
+}
+#endif
+
+#endif /* defined(HAVE_ROW_BASED_REPLICATION) */
diff --git a/sql/log_event.h b/sql/log_event.h
index 7783a97f03f..5d58a204ec9 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -26,6 +26,16 @@
#pragma interface /* gcc class implementation */
#endif
+#include <my_bitmap.h>
+
+#if !defined(MYSQL_CLIENT)
+#ifdef HAVE_ROW_BASED_REPLICATION
+extern my_bool binlog_row_based;
+#else
+extern const my_bool binlog_row_based;
+#endif
+#endif
+
#define LOG_READ_EOF -1
#define LOG_READ_BOGUS -2
#define LOG_READ_IO -3
@@ -196,6 +206,8 @@ struct sql_ex_info
#define EXEC_LOAD_HEADER_LEN 4
#define DELETE_FILE_HEADER_LEN 4
#define FORMAT_DESCRIPTION_HEADER_LEN (START_V3_HEADER_LEN+1+LOG_EVENT_TYPES)
+#define ROWS_HEADER_LEN 8
+#define TABLE_MAP_HEADER_LEN 8
#define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1)
#define EXECUTE_LOAD_QUERY_HEADER_LEN (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN)
@@ -302,6 +314,14 @@ struct sql_ex_info
/* DF = "Delete File" */
#define DF_FILE_ID_OFFSET 0
+/* TM = "Table Map" */
+#define TM_MAPID_OFFSET 0
+#define TM_FLAGS_OFFSET 6
+
+/* RW = "RoWs" */
+#define RW_MAPID_OFFSET 0
+#define RW_FLAGS_OFFSET 6
+
/* ELQ = "Execute Load Query" */
#define ELQ_FILE_ID_OFFSET QUERY_HEADER_LEN
#define ELQ_FN_POS_START_OFFSET ELQ_FILE_ID_OFFSET + 4
@@ -373,6 +393,12 @@ struct sql_ex_info
#define LOG_EVENT_SUPPRESS_USE_F 0x8
/*
+ The table map version internal to the log should be increased after
+ the event has been written to the binary log.
+ */
+#define LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F 0x10
+
+/*
OPTIONS_WRITTEN_TO_BIN_LOG are the bits of thd->options which must be
written to the binlog. OPTIONS_WRITTEN_TO_BINLOG could be written
into the Format_description_log_event, so that if later we don't want
@@ -427,6 +453,10 @@ enum Log_event_type
XID_EVENT= 16,
BEGIN_LOAD_QUERY_EVENT= 17,
EXECUTE_LOAD_QUERY_EVENT= 18,
+ TABLE_MAP_EVENT = 19,
+ WRITE_ROWS_EVENT = 20,
+ UPDATE_ROWS_EVENT = 21,
+ DELETE_ROWS_EVENT = 22,
/*
Add new events here - right above this comment!
@@ -504,6 +534,7 @@ typedef struct st_print_event_info
/* Settings on how to print the events */
bool short_form;
+ bool base64_output;
my_off_t hexdump_from;
uint8 common_header_len;
@@ -616,9 +647,10 @@ public:
static Log_event* read_log_event(IO_CACHE* file,
const Format_description_log_event *description_event);
/* print*() functions are used by mysqlbinlog */
- virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0) = 0;
+ virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0;
void print_timestamp(FILE* file, time_t *ts = 0);
- void print_header(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print_header(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ void print_base64(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
static void *operator new(size_t size)
@@ -646,7 +678,7 @@ public:
virtual Log_event_type get_type_code() = 0;
virtual bool is_valid() const = 0;
virtual bool is_artificial_event() { return 0; }
- inline bool get_cache_stmt() { return cache_stmt; }
+ inline bool get_cache_stmt() const { return cache_stmt; }
Log_event(const char* buf, const Format_description_log_event* description_event);
virtual ~Log_event() { free_temp_buf();}
void register_temp_buf(char* buf) { temp_buf = buf; }
@@ -778,8 +810,8 @@ public:
uint32 q_len_arg);
#endif /* HAVE_REPLICATION */
#else
- void print_query_header(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print_query_header(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Query_log_event(const char* buf, uint event_len,
@@ -833,7 +865,7 @@ public:
void pack_info(Protocol* protocol);
int exec_event(struct st_relay_log_info* rli);
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Slave_log_event(const char* buf, uint event_len);
@@ -921,7 +953,7 @@ public:
bool use_rli_only_for_errors);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info = 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool commented);
#endif
@@ -1011,7 +1043,7 @@ public:
#endif /* HAVE_REPLICATION */
#else
Start_log_event_v3() {}
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Start_log_event_v3(const char* buf,
@@ -1106,7 +1138,7 @@ public:
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Intvar_log_event(const char* buf, const Format_description_log_event* description_event);
@@ -1147,7 +1179,7 @@ class Rand_log_event: public Log_event
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Rand_log_event(const char* buf, const Format_description_log_event* description_event);
@@ -1184,7 +1216,7 @@ class Xid_log_event: public Log_event
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Xid_log_event(const char* buf, const Format_description_log_event* description_event);
@@ -1195,6 +1227,9 @@ class Xid_log_event: public Log_event
bool write(IO_CACHE* file);
#endif
bool is_valid() const { return 1; }
+#if !defined(DBUG_OFF) && !defined(MYSQL_CLIENT)
+ static my_bool show_xid;
+#endif
};
/*****************************************************************************
@@ -1226,7 +1261,7 @@ public:
void pack_info(Protocol* protocol);
int exec_event(struct st_relay_log_info* rli);
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
User_var_log_event(const char* buf, const Format_description_log_event* description_event);
@@ -1252,7 +1287,7 @@ public:
{}
int exec_event(struct st_relay_log_info* rli);
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Stop_log_event(const char* buf, const Format_description_log_event* description_event):
@@ -1282,7 +1317,7 @@ public:
uint ident_len;
uint flags;
#ifndef MYSQL_CLIENT
- Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg,
+ Rotate_log_event(const char* new_log_ident_arg,
uint ident_len_arg,
ulonglong pos_arg, uint flags);
#ifdef HAVE_REPLICATION
@@ -1290,7 +1325,7 @@ public:
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Rotate_log_event(const char* buf, uint event_len,
@@ -1343,7 +1378,7 @@ public:
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool enable_local);
#endif
@@ -1411,7 +1446,7 @@ public:
virtual int get_create_or_append() const;
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Append_block_log_event(const char* buf, uint event_len,
@@ -1422,8 +1457,8 @@ public:
bool is_valid() const { return block != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
-#endif
const char* get_db() { return db; }
+#endif
};
@@ -1446,7 +1481,7 @@ public:
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool enable_local);
#endif
@@ -1458,8 +1493,8 @@ public:
bool is_valid() const { return file_id != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
-#endif
const char* get_db() { return db; }
+#endif
};
@@ -1482,7 +1517,7 @@ public:
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
#endif
Execute_load_log_event(const char* buf, uint event_len,
@@ -1493,8 +1528,8 @@ public:
bool is_valid() const { return file_id != 0; }
#ifndef MYSQL_CLIENT
bool write(IO_CACHE* file);
-#endif
const char* get_db() { return db; }
+#endif
};
@@ -1567,7 +1602,7 @@ public:
int exec_event(struct st_relay_log_info* rli);
#endif /* HAVE_REPLICATION */
#else
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
/* Prints the query as LOAD DATA LOCAL and with rewritten filename */
void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
const char *local_fname);
@@ -1599,10 +1634,523 @@ public:
Log_event(buf, description_event)
{}
~Unknown_log_event() {}
- void print(FILE* file, PRINT_EVENT_INFO* print_event_info= 0);
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
Log_event_type get_type_code() { return UNKNOWN_EVENT;}
bool is_valid() const { return 1; }
};
#endif
char *str_to_hex(char *to, const char *from, uint len);
+
+/*****************************************************************************
+
+ Table map log event class
+
+ Create a mapping from a (database name, table name) couple to a table
+ identifier (an integer number).
+
+ ****************************************************************************/
+
+class Table_map_log_event : public Log_event
+{
+public:
+ /* Constants */
+ enum
+ {
+ TYPE_CODE = TABLE_MAP_EVENT
+ };
+
+ enum enum_error
+ {
+ ERR_OPEN_FAILURE = -1, /* Failure to open table */
+ ERR_OK = 0, /* No error */
+ ERR_TABLE_LIMIT_EXCEEDED = 1, /* No more room for tables */
+ ERR_OUT_OF_MEM = 2, /* Out of memory */
+ ERR_BAD_TABLE_DEF = 3, /* Table definition does not match */
+ ERR_RBR_TO_SBR = 4 /* daisy-chanining RBR to SBR not allowed */
+ };
+
+ enum enum_flag
+ {
+ /*
+ Nothing here right now, but the flags support is there in
+ preparation for changes that are coming.
+ */
+ };
+
+ typedef uint16 flag_set;
+
+ /* Special constants representing sets of flags */
+ enum
+ {
+ NO_FLAGS = 0U
+ };
+
+ void set_flags(flag_set flag) { m_flags |= flag; }
+ void clear_flags(flag_set flag) { m_flags &= ~flag; }
+ flag_set get_flags(flag_set flag) const { return m_flags & flag; }
+
+#ifndef MYSQL_CLIENT
+ Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
+ bool is_transactional, uint16 flags);
+#endif
+#ifdef HAVE_REPLICATION
+ Table_map_log_event(const char *buf, uint event_len,
+ const Format_description_log_event *description_event);
+#endif
+
+ ~Table_map_log_event();
+
+ virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; }
+ virtual bool is_valid() const { return m_memory; /* we check malloc */ }
+
+ virtual int get_data_size() { return m_data_size; }
+#ifndef MYSQL_CLIENT
+ virtual bool write_data_header(IO_CACHE *file);
+ virtual bool write_data_body(IO_CACHE *file);
+ virtual const char *get_db() { return m_dbnam; }
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int exec_event(struct st_relay_log_info *rli);
+ virtual void pack_info(Protocol *protocol);
+#endif
+
+#ifdef MYSQL_CLIENT
+ virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+
+
+private:
+#ifndef MYSQL_CLIENT
+ TABLE *m_table;
+#endif
+ char const *m_dbnam;
+ my_size_t m_dblen;
+ char const *m_tblnam;
+ my_size_t m_tbllen;
+ ulong m_colcnt;
+ unsigned char *m_coltype;
+
+ gptr m_memory;
+ ulong m_table_id;
+ flag_set m_flags;
+
+ my_size_t m_data_size;
+};
+
+
+/*****************************************************************************
+
+ Row level log event class.
+
+ Common base class for all row-level log events.
+
+ RESPONSIBILITIES
+
+ Encode the common parts of all events containing rows, which are:
+ - Write data header and data body to an IO_CACHE.
+ - Provide an interface for adding an individual row to the event.
+
+ ****************************************************************************/
+
+class Rows_log_event : public Log_event
+{
+public:
+ /*
+ These definitions allow you to combine the flags into an
+ appropriate flag set using the normal bitwise operators. The
+ implicit conversion from an enum-constant to an integer is
+ accepted by the compiler, which is then used to set the real set
+ of flags.
+ */
+
+ enum enum_flag
+ {
+ /* Last event of a statement */
+ STMT_END_F = (1U << 0),
+
+ /* Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */
+ NO_FOREIGN_KEY_CHECKS_F = (1U << 1),
+
+ /* Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */
+ RELAXED_UNIQUE_CHECKS_F = (1U << 2)
+ };
+
+ typedef uint16 flag_set;
+
+ /* Special constants representing sets of flags */
+ enum
+ {
+ NO_FLAGS = 0U
+ };
+
+ virtual ~Rows_log_event();
+
+ void set_flags(flag_set flags) { m_flags |= flags; }
+ void clear_flags(flag_set flags) { m_flags &= ~flags; }
+ flag_set get_flags(flag_set flags) const { return m_flags & flags; }
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ virtual int exec_event(struct st_relay_log_info *rli);
+#ifdef DBUG_RBR
+ virtual void pack_info(Protocol *protocol);
+#endif
+#endif
+
+#ifdef MYSQL_CLIENT
+ /* not for direct call, each derived has its own ::print() */
+ virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0;
+#endif
+
+#ifndef MYSQL_CLIENT
+ int add_row_data(byte *data, my_size_t length)
+ {
+ return do_add_row_data(data,length);
+ }
+#endif
+
+ /* Member functions to implement superclass interface */
+ virtual int get_data_size()
+ {
+ DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
+ return 6 + 1 + no_bytes_in_map(&m_cols) +
+ (m_rows_cur - m_rows_buf););
+ return ROWS_HEADER_LEN + 1 + no_bytes_in_map(&m_cols) +
+ (m_rows_cur - m_rows_buf);
+ }
+
+ MY_BITMAP const *get_cols() const { return &m_cols; }
+ my_size_t get_width() const { return m_width; }
+ ulong get_table_id() const { return m_table_id; }
+
+#ifndef MYSQL_CLIENT
+ virtual bool write_data_header(IO_CACHE *file);
+ virtual bool write_data_body(IO_CACHE *file);
+ virtual const char *get_db() { return m_table->s->db.str; }
+#endif
+ virtual bool is_valid() const
+ {
+ /* that's how we check malloc() succeeded */
+ return m_rows_buf && m_cols.bitmap;
+ }
+
+ /*
+ If there is no table map active for the event, write one to the
+ binary log.
+
+ LOCK_log has to be aquired before calling this function.
+
+ PARAMETERS
+ thd - Thread to use when writing the table map
+
+ RETURN VALUE
+ Error code, or zero if write succeeded.
+ */
+#if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED_REPLICATION)
+ int maybe_write_table_map(THD *thd, IO_CACHE *file, MYSQL_LOG *log) const
+ {
+ /*
+ N.B., get_cache_stmt() returns the value of 'using_trans' that
+ was provided to the constructor, i.e., get_cache_stmt() == true
+ if and only if the table is transactional.
+ */
+
+ int result= 0;
+ if (!log->is_table_mapped(m_table))
+ result= log->write_table_map(thd, file, m_table, get_cache_stmt());
+ return result;
+ }
+#endif
+
+protected:
+ /*
+ The constructors are protected since you're supposed to inherit
+ this class, not create instances of this class.
+ */
+#ifndef MYSQL_CLIENT
+ Rows_log_event(THD*, TABLE*, ulong table_id,
+ MY_BITMAP const *cols, bool is_transactional);
+#endif
+ Rows_log_event(const char *row_data, uint event_len,
+ Log_event_type event_type,
+ const Format_description_log_event *description_event);
+
+#ifndef MYSQL_CLIENT
+ virtual int do_add_row_data(byte *data, my_size_t length);
+#endif
+
+#ifndef MYSQL_CLIENT
+ TABLE *m_table; /* The table the rows belong to */
+#endif
+ ulong m_table_id; /* Table ID */
+ MY_BITMAP m_cols; /* Bitmap denoting columns available */
+ ulong m_width; /* The width of the columns bitmap */
+
+ /* Bit buffer in the same memory as the class */
+ uint32 m_bitbuf[128/(sizeof(uint32)*8)];
+
+ byte *m_rows_buf; /* The rows in packed format */
+ byte *m_rows_cur; /* One-after the end of the data */
+ byte *m_rows_end; /* One-after the end of the allocated space */
+
+ flag_set m_flags; /* Flags for row-level events */
+
+private:
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ /*
+ Primitive to prepare for a sequence of row executions.
+
+ DESCRIPTION
+
+ Before doing a sequence of do_prepare_row() and do_exec_row()
+ calls, this member function should be called to prepare for the
+ entire sequence. Typically, this member function will allocate
+ space for any buffers that are needed for the two member
+ functions mentioned above.
+
+ RETURN VALUE
+
+ The member function will return 0 if all went OK, or a non-zero
+ error code otherwise.
+ */
+ virtual int do_before_row_operations(TABLE *table) = 0;
+
+ /*
+ Primitive to clean up after a sequence of row executions.
+
+ DESCRIPTION
+
+ After doing a sequence of do_prepare_row() and do_exec_row(),
+ this member function should be called to clean up and release
+ any allocated buffers.
+ */
+ virtual int do_after_row_operations(TABLE *table, int error) = 0;
+
+ /*
+ Primitive to prepare for handling one row in a row-level event.
+
+ DESCRIPTION
+
+ The member function prepares for execution of operations needed for one
+ row in a row-level event by reading up data from the buffer containing
+ the row. No specific interpretation of the data is normally done here,
+ since SQL thread specific data is not available: that data is made
+ available for the do_exec function.
+
+ RETURN VALUE
+ A pointer to the start of the next row, or NULL if the preparation
+ failed. Currently, preparation cannot fail, but don't rely on this
+ behavior.
+ */
+ virtual char const *do_prepare_row(THD*, TABLE*, char const *row_start) = 0;
+
+ /*
+ Primitive to do the actual execution necessary for a row.
+
+ DESCRIPTION
+ The member function will do the actual execution needed to handle a row.
+
+ RETURN VALUE
+ 0 if execution succeeded, 1 if execution failed.
+
+ */
+ virtual int do_exec_row(TABLE *table) = 0;
+#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
+};
+
+
+/*****************************************************************************
+
+ Write row log event class
+
+ Log row insertions and updates. The event contain several
+ insert/update rows for a table. Note that each event contains only
+ rows for one table.
+
+ ****************************************************************************/
+class Write_rows_log_event : public Rows_log_event
+{
+public:
+ enum
+ {
+ /* Support interface to THD::binlog_prepare_pending_rows_event */
+ TYPE_CODE = WRITE_ROWS_EVENT
+ };
+
+#if !defined(MYSQL_CLIENT)
+ Write_rows_log_event(THD*, TABLE*, ulong table_id,
+ MY_BITMAP const *cols, bool is_transactional);
+#endif
+#ifdef HAVE_REPLICATION
+ Write_rows_log_event(const char *buf, uint event_len,
+ const Format_description_log_event *description_event);
+#endif
+#if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED_REPLICATION)
+ static bool binlog_row_logging_function(THD *thd, TABLE *table,
+ bool is_transactional,
+ MY_BITMAP *cols,
+ uint fields,
+ const byte *before_record
+ __attribute__((unused)),
+ const byte *after_record)
+ {
+ return thd->binlog_write_row(table, is_transactional,
+ cols, fields, after_record);
+ }
+#endif
+
+private:
+ virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
+
+#ifdef MYSQL_CLIENT
+ void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ gptr m_memory;
+ byte *m_search_record;
+
+ virtual int do_before_row_operations(TABLE *table);
+ virtual int do_after_row_operations(TABLE *table, int error);
+ virtual char const *do_prepare_row(THD*, TABLE*, char const *row_start);
+ virtual int do_exec_row(TABLE *table);
+#endif
+};
+
+
+/*****************************************************************************
+
+ Update rows log event class
+
+ Log row updates with a before image. The event contain several
+ update rows for a table. Note that each event contains only rows for
+ one table.
+
+ Also note that the row data consists of pairs of row data: one row
+ for the old data and one row for the new data.
+
+ ****************************************************************************/
+class Update_rows_log_event : public Rows_log_event
+{
+public:
+ enum
+ {
+ /* Support interface to THD::binlog_prepare_pending_rows_event */
+ TYPE_CODE = UPDATE_ROWS_EVENT
+ };
+
+#ifndef MYSQL_CLIENT
+ Update_rows_log_event(THD*, TABLE*, ulong table_id,
+ MY_BITMAP const *cols, bool is_transactional);
+#endif
+
+#ifdef HAVE_REPLICATION
+ Update_rows_log_event(const char *buf, uint event_len,
+ const Format_description_log_event *description_event);
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED_REPLICATION)
+ static bool binlog_row_logging_function(THD *thd, TABLE *table,
+ bool is_transactional,
+ MY_BITMAP *cols,
+ uint fields,
+ const byte *before_record,
+ const byte *after_record)
+ {
+ return thd->binlog_update_row(table, is_transactional,
+ cols, fields, before_record, after_record);
+ }
+#endif
+
+private:
+ virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
+
+#ifdef MYSQL_CLIENT
+ void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ gptr m_memory;
+ byte *m_key;
+ byte *m_search_record;
+
+ virtual int do_before_row_operations(TABLE *table);
+ virtual int do_after_row_operations(TABLE *table, int error);
+ virtual char const *do_prepare_row(THD*, TABLE*, char const *row_start);
+ virtual int do_exec_row(TABLE *table);
+#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
+};
+
+/*****************************************************************************
+
+ Delete rows log event class.
+
+ Log row deletions. The event contain several delete rows for a
+ table. Note that each event contains only rows for one table.
+
+ RESPONSIBILITIES
+
+ - Act as a container for rows that has been deleted on the master
+ and should be deleted on the slave.
+
+ COLLABORATION
+
+ Row_writer
+ Create the event and add rows to the event.
+ Row_reader
+ Extract the rows from the event.
+
+ ****************************************************************************/
+class Delete_rows_log_event : public Rows_log_event
+{
+public:
+ enum
+ {
+ /* Support interface to THD::binlog_prepare_pending_rows_event */
+ TYPE_CODE = DELETE_ROWS_EVENT
+ };
+
+#ifndef MYSQL_CLIENT
+ Delete_rows_log_event(THD*, TABLE*, ulong,
+ MY_BITMAP const *cols, bool is_transactional);
+#endif
+#ifdef HAVE_REPLICATION
+ Delete_rows_log_event(const char *buf, uint event_len,
+ const Format_description_log_event *description_event);
+#endif
+#if !defined(MYSQL_CLIENT) && defined(HAVE_ROW_BASED_REPLICATION)
+ static bool binlog_row_logging_function(THD *thd, TABLE *table,
+ bool is_transactional,
+ MY_BITMAP *cols,
+ uint fields,
+ const byte *before_record,
+ const byte *after_record
+ __attribute__((unused)))
+ {
+ return thd->binlog_delete_row(table, is_transactional,
+ cols, fields, before_record);
+ }
+#endif
+
+private:
+ virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
+
+#ifdef MYSQL_CLIENT
+ void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
+#endif
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+ gptr m_memory;
+ byte *m_key;
+ byte *m_search_record;
+
+ virtual int do_before_row_operations(TABLE *table);
+ virtual int do_after_row_operations(TABLE *table, int error);
+ virtual char const *do_prepare_row(THD*, TABLE*, char const *row_start);
+ virtual int do_exec_row(TABLE *table);
+#endif
+};
+
+
#endif /* _log_event_h */
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index f18447de71c..48d1ea8e798 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -248,50 +248,50 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
TODO: separate three contexts above, move them to separate bitfields.
*/
-#define SELECT_DISTINCT (1L << 0) // SELECT, user
-#define SELECT_STRAIGHT_JOIN (1L << 1) // SELECT, user
-#define SELECT_DESCRIBE (1L << 2) // SELECT, user
-#define SELECT_SMALL_RESULT (1L << 3) // SELECT, user
-#define SELECT_BIG_RESULT (1L << 4) // SELECT, user
-#define OPTION_FOUND_ROWS (1L << 5) // SELECT, user
-#define OPTION_TO_QUERY_CACHE (1L << 6) // SELECT, user
-#define SELECT_NO_JOIN_CACHE (1L << 7) // intern
-#define OPTION_BIG_TABLES (1L << 8) // THD, user
-#define OPTION_BIG_SELECTS (1L << 9) // THD, user
-#define OPTION_LOG_OFF (1L << 10) // THD, user
-#define OPTION_UPDATE_LOG (1L << 11) // THD, user, unused
-#define TMP_TABLE_ALL_COLUMNS (1L << 12) // SELECT, intern
-#define OPTION_WARNINGS (1L << 13) // THD, user
-#define OPTION_AUTO_IS_NULL (1L << 14) // THD, user, binlog
-#define OPTION_FOUND_COMMENT (1L << 15) // SELECT, intern, parser
-#define OPTION_SAFE_UPDATES (1L << 16) // THD, user
-#define OPTION_BUFFER_RESULT (1L << 17) // SELECT, user
-#define OPTION_BIN_LOG (1L << 18) // THD, user
-#define OPTION_NOT_AUTOCOMMIT (1L << 19) // THD, user
-#define OPTION_BEGIN (1L << 20) // THD, intern
-#define OPTION_TABLE_LOCK (1L << 21) // THD, intern
-#define OPTION_QUICK (1L << 22) // SELECT (for DELETE)
-#define OPTION_QUOTE_SHOW_CREATE (1L << 23) // THD, user
+#define SELECT_DISTINCT (LL(1) << 0) // SELECT, user
+#define SELECT_STRAIGHT_JOIN (LL(1) << 1) // SELECT, user
+#define SELECT_DESCRIBE (LL(1) << 2) // SELECT, user
+#define SELECT_SMALL_RESULT (LL(1) << 3) // SELECT, user
+#define SELECT_BIG_RESULT (LL(1) << 4) // SELECT, user
+#define OPTION_FOUND_ROWS (LL(1) << 5) // SELECT, user
+#define OPTION_TO_QUERY_CACHE (LL(1) << 6) // SELECT, user
+#define SELECT_NO_JOIN_CACHE (LL(1) << 7) // intern
+#define OPTION_BIG_TABLES (LL(1) << 8) // THD, user
+#define OPTION_BIG_SELECTS (LL(1) << 9) // THD, user
+#define OPTION_LOG_OFF (LL(1) << 10) // THD, user
+#define OPTION_UPDATE_LOG (LL(1) << 11) // THD, user, unused
+#define TMP_TABLE_ALL_COLUMNS (LL(1) << 12) // SELECT, intern
+#define OPTION_WARNINGS (LL(1) << 13) // THD, user
+#define OPTION_AUTO_IS_NULL (LL(1) << 14) // THD, user, binlog
+#define OPTION_FOUND_COMMENT (LL(1) << 15) // SELECT, intern, parser
+#define OPTION_SAFE_UPDATES (LL(1) << 16) // THD, user
+#define OPTION_BUFFER_RESULT (LL(1) << 17) // SELECT, user
+#define OPTION_BIN_LOG (LL(1) << 18) // THD, user
+#define OPTION_NOT_AUTOCOMMIT (LL(1) << 19) // THD, user
+#define OPTION_BEGIN (LL(1) << 20) // THD, intern
+#define OPTION_TABLE_LOCK (LL(1) << 21) // THD, intern
+#define OPTION_QUICK (LL(1) << 22) // SELECT (for DELETE)
+#define OPTION_QUOTE_SHOW_CREATE (LL(1) << 23) // THD, user
/* Thr following is used to detect a conflict with DISTINCT
in the user query has requested */
-#define SELECT_ALL (1L << 24) // SELECT, user, parser
+#define SELECT_ALL (LL(1) << 24) // SELECT, user, parser
/* Set if we are updating a non-transaction safe table */
-#define OPTION_STATUS_NO_TRANS_UPDATE (1L << 25) // THD, intern
+#define OPTION_STATUS_NO_TRANS_UPDATE (LL(1) << 25) // THD, intern
/* The following can be set when importing tables in a 'wrong order'
to suppress foreign key checks */
-#define OPTION_NO_FOREIGN_KEY_CHECKS (1L << 26) // THD, user, binlog
+#define OPTION_NO_FOREIGN_KEY_CHECKS (LL(1) << 26) // THD, user, binlog
/* The following speeds up inserts to InnoDB tables by suppressing unique
key checks in some cases */
-#define OPTION_RELAXED_UNIQUE_CHECKS (1L << 27) // THD, user, binlog
-#define SELECT_NO_UNLOCK (1L << 28) // SELECT, intern
-#define OPTION_SCHEMA_TABLE (1L << 29) // SELECT, intern
+#define OPTION_RELAXED_UNIQUE_CHECKS (LL(1) << 27) // THD, user, binlog
+#define SELECT_NO_UNLOCK (LL(1) << 28) // SELECT, intern
+#define OPTION_SCHEMA_TABLE (LL(1) << 29) // SELECT, intern
/* Flag set if setup_tables already done */
-#define OPTION_SETUP_TABLES_DONE (1L << 30) // intern
+#define OPTION_SETUP_TABLES_DONE (LL(1) << 30) // intern
/* If not set then the thread will ignore all warnings with level notes. */
-#define OPTION_SQL_NOTES (1UL << 31) // THD, user
+#define OPTION_SQL_NOTES (LL(1) << 31) // THD, user
/*
Force the used temporary table to be a MyISAM table (because we will use
fulltext functions when reading from it.
@@ -600,6 +600,7 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create);
bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent);
void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, ushort flags);
+void mysql_client_binlog_statement(THD *thd);
bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
my_bool drop_temporary);
int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
@@ -1198,6 +1199,13 @@ extern ulong what_to_log,flush_time;
extern ulong query_buff_size, thread_stack;
extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
extern ulong max_binlog_size, max_relay_log_size;
+extern const char *opt_binlog_format;
+#ifdef HAVE_ROW_BASED_REPLICATION
+extern my_bool binlog_row_based;
+extern ulong opt_binlog_rows_event_max_size;
+#else
+extern const my_bool binlog_row_based;
+#endif
extern ulong rpl_recovery_rank, thread_cache_size;
extern ulong back_log;
extern ulong specialflag, current_pid;
@@ -1338,6 +1346,7 @@ extern handlerton myisammrg_hton;
extern handlerton heap_hton;
extern SHOW_COMP_OPTION have_isam;
+extern SHOW_COMP_OPTION have_row_based_replication;
extern SHOW_COMP_OPTION have_raid, have_openssl, have_symlink;
extern SHOW_COMP_OPTION have_query_cache;
extern SHOW_COMP_OPTION have_geometry, have_rtree_keys;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 20d09ae0228..2a51afbee8d 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -441,6 +441,33 @@ volatile bool mqh_used = 0;
my_bool opt_noacl;
my_bool sp_automatic_privileges= 1;
+#ifdef HAVE_ROW_BASED_REPLICATION
+/*
+ This variable below serves as an optimization for (opt_binlog_format ==
+ BF_ROW) as we need to do this test for every row. Stmt-based is default.
+*/
+my_bool binlog_row_based= FALSE;
+ulong opt_binlog_rows_event_max_size;
+const char *binlog_format_names[]= {"STATEMENT", "ROW", NullS};
+/*
+ Note that BF_UNSPECIFIED is last, after the end of binlog_format_names: it
+ has no corresponding cell in this array. We use this value to be able to
+ know if the user has explicitely specified a binlog format (then we require
+ also --log-bin) or not (then we fall back to statement-based).
+*/
+enum binlog_format { BF_STMT= 0, BF_ROW= 1, BF_UNSPECIFIED= 2 };
+#else
+const my_bool binlog_row_based= FALSE;
+const char *binlog_format_names[]= {"STATEMENT", NullS};
+enum binlog_format { BF_STMT= 0, BF_UNSPECIFIED= 2 };
+#endif
+
+TYPELIB binlog_format_typelib=
+ { array_elements(binlog_format_names)-1,"",
+ binlog_format_names, NULL };
+const char *opt_binlog_format= 0;
+enum binlog_format opt_binlog_format_id= BF_UNSPECIFIED;
+
#ifdef HAVE_INITGROUPS
static bool calling_initgroups= FALSE; /* Used in SIGSEGV handler. */
#endif
@@ -528,6 +555,7 @@ MY_BITMAP temp_pool;
CHARSET_INFO *system_charset_info, *files_charset_info ;
CHARSET_INFO *national_charset_info, *table_alias_charset;
+SHOW_COMP_OPTION have_row_based_replication;
SHOW_COMP_OPTION have_raid, have_openssl, have_symlink, have_query_cache;
SHOW_COMP_OPTION have_geometry, have_rtree_keys;
SHOW_COMP_OPTION have_crypt, have_compress;
@@ -3032,8 +3060,44 @@ with --log-bin instead.");
{
sql_print_warning("You need to use --log-bin to make "
"--log-slave-updates work.");
- unireg_abort(1);
+ unireg_abort(1);
+ }
+
+ if (!opt_bin_log && (opt_binlog_format_id != BF_UNSPECIFIED))
+ {
+ sql_print_warning("You need to use --log-bin to make "
+ "--binlog-format work.");
+ unireg_abort(1);
}
+ if (opt_binlog_format_id == BF_UNSPECIFIED)
+ {
+ /*
+ We use statement-based by default, but could change this to be row-based
+ if this is a cluster build (i.e. have_ndbcluster is true)...
+ */
+ opt_binlog_format_id= BF_STMT;
+ }
+#ifdef HAVE_ROW_BASED_REPLICATION
+ if (opt_binlog_format_id == BF_ROW)
+ {
+ binlog_row_based= TRUE;
+ /*
+ Row-based binlogging turns on InnoDB unsafe locking, because the locks
+ are not needed when using row-based binlogging. In fact
+ innodb-locks-unsafe-for-binlog is unsafe only for stmt-based, it's
+ safe for row-based.
+ */
+#ifdef HAVE_INNOBASE_DB
+ innobase_locks_unsafe_for_binlog= TRUE;
+#endif
+ /* Trust stored function creators because they can do no harm */
+ trust_function_creators= 1;
+ }
+#endif
+ /* Check that we have not let the format to unspecified at this point */
+ DBUG_ASSERT((uint)opt_binlog_format_id <=
+ array_elements(binlog_format_names)-1);
+ opt_binlog_format= binlog_format_names[opt_binlog_format_id];
if (opt_slow_log)
mysql_slow_log.open_slow_log(opt_slow_logname);
@@ -4504,6 +4568,13 @@ enum options_mysqld
OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB,
OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES,
OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB,
+ OPT_BINLOG_FORMAT,
+#ifndef DBUG_OFF
+ OPT_BINLOG_SHOW_XID,
+#endif
+#ifdef HAVE_ROW_BASED_REPLICATION
+ OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
+#endif
OPT_WANT_CORE, OPT_CONCURRENT_INSERT,
OPT_MEMLOCK, OPT_MYISAM_RECOVER,
OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID,
@@ -4732,12 +4803,46 @@ Disable with --skip-bdb (will save memory).",
{"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
(gptr*) &my_bind_addr_str, (gptr*) &my_bind_addr_str, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"binlog-format", OPT_BINLOG_FORMAT,
+#ifdef HAVE_ROW_BASED_REPLICATION
+ "Tell the master the form of binary logging to use: either 'row' for "
+ "row-based binary logging (which automatically turns on "
+ "innodb_locks_unsafe_for_binlog as it is safe in this case), or "
+ "'statement' for statement-based logging. ",
+#else
+ "Tell the master the form of binary logging to use: this release build "
+ "supports only statement-based binary logging, so only 'statement' is "
+ "a legal value; MySQL-Max release builds support row-based binary logging "
+ "in addition.",
+#endif
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"binlog-do-db", OPT_BINLOG_DO_DB,
"Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
"Tells the master that updates to the given database should not be logged tothe binary log.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#if !defined(DBUG_OFF) && !defined(MYSQL_CLIENT)
+ {"binlog-show-xid", OPT_BINLOG_SHOW_XID,
+ "Option used by mysql-test for debugging and testing: "
+ "do not display the XID in SHOW BINLOG EVENTS; "
+ "may be removed in future versions",
+ (gptr*) &Xid_log_event::show_xid, (gptr*) &Xid_log_event::show_xid,
+ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+#endif
+#ifdef HAVE_ROW_BASED_REPLICATION
+ {"binlog-row-event-max-size", OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
+ "The maximum size of a row-based binary log event in bytes. Rows will be "
+ "grouped into events smaller than this size if possible. "
+ "The value has to be a multiple of 256.",
+ (gptr*) &opt_binlog_rows_event_max_size,
+ (gptr*) &opt_binlog_rows_event_max_size, 0,
+ GET_ULONG, REQUIRED_ARG,
+ /* def_value */ 1024, /* min_value */ 256, /* max_value */ ULONG_MAX,
+ /* sub_size */ 0, /* block_size */ 256,
+ /* app_type */ 0
+ },
+#endif
{"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"character-set-client-handshake", OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
@@ -4905,7 +5010,9 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
(gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
0, 0, 0},
{"innodb_locks_unsafe_for_binlog", OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG,
- "Force InnoDB not to use next-key locking. Instead use only row-level locking",
+ "Force InnoDB not to use next-key locking, to use only row-level locking."
+ " This is unsafe if you are using statement-based binary logging, and safe"
+ " if you are using row-based binary logging.",
(gptr*) &innobase_locks_unsafe_for_binlog,
(gptr*) &innobase_locks_unsafe_for_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"innodb_log_arch_dir", OPT_INNODB_LOG_ARCH_DIR,
@@ -4984,8 +5091,12 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
{"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
"If equal to 0 (the default), then when --log-bin is used, creation of "
"a function is allowed only to users having the SUPER privilege and only "
- "if this function may not break binary logging.",
- (gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
+ "if this function may not break binary logging."
+#ifdef HAVE_ROW_BASED_REPLICATION
+ " If using --binlog-format=row, the security issues do not exist and the "
+ "binary logging cannot break so this option is automatically set to 1."
+#endif
+ ,(gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
(gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR,
@@ -6459,6 +6570,11 @@ static void mysql_init_variables(void)
"d:t:i:o,/tmp/mysqld.trace");
#endif
opt_error_log= IF_WIN(1,0);
+#ifdef HAVE_ROW_BASED_REPLICATION
+ have_row_based_replication= SHOW_OPTION_YES;
+#else
+ have_row_based_replication= SHOW_OPTION_NO;
+#endif
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
have_ndbcluster=SHOW_OPTION_DISABLED;
global_system_variables.ndb_index_stat_enable=TRUE;
@@ -6682,6 +6798,28 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
binlog_filter->add_ignore_db(argument);
break;
}
+ case OPT_BINLOG_FORMAT:
+ {
+ int id;
+ if ((id= find_type(argument, &binlog_format_typelib, 2)) <= 0)
+ {
+#ifdef HAVE_ROW_BASED_REPLICATION
+ fprintf(stderr,
+ "Unknown binary log format: '%s' "
+ "(should be '%s' or '%s')\n",
+ argument,
+ binlog_format_names[BF_STMT],
+ binlog_format_names[BF_ROW]);
+#else
+ fprintf(stderr,
+ "Unknown binary log format: '%s' (only legal value is '%s')\n",
+ argument, binlog_format_names[BF_STMT]);
+#endif
+ exit(1);
+ }
+ opt_binlog_format_id= (enum binlog_format)(id-1);
+ break;
+ }
case (int)OPT_BINLOG_DO_DB:
{
binlog_filter->add_do_db(argument);
@@ -7229,6 +7367,7 @@ static void get_options(int argc,char **argv)
init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
&global_system_variables.datetime_format))
exit(1);
+
}
diff --git a/sql/rpl_filter.h b/sql/rpl_filter.h
index 5a766424d19..58d2b97c9c6 100644
--- a/sql/rpl_filter.h
+++ b/sql/rpl_filter.h
@@ -18,7 +18,6 @@
#define RPL_FILTER_H
#include "mysql.h"
-#include "my_list.h"
typedef struct st_table_rule_ent
{
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
new file mode 100644
index 00000000000..5500fdf1f64
--- /dev/null
+++ b/sql/rpl_rli.h
@@ -0,0 +1,312 @@
+/* Copyright (C) 2005 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef RPL_RLI_H
+#define RPL_RLI_H
+
+#define MAX_SLAVE_ERRMSG 1024
+
+#include "rpl_tblmap.h"
+
+/****************************************************************************
+
+ Replication SQL Thread
+
+ st_relay_log_info contains:
+ - the current relay log
+ - the current relay log offset
+ - master log name
+ - master log sequence corresponding to the last update
+ - misc information specific to the SQL thread
+
+ st_relay_log_info is initialized from the slave.info file if such exists.
+ Otherwise, data members are intialized with defaults. The initialization is
+ done with init_relay_log_info() call.
+
+ The format of slave.info file:
+
+ relay_log_name
+ relay_log_pos
+ master_log_name
+ master_log_pos
+
+ To clean up, call end_relay_log_info()
+
+*****************************************************************************/
+
+typedef struct st_relay_log_info
+{
+ /*
+ If flag set, then rli does not store its state in any info file.
+ This is the case only when we execute BINLOG SQL commands inside
+ a client, non-replication thread.
+ */
+ bool no_storage;
+
+ /*** The following variables can only be read when protect by data lock ****/
+
+ /*
+ info_fd - file descriptor of the info file. set only during
+ initialization or clean up - safe to read anytime
+ cur_log_fd - file descriptor of the current read relay log
+ */
+ File info_fd,cur_log_fd;
+
+ /*
+ Protected with internal locks.
+ Must get data_lock when resetting the logs.
+ */
+ MYSQL_LOG relay_log;
+ LOG_INFO linfo;
+ IO_CACHE cache_buf,*cur_log;
+
+ /* The following variables are safe to read any time */
+
+ /* IO_CACHE of the info file - set only during init or end */
+ IO_CACHE info_file;
+
+ /*
+ When we restart slave thread we need to have access to the previously
+ created temporary tables. Modified only on init/end and by the SQL
+ thread, read only by SQL thread.
+ */
+ TABLE *save_temporary_tables;
+
+ /*
+ standard lock acquistion order to avoid deadlocks:
+ run_lock, data_lock, relay_log.LOCK_log, relay_log.LOCK_index
+ */
+ pthread_mutex_t data_lock,run_lock;
+
+ /*
+ start_cond is broadcast when SQL thread is started
+ stop_cond - when stopped
+ data_cond - when data protected by data_lock changes
+ */
+ pthread_cond_t start_cond, stop_cond, data_cond;
+
+ /* parent master info structure */
+ struct st_master_info *mi;
+
+ /*
+ Needed to deal properly with cur_log getting closed and re-opened with
+ a different log under our feet
+ */
+ uint32 cur_log_old_open_count;
+
+ /*
+ Let's call a group (of events) :
+ - a transaction
+ or
+ - an autocommiting query + its associated events (INSERT_ID,
+ TIMESTAMP...)
+ We need these rli coordinates :
+ - relay log name and position of the beginning of the group we currently are
+ executing. Needed to know where we have to restart when replication has
+ stopped in the middle of a group (which has been rolled back by the slave).
+ - relay log name and position just after the event we have just
+ executed. This event is part of the current group.
+ Formerly we only had the immediately above coordinates, plus a 'pending'
+ variable, but this dealt wrong with the case of a transaction starting on a
+ relay log and finishing (commiting) on another relay log. Case which can
+ happen when, for example, the relay log gets rotated because of
+ max_binlog_size.
+ */
+ char group_relay_log_name[FN_REFLEN];
+ ulonglong group_relay_log_pos;
+ char event_relay_log_name[FN_REFLEN];
+ ulonglong event_relay_log_pos;
+ ulonglong future_event_relay_log_pos;
+
+ /*
+ Original log name and position of the group we're currently executing
+ (whose coordinates are group_relay_log_name/pos in the relay log)
+ in the master's binlog. These concern the *group*, because in the master's
+ binlog the log_pos that comes with each event is the position of the
+ beginning of the group.
+ */
+ char group_master_log_name[FN_REFLEN];
+ volatile my_off_t group_master_log_pos;
+
+ /*
+ Handling of the relay_log_space_limit optional constraint.
+ ignore_log_space_limit is used to resolve a deadlock between I/O and SQL
+ threads, the SQL thread sets it to unblock the I/O thread and make it
+ temporarily forget about the constraint.
+ */
+ ulonglong log_space_limit,log_space_total;
+ bool ignore_log_space_limit;
+
+ /*
+ When it commits, InnoDB internally stores the master log position it has
+ processed so far; the position to store is the one of the end of the
+ committing event (the COMMIT query event, or the event if in autocommit
+ mode).
+ */
+#if MYSQL_VERSION_ID < 40100
+ ulonglong future_master_log_pos;
+#else
+ ulonglong future_group_master_log_pos;
+#endif
+
+ time_t last_master_timestamp;
+
+ /*
+ Needed for problems when slave stops and we want to restart it
+ skipping one or more events in the master log that have caused
+ errors, and have been manually applied by DBA already.
+ */
+ volatile uint32 slave_skip_counter;
+ volatile ulong abort_pos_wait; /* Incremented on change master */
+ volatile ulong slave_run_id; /* Incremented on slave start */
+ pthread_mutex_t log_space_lock;
+ pthread_cond_t log_space_cond;
+ THD * sql_thd;
+ int last_slave_errno;
+#ifndef DBUG_OFF
+ int events_till_abort;
+#endif
+ char last_slave_error[MAX_SLAVE_ERRMSG];
+
+ /* if not set, the value of other members of the structure are undefined */
+ bool inited;
+ volatile bool abort_slave;
+ volatile uint slave_running;
+
+ /*
+ Condition and its parameters from START SLAVE UNTIL clause.
+
+ UNTIL condition is tested with is_until_satisfied() method that is
+ called by exec_relay_log_event(). is_until_satisfied() caches the result
+ of the comparison of log names because log names don't change very often;
+ this cache is invalidated by parts of code which change log names with
+ notify_*_log_name_updated() methods. (They need to be called only if SQL
+ thread is running).
+ */
+
+ enum {UNTIL_NONE= 0, UNTIL_MASTER_POS, UNTIL_RELAY_POS} until_condition;
+ char until_log_name[FN_REFLEN];
+ ulonglong until_log_pos;
+ /* extension extracted from log_name and converted to int */
+ ulong until_log_name_extension;
+ /*
+ Cached result of comparison of until_log_name and current log name
+ -2 means unitialised, -1,0,1 are comarison results
+ */
+ enum
+ {
+ UNTIL_LOG_NAMES_CMP_UNKNOWN= -2, UNTIL_LOG_NAMES_CMP_LESS= -1,
+ UNTIL_LOG_NAMES_CMP_EQUAL= 0, UNTIL_LOG_NAMES_CMP_GREATER= 1
+ } until_log_names_cmp_result;
+
+ char cached_charset[6];
+ /*
+ trans_retries varies between 0 to slave_transaction_retries and counts how
+ many times the slave has retried the present transaction; gets reset to 0
+ when the transaction finally succeeds. retried_trans is a cumulative
+ counter: how many times the slave has retried a transaction (any) since
+ slave started.
+ */
+ ulong trans_retries, retried_trans;
+
+ /*
+ If the end of the hot relay log is made of master's events ignored by the
+ slave I/O thread, these two keep track of the coords (in the master's
+ binlog) of the last of these events seen by the slave I/O thread. If not,
+ ign_master_log_name_end[0] == 0.
+ As they are like a Rotate event read/written from/to the relay log, they
+ are both protected by rli->relay_log.LOCK_log.
+ */
+ char ign_master_log_name_end[FN_REFLEN];
+ ulonglong ign_master_log_pos_end;
+
+ st_relay_log_info();
+ ~st_relay_log_info();
+
+ /*
+ Invalidate cached until_log_name and group_relay_log_name comparison
+ result. Should be called after any update of group_realy_log_name if
+ there chances that sql_thread is running.
+ */
+ inline void notify_group_relay_log_name_update()
+ {
+ if (until_condition==UNTIL_RELAY_POS)
+ until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
+ }
+
+ /*
+ The same as previous but for group_master_log_name.
+ */
+ inline void notify_group_master_log_name_update()
+ {
+ if (until_condition==UNTIL_MASTER_POS)
+ until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
+ }
+
+ inline void inc_event_relay_log_pos()
+ {
+ event_relay_log_pos= future_event_relay_log_pos;
+ }
+
+ void inc_group_relay_log_pos(ulonglong log_pos,
+ bool skip_lock=0);
+
+ int wait_for_pos(THD* thd, String* log_name, longlong log_pos,
+ longlong timeout);
+ void close_temporary_tables();
+
+ /* Check if UNTIL condition is satisfied. See slave.cc for more. */
+ bool is_until_satisfied();
+ inline ulonglong until_pos()
+ {
+ return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_pos :
+ group_relay_log_pos);
+ }
+
+ table_mapping m_table_map;
+
+ /*
+ Last charset (6 bytes) seen by slave SQL thread is cached here; it helps
+ the thread save 3 get_charset() per Query_log_event if the charset is not
+ changing from event to event (common situation).
+ When the 6 bytes are equal to 0 is used to mean "cache is invalidated".
+ */
+ void cached_charset_invalidate();
+ bool cached_charset_compare(char *charset);
+
+ /*
+ To reload special tables when they are changes, we introduce a set
+ of functions that will mark whenever special functions need to be
+ called after modifying tables. Right now, the tables are either
+ ACL tables or grants tables.
+ */
+ enum enum_reload_flag
+ {
+ RELOAD_NONE_F = 0UL,
+ RELOAD_GRANT_F = (1UL << 0),
+ RELOAD_ACCESS_F = (1UL << 1)
+ };
+
+ ulong m_reload_flags;
+
+ void touching_table(char const* db, char const* table, ulong table_id);
+ void transaction_end(THD*);
+
+ void cleanup_context(THD *, bool);
+ time_t unsafe_to_stop_at;
+} RELAY_LOG_INFO;
+
+#endif /* RPL_RLI_H */
diff --git a/sql/rpl_tblmap.cc b/sql/rpl_tblmap.cc
new file mode 100644
index 00000000000..a0272b23ee8
--- /dev/null
+++ b/sql/rpl_tblmap.cc
@@ -0,0 +1,151 @@
+/* Copyright (C) 2005 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "mysql_priv.h"
+
+#ifdef HAVE_REPLICATION
+
+#include "rpl_tblmap.h"
+
+#define MAYBE_TABLE_NAME(T) ((T) ? (T)->s->table_name.str : "<>")
+#define TABLE_ID_HASH_SIZE 32
+#define TABLE_ID_CHUNK 256
+
+table_mapping::table_mapping()
+ : m_free(0)
+{
+ /*
+ No "free_element" function for entries passed here, as the entries are
+ allocated in a MEM_ROOT (freed as a whole in the destructor), they cannot
+ be freed one by one.
+ Note that below we don't test if hash_init() succeeded. This constructor
+ is called at startup only.
+ */
+ (void) hash_init(&m_table_ids,&my_charset_bin,TABLE_ID_HASH_SIZE,
+ offsetof(entry,table_id),sizeof(ulong),
+ 0,0,0);
+ /* We don't preallocate any block, this is consistent with m_free=0 above */
+ init_alloc_root(&m_mem_root, TABLE_ID_HASH_SIZE*sizeof(entry), 0);
+}
+
+table_mapping::~table_mapping()
+{
+ hash_free(&m_table_ids);
+ free_root(&m_mem_root, MYF(0));
+}
+
+st_table* table_mapping::get_table(ulong table_id)
+{
+ DBUG_ENTER("table_mapping::get_table(ulong)");
+ DBUG_PRINT("enter", ("table_id=%d", table_id));
+ entry *e= find_entry(table_id);
+ if (e)
+ {
+ DBUG_PRINT("info", ("tid %d -> table %p (%s)",
+ table_id, e->table,
+ MAYBE_TABLE_NAME(e->table)));
+ DBUG_RETURN(e->table);
+ }
+
+ DBUG_PRINT("info", ("tid %d is not mapped!", table_id));
+ DBUG_RETURN(NULL);
+}
+
+/*
+ Called when we are out of table id entries. Creates TABLE_ID_CHUNK
+ new entries, chain them and attach them at the head of the list of free
+ (free for use) entries.
+*/
+int table_mapping::expand()
+{
+ /*
+ If we wanted to use "tmp= new (&m_mem_root) entry[TABLE_ID_CHUNK]",
+ we would have to make "entry" derive from Sql_alloc but then it would not
+ be a POD anymore and we want it to be (see rpl_tblmap.h). So we allocate
+ in C.
+ */
+ entry *tmp= (entry *)alloc_root(&m_mem_root, TABLE_ID_CHUNK*sizeof(entry));
+ if (tmp == NULL)
+ return ERR_MEMORY_ALLOCATION; // Memory allocation failed
+
+ /* Find the end of this fresh new array of free entries */
+ entry *e_end= tmp+TABLE_ID_CHUNK-1;
+ for (entry *e= tmp; e < e_end; e++)
+ e->next= e+1;
+ e_end->next= m_free;
+ m_free= tmp;
+ return 0;
+}
+
+int table_mapping::set_table(ulong table_id, TABLE* table)
+{
+ DBUG_ENTER("table_mapping::set_table(ulong,TABLE*)");
+ DBUG_PRINT("enter", ("table_id=%d, table=%p (%s)",
+ table_id,
+ table, MAYBE_TABLE_NAME(table)));
+ entry *e= find_entry(table_id);
+ if (e == 0)
+ {
+ if (m_free == 0 && expand())
+ DBUG_RETURN(ERR_MEMORY_ALLOCATION); // Memory allocation failed
+ e= m_free;
+ m_free= m_free->next;
+ }
+ else
+ hash_delete(&m_table_ids,(byte *)e);
+
+ e->table_id= table_id;
+ e->table= table;
+ my_hash_insert(&m_table_ids,(byte *)e);
+
+ DBUG_PRINT("info", ("tid %d -> table %p (%s)",
+ table_id, e->table,
+ MAYBE_TABLE_NAME(e->table)));
+ DBUG_RETURN(0); // All OK
+}
+
+int table_mapping::remove_table(ulong table_id)
+{
+ entry *e= find_entry(table_id);
+ if (e)
+ {
+ hash_delete(&m_table_ids,(byte *)e);
+ /* we add this entry to the chain of free (free for use) entries */
+ e->next= m_free;
+ m_free= e;
+ return 0; // All OK
+ }
+ return 1; // No table to remove
+}
+
+/*
+ Puts all entries into the list of free-for-use entries (does not free any
+ memory), and empties the hash.
+*/
+void table_mapping::clear_tables()
+{
+ DBUG_ENTER("table_mapping::clear_tables()");
+ for (uint i= 0; i < m_table_ids.records; i++)
+ {
+ entry *e= (entry *)hash_element(&m_table_ids, i);
+ e->next= m_free;
+ m_free= e;
+ }
+ my_hash_reset(&m_table_ids);
+ DBUG_VOID_RETURN;
+}
+
+#endif
diff --git a/sql/rpl_tblmap.h b/sql/rpl_tblmap.h
new file mode 100644
index 00000000000..cfc2d7c2c6c
--- /dev/null
+++ b/sql/rpl_tblmap.h
@@ -0,0 +1,109 @@
+/* Copyright (C) 2005 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef TABLE_MAPPING_H
+#define TABLE_MAPPING_H
+
+/* Forward declarations */
+struct st_table;
+typedef st_table TABLE;
+
+/*
+ CLASS table_mapping
+
+ RESPONSIBILITIES
+ The table mapping is used to map table id's to table pointers
+
+ COLLABORATION
+ RELAY_LOG For mapping table id:s to tables when receiving events.
+ */
+
+/*
+ Guilhem to Mats:
+ in the table_mapping class, the memory is allocated and never freed (until
+ destruction). So this is a good candidate for allocating inside a MEM_ROOT:
+ it gives the efficient allocation in chunks (like in expand()). So I have
+ introduced a MEM_ROOT.
+
+ Note that inheriting from Sql_alloc had no effect: it has effects only when
+ "ptr= new table_mapping" is called, and this is never called. And it would
+ then allocate from thd->mem_root which is a highly volatile object (reset
+ from example after executing each query, see dispatch_command(), it has a
+ free_root() at end); as the table_mapping object is supposed to live longer
+ than a query, it was dangerous.
+ A dedicated MEM_ROOT needs to be used, see below.
+*/
+
+class table_mapping {
+
+private:
+ MEM_ROOT m_mem_root;
+
+public:
+
+ enum {
+ NO_TABLE = ULONG_MAX
+ };
+
+ enum enum_error {
+ ERR_NO_ERROR = 0,
+ ERR_LIMIT_EXCEEDED,
+ ERR_MEMORY_ALLOCATION
+ };
+
+ table_mapping();
+ ~table_mapping();
+
+ TABLE* get_table(ulong table_id);
+
+ int set_table(ulong table_id, TABLE* table);
+ int remove_table(ulong table_id);
+ void clear_tables();
+ ulong count() const { return m_table_ids.records; }
+
+private:
+ /*
+ This is a POD (Plain Old Data). Keep it that way (we apply offsetof() to
+ it, which only works for PODs)
+ */
+ struct entry {
+ ulong table_id;
+ union {
+ TABLE *table;
+ entry *next;
+ };
+ };
+
+ entry *find_entry(ulong table_id)
+ {
+ return (entry *)hash_search(&m_table_ids,
+ (byte*)&table_id,
+ sizeof(table_id));
+ }
+ int expand();
+
+ /*
+ Head of the list of free entries; "free" in the sense that it's an
+ allocated entry free for use, NOT in the sense that it's freed
+ memory.
+ */
+ entry *m_free;
+
+ /* Correspondance between an id (a number) and a TABLE object */
+ HASH m_table_ids;
+};
+
+#endif
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 990d8047009..01ff30045c4 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -619,6 +619,7 @@ sys_var_have_variable sys_have_query_cache("have_query_cache",
sys_var_have_variable sys_have_raid("have_raid", &have_raid);
sys_var_have_variable sys_have_rtree_keys("have_rtree_keys", &have_rtree_keys);
sys_var_have_variable sys_have_symlink("have_symlink", &have_symlink);
+sys_var_have_variable sys_have_row_based_replication("have_row_based_replication",&have_row_based_replication);
/* Global read-only variable describing server license */
sys_var_const_str sys_license("license", STRINGIFY_ARG(LICENSE));
@@ -643,6 +644,7 @@ struct show_var_st init_vars[]= {
{"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL},
{"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR},
{sys_binlog_cache_size.name,(char*) &sys_binlog_cache_size, SHOW_SYS},
+ {"binlog_format", (char*) &opt_binlog_format, SHOW_CHAR_PTR},
{sys_bulk_insert_buff_size.name,(char*) &sys_bulk_insert_buff_size,SHOW_SYS},
{sys_character_set_client.name,(char*) &sys_character_set_client, SHOW_SYS},
{sys_character_set_connection.name,(char*) &sys_character_set_connection,SHOW_SYS},
@@ -695,6 +697,7 @@ struct show_var_st init_vars[]= {
{sys_have_raid.name, (char*) &have_raid, SHOW_HAVE},
{sys_have_rtree_keys.name, (char*) &have_rtree_keys, SHOW_HAVE},
{sys_have_symlink.name, (char*) &have_symlink, SHOW_HAVE},
+ {sys_have_row_based_replication.name, (char*) &have_row_based_replication, SHOW_HAVE},
{"init_connect", (char*) &sys_init_connect, SHOW_SYS},
{"init_file", (char*) &opt_init_file, SHOW_CHAR_PTR},
{"init_slave", (char*) &sys_init_slave, SHOW_SYS},
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index aa5607c9f6a..ab9663db475 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5727,3 +5727,9 @@ ER_WRONG_VALUE
eng "Incorrect %-.32s value: '%-.128s'"
ER_NO_PARTITION_FOR_GIVEN_VALUE
eng "Table has no partition for value %ld"
+ER_BINLOG_ROW_LOGGING_FAILED
+ eng "Writing one row to the row-based binary log failed"
+ER_BINLOG_ROW_WRONG_TABLE_DEF
+ eng "Table definition on master and slave does not match"
+ER_BINLOG_ROW_RBR_TO_SBR
+ eng "Slave running with --log-slave-updates must use row-based binary logging to be able to replicate row-based binary log events"
diff --git a/sql/slave.cc b/sql/slave.cc
index 6c9cfc250c5..99bddb7b9b0 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -16,10 +16,9 @@
#include "mysql_priv.h"
-#ifdef HAVE_REPLICATION
-
#include <mysql.h>
#include <myisam.h>
+#include "rpl_rli.h"
#include "slave.h"
#include "sql_repl.h"
#include "rpl_filter.h"
@@ -28,6 +27,10 @@
#include <my_dir.h>
#include <sql_common.h>
+#ifdef HAVE_REPLICATION
+
+#include "rpl_tblmap.h"
+
#define MAX_SLAVE_RETRY_PAUSE 5
bool use_slave_mask = 0;
MY_BITMAP slave_error_mask;
@@ -48,8 +51,6 @@ ulonglong relay_log_space_limit = 0;
*/
int disconnect_slave_event_count = 0, abort_slave_event_count = 0;
-int events_till_abort = -1;
-static int events_till_disconnect = -1;
typedef enum { SLAVE_THD_IO, SLAVE_THD_SQL} SLAVE_THD_TYPE;
@@ -860,19 +861,48 @@ static bool sql_slave_killed(THD* thd, RELAY_LOG_INFO* rli)
{
DBUG_ASSERT(rli->sql_thd == thd);
DBUG_ASSERT(rli->slave_running == 1);// tracking buffer overrun
- return rli->abort_slave || abort_loop || thd->killed;
+ if (abort_loop || thd->killed || rli->abort_slave)
+ {
+ /*
+ If we are in an unsafe situation (stopping could corrupt replication),
+ we give one minute to the slave SQL thread of grace before really
+ terminating, in the hope that it will be able to read more events and
+ the unsafe situation will soon be left. Note that this one minute starts
+ from the last time anything happened in the slave SQL thread. So it's
+ really one minute of idleness, we don't timeout if the slave SQL thread
+ is actively working.
+ */
+ if (!rli->unsafe_to_stop_at)
+ return 1;
+ DBUG_PRINT("info", ("Slave SQL thread is in an unsafe situation, giving "
+ "it some grace period"));
+ if (difftime(time(0), rli->unsafe_to_stop_at) > 60)
+ {
+ slave_print_msg(ERROR_LEVEL, rli, 0,
+ "SQL thread had to stop in an unsafe situation, in "
+ "the middle of applying updates to a "
+ "non-transactional table without any primary key. "
+ "There is a risk of duplicate updates when the slave "
+ "SQL thread is restarted. Please check your tables' "
+ "contents after restart.");
+ return 1;
+ }
+ }
+ return 0;
}
/*
- Writes an error message to rli->last_slave_error and rli->last_slave_errno
- (which will be displayed by SHOW SLAVE STATUS), and prints it to stderr.
+ Writes a message to stderr, and if it's an error message, to
+ rli->last_slave_error and rli->last_slave_errno (which will be displayed by
+ SHOW SLAVE STATUS).
SYNOPSIS
- slave_print_error()
- rli
+ slave_print_msg()
+ level The severity level
+ rli
err_code The error code
- msg The error message (usually related to the error code, but can
+ msg The message (usually related to the error code, but can
contain more information).
... (this is printf-like format, with % symbols in msg)
@@ -880,22 +910,47 @@ static bool sql_slave_killed(THD* thd, RELAY_LOG_INFO* rli)
void
*/
-void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...)
+void slave_print_msg(enum loglevel level, RELAY_LOG_INFO* rli,
+ int err_code, const char* msg, ...)
{
+ void (*report_function)(const char *, ...);
+ char buff[MAX_SLAVE_ERRMSG], *pbuff= buff;
+ uint pbuffsize= sizeof(buff);
va_list args;
va_start(args,msg);
- my_vsnprintf(rli->last_slave_error,
- sizeof(rli->last_slave_error), msg, args);
- rli->last_slave_errno = err_code;
- /* If the error string ends with '.', do not add a ',' it would be ugly */
- if (rli->last_slave_error[0] &&
- (*(strend(rli->last_slave_error)-1) == '.'))
- sql_print_error("Slave: %s Error_code: %d", rli->last_slave_error,
- err_code);
+ switch (level)
+ {
+ case ERROR_LEVEL:
+ /*
+ This my_error call only has effect in client threads.
+ Slave threads do nothing in my_error().
+ */
+ my_error(ER_UNKNOWN_ERROR, MYF(0), msg);
+ /*
+ It's an error, it must be reported in Last_error and Last_errno in SHOW
+ SLAVE STATUS.
+ */
+ pbuff= rli->last_slave_error;
+ pbuffsize= sizeof(rli->last_slave_error);
+ rli->last_slave_errno = err_code;
+ report_function= sql_print_error;
+ break;
+ case WARNING_LEVEL:
+ report_function= sql_print_warning;
+ break;
+ case INFORMATION_LEVEL:
+ report_function= sql_print_information;
+ break;
+ default:
+ DBUG_ASSERT(0); // should not come here
+ return; // don't crash production builds, just do nothing
+ }
+ my_vsnprintf(pbuff, pbuffsize, msg, args);
+ /* If the msg string ends with '.', do not add a ',' it would be ugly */
+ if (pbuff[0] && (*(strend(pbuff)-1) == '.'))
+ (*report_function)("Slave: %s Error_code: %d", pbuff, err_code);
else
- sql_print_error("Slave: %s, Error_code: %d", rli->last_slave_error,
- err_code);
-
+ (*report_function)("Slave: %s, Error_code: %d", pbuff, err_code);
}
/*
@@ -919,7 +974,6 @@ bool net_request_file(NET* net, const char* fname)
DBUG_RETURN(net_write_command(net, 251, fname, strlen(fname), "", 0));
}
-
/*
From other comments and tests in code, it looks like
sometimes Query_log_event and Load_log_event can have db == 0
@@ -932,7 +986,6 @@ const char *print_slave_db_safe(const char* db)
return (db ? db : "");
}
-
static int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
const char *default_val)
{
@@ -1379,6 +1432,7 @@ static int init_relay_log_info(RELAY_LOG_INFO* rli,
const char* msg = 0;
int error = 0;
DBUG_ENTER("init_relay_log_info");
+ DBUG_ASSERT(!rli->no_storage); // Don't init if there is no storage
if (rli->inited) // Set if this function called
DBUG_RETURN(0);
@@ -1674,7 +1728,7 @@ static void write_ignored_events_info_to_relay_log(THD *thd, MASTER_INFO *mi)
if (rli->ign_master_log_name_end[0])
{
DBUG_PRINT("info",("writing a Rotate event to track down ignored events"));
- Rotate_log_event *ev= new Rotate_log_event(thd, rli->ign_master_log_name_end,
+ Rotate_log_event *ev= new Rotate_log_event(rli->ign_master_log_name_end,
0, rli->ign_master_log_pos_end,
Rotate_log_event::DUP_NAME);
rli->ign_master_log_name_end[0]= 0;
@@ -2241,17 +2295,17 @@ bool flush_master_info(MASTER_INFO* mi, bool flush_relay_log_cache)
st_relay_log_info::st_relay_log_info()
- :info_fd(-1), cur_log_fd(-1), save_temporary_tables(0),
+ :no_storage(FALSE), info_fd(-1), cur_log_fd(-1), save_temporary_tables(0),
cur_log_old_open_count(0), group_master_log_pos(0), log_space_total(0),
ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0),
abort_pos_wait(0), slave_run_id(0), sql_thd(0), last_slave_errno(0),
inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE),
- until_log_pos(0), retried_trans(0)
+ until_log_pos(0), retried_trans(0), m_reload_flags(RELOAD_NONE_F),
+ unsafe_to_stop_at(0)
{
group_relay_log_name[0]= event_relay_log_name[0]=
group_master_log_name[0]= 0;
last_slave_error[0]= until_log_name[0]= ign_master_log_name_end[0]= 0;
-
bzero((char*) &info_file, sizeof(info_file));
bzero((char*) &cache_buf, sizeof(cache_buf));
cached_charset_invalidate();
@@ -2671,11 +2725,9 @@ static ulong read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings)
/*
my_real_read() will time us out
We check if we were told to die, and if not, try reading again
-
- TODO: Move 'events_till_disconnect' to the MASTER_INFO structure
*/
#ifndef DBUG_OFF
- if (disconnect_slave_event_count && !(events_till_disconnect--))
+ if (disconnect_slave_event_count && !(mi->events_till_disconnect--))
return packet_error;
#endif
@@ -2950,7 +3002,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
thd->lex->current_select= 0;
if (!ev->when)
ev->when = time(NULL);
- ev->thd = thd;
+ ev->thd = thd; // because up to this point, ev->thd == 0
exec_res = ev->exec_event(rli);
DBUG_ASSERT(rli->sql_thd==thd);
/*
@@ -3022,7 +3074,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
else
{
pthread_mutex_unlock(&rli->data_lock);
- slave_print_error(rli, 0, "\
+ slave_print_msg(ERROR_LEVEL, rli, 0, "\
Could not parse relay log event entry. The possible reasons are: the master's \
binary log is corrupted (you can check this by running 'mysqlbinlog' on the \
binary log), the slave's relay log is corrupted (you can check this by running \
@@ -3051,9 +3103,6 @@ pthread_handler_t handle_slave_io(void *arg)
my_thread_init();
DBUG_ENTER("handle_slave_io");
-#ifndef DBUG_OFF
-slave_begin:
-#endif
DBUG_ASSERT(mi->inited);
mysql= NULL ;
retry_count= 0;
@@ -3063,7 +3112,7 @@ slave_begin:
mi->slave_run_id++;
#ifndef DBUG_OFF
- mi->events_till_abort = abort_slave_event_count;
+ mi->events_till_disconnect = disconnect_slave_event_count;
#endif
thd= new THD; // note that contructor of THD uses DBUG_ !
@@ -3301,14 +3350,6 @@ ignore_log_space_limit=%d",
log space");
goto err;
}
- // TODO: check debugging abort code
-#ifndef DBUG_OFF
- if (abort_slave_event_count && !--events_till_abort)
- {
- sql_print_error("Slave I/O thread: debugging abort");
- goto err;
- }
-#endif
}
}
@@ -3347,10 +3388,6 @@ err:
pthread_mutex_unlock(&LOCK_thread_count);
pthread_cond_broadcast(&mi->stop_cond); // tell the world we are done
pthread_mutex_unlock(&mi->run_lock);
-#ifndef DBUG_OFF
- if (abort_slave_event_count && !events_till_abort)
- goto slave_begin;
-#endif
my_thread_end();
pthread_exit(0);
DBUG_RETURN(0); // Can't return anything here
@@ -3370,10 +3407,6 @@ pthread_handler_t handle_slave_sql(void *arg)
my_thread_init();
DBUG_ENTER("handle_slave_sql");
-#ifndef DBUG_OFF
-slave_begin:
-#endif
-
DBUG_ASSERT(rli->inited);
pthread_mutex_lock(&rli->run_lock);
DBUG_ASSERT(!rli->slave_running);
@@ -3520,6 +3553,14 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
RPL_LOG_NAME, llstr(rli->group_master_log_pos,llbuff));
err:
+
+ /*
+ Some events set some playgrounds, which won't be cleared because thread
+ stops. Stopping of this thread may not be known to these events ("stop"
+ request is detected only by the present function, not by events), so we
+ must "proactively" clear playgrounds:
+ */
+ rli->cleanup_context(thd, 1);
VOID(pthread_mutex_lock(&LOCK_thread_count));
/*
Some extra safety, which should not been needed (normally, event deletion
@@ -3565,10 +3606,6 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
pthread_cond_broadcast(&rli->stop_cond);
// tell the world we are done
pthread_mutex_unlock(&rli->run_lock);
-#ifndef DBUG_OFF // TODO: reconsider the code below
- if (abort_slave_event_count && !rli->events_till_abort)
- goto slave_begin;
-#endif
my_thread_end();
pthread_exit(0);
DBUG_RETURN(0); // Can't return anything here
@@ -3721,7 +3758,7 @@ static int process_io_rotate(MASTER_INFO *mi, Rotate_log_event *rev)
rotate event forever, so we need to not disconnect after one.
*/
if (disconnect_slave_event_count)
- events_till_disconnect++;
+ mi->events_till_disconnect++;
#endif
/*
@@ -4177,7 +4214,7 @@ static int connect_to_master(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
DBUG_ENTER("connect_to_master");
#ifndef DBUG_OFF
- events_till_disconnect = disconnect_slave_event_count;
+ mi->events_till_disconnect = disconnect_slave_event_count;
#endif
ulong client_flag= CLIENT_REMEMBER_OPTIONS;
if (opt_slave_compressed_protocol)
@@ -4311,6 +4348,10 @@ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi,
bool flush_relay_log_info(RELAY_LOG_INFO* rli)
{
bool error=0;
+
+ if (unlikely(rli->no_storage))
+ return 0;
+
IO_CACHE *file = &rli->info_file;
char buff[FN_REFLEN*2+22*2+4], *pos;
@@ -4327,6 +4368,7 @@ bool flush_relay_log_info(RELAY_LOG_INFO* rli)
error=1;
if (flush_io_cache(file))
error=1;
+
/* Flushing the relay log is done by the slave I/O thread */
return error;
}
@@ -4357,7 +4399,7 @@ static IO_CACHE *reopen_relay_log(RELAY_LOG_INFO *rli, const char **errmsg)
}
-Log_event* next_event(RELAY_LOG_INFO* rli)
+static Log_event* next_event(RELAY_LOG_INFO* rli)
{
Log_event* ev;
IO_CACHE* cur_log = rli->cur_log;
@@ -4368,6 +4410,11 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
DBUG_ENTER("next_event");
DBUG_ASSERT(thd != 0);
+#ifndef DBUG_OFF
+ if (abort_slave_event_count && !rli->events_till_abort--)
+ DBUG_RETURN(0);
+#endif
+
/*
For most operations we need to protect rli members with data_lock,
so we assume calling function acquired this mutex for us and we will
@@ -4489,7 +4536,7 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
{
/* We generate and return a Rotate, to make our positions advance */
DBUG_PRINT("info",("seeing an ignored end segment"));
- ev= new Rotate_log_event(thd, rli->ign_master_log_name_end,
+ ev= new Rotate_log_event(rli->ign_master_log_name_end,
0, rli->ign_master_log_pos_end,
Rotate_log_event::DUP_NAME);
rli->ign_master_log_name_end[0]= 0;
@@ -4737,11 +4784,114 @@ end:
DBUG_VOID_RETURN;
}
+/*
+ Some system tables needed to be re-read by the MySQL server after it has
+ updated them; in statement-based replication, the GRANT and other commands
+ are sent verbatim to the slave which then reloads; in row-based replication,
+ changes to these tables are done through ordinary Rows binlog events, so
+ master must add some flag for the slave to know it has to reload the tables.
+*/
+struct st_reload_entry
+{
+ char const *table;
+ st_relay_log_info::enum_reload_flag flag;
+};
+
+/*
+ Sorted array of table names, please keep it sorted since we are
+ using bsearch() on it below.
+ */
+static st_reload_entry s_mysql_tables[] =
+{
+ { "columns_priv", st_relay_log_info::RELOAD_GRANT_F },
+ { "db", st_relay_log_info::RELOAD_ACCESS_F },
+ { "host", st_relay_log_info::RELOAD_ACCESS_F },
+ { "procs_priv", st_relay_log_info::RELOAD_GRANT_F },
+ { "tables_priv", st_relay_log_info::RELOAD_GRANT_F },
+ { "user", st_relay_log_info::RELOAD_ACCESS_F }
+};
+
+static const my_size_t s_mysql_tables_size =
+ sizeof(s_mysql_tables)/sizeof(*s_mysql_tables);
+
+static int reload_entry_compare(const void *lhs, const void *rhs)
+{
+ const char *lstr = static_cast<const char *>(lhs);
+ const char *rstr = static_cast<const st_reload_entry*>(rhs)->table;
+ return strcmp(lstr, rstr);
+}
+
+void st_relay_log_info::touching_table(char const* db, char const* table,
+ ulong table_id)
+{
+ if (strcmp(db,"mysql") == 0)
+ {
+#if defined(HAVE_BSEARCH) && defined(HAVE_SIZE_T)
+ void *const ptr= bsearch(table, s_mysql_tables,
+ s_mysql_tables_size,
+ sizeof(*s_mysql_tables), reload_entry_compare);
+ st_reload_entry const *const entry= static_cast<st_reload_entry*>(ptr);
+#else
+ /*
+ Fall back to full scan, there are few rows anyway and updating the
+ "mysql" database is rare.
+ */
+ st_reload_entry const *entry= s_mysql_tables;
+ for ( ; entry < s_mysql_tables + s_mysql_tables_size ; entry++)
+ if (reload_entry_compare(table, entry) == 0)
+ break;
+#endif
+ if (entry)
+ m_reload_flags|= entry->flag;
+ }
+}
+
+void st_relay_log_info::transaction_end(THD* thd)
+{
+ if (m_reload_flags != RELOAD_NONE_F)
+ {
+ if (m_reload_flags & RELOAD_ACCESS_F)
+ acl_reload(thd);
+
+ if (m_reload_flags & RELOAD_GRANT_F)
+ grant_reload(thd);
+
+ m_reload_flags= RELOAD_NONE_F;
+ }
+}
+
+#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+void st_relay_log_info::cleanup_context(THD *thd, bool error)
+{
+ DBUG_ASSERT(sql_thd == thd);
+ /*
+ 1) Instances of Table_map_log_event, if ::exec_event() was called on them,
+ may have opened tables, which we cannot be sure have been closed (because
+ maybe the Rows_log_event have not been found or will not be, because slave
+ SQL thread is stopping, or relay log has a missing tail etc). So we close
+ all thread's tables. And so the table mappings have to be cancelled.
+ 2) Rows_log_event::exec_event() may even have started statements or
+ transactions on them, which we need to rollback in case of error.
+ 3) If finding a Format_description_log_event after a BEGIN, we also need
+ to rollback before continuing with the next events.
+ 4) so we need this "context cleanup" function.
+ */
+ if (error)
+ {
+ ha_autocommit_or_rollback(thd, 1); // if a "statement transaction"
+ end_trans(thd, ROLLBACK); // if a "real transaction"
+ }
+ m_table_map.clear_tables();
+ close_thread_tables(thd);
+ unsafe_to_stop_at= 0;
+}
+#endif
+
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
template class I_List_iterator<i_string>;
template class I_List_iterator<i_string_pair>;
#endif
-
#endif /* HAVE_REPLICATION */
+
diff --git a/sql/slave.h b/sql/slave.h
index c994bfb2d34..6870aaca752 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -14,17 +14,19 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifdef HAVE_REPLICATION
-
#ifndef SLAVE_H
#define SLAVE_H
-#include "mysql.h"
+#ifdef HAVE_REPLICATION
+
+#include "log.h"
#include "my_list.h"
#include "rpl_filter.h"
+#include "rpl_tblmap.h"
+#include "rpl_rli.h"
#define SLAVE_NET_TIMEOUT 3600
-#define MAX_SLAVE_ERRMSG 1024
+
#define MAX_SLAVE_ERROR 2000
/*****************************************************************************
@@ -110,265 +112,7 @@ struct st_master_info;
#define MYSQL_SLAVE_RUN_NOT_CONNECT 1
#define MYSQL_SLAVE_RUN_CONNECT 2
-/****************************************************************************
-
- Replication SQL Thread
-
- st_relay_log_info contains:
- - the current relay log
- - the current relay log offset
- - master log name
- - master log sequence corresponding to the last update
- - misc information specific to the SQL thread
-
- st_relay_log_info is initialized from the slave.info file if such exists.
- Otherwise, data members are intialized with defaults. The initialization is
- done with init_relay_log_info() call.
-
- The format of slave.info file:
-
- relay_log_name
- relay_log_pos
- master_log_name
- master_log_pos
-
- To clean up, call end_relay_log_info()
-
-*****************************************************************************/
-
-typedef struct st_relay_log_info
-{
- /*** The following variables can only be read when protect by data lock ****/
-
- /*
- info_fd - file descriptor of the info file. set only during
- initialization or clean up - safe to read anytime
- cur_log_fd - file descriptor of the current read relay log
- */
- File info_fd,cur_log_fd;
-
- /*
- Protected with internal locks.
- Must get data_lock when resetting the logs.
- */
- MYSQL_LOG relay_log;
- LOG_INFO linfo;
- IO_CACHE cache_buf,*cur_log;
-
- /* The following variables are safe to read any time */
-
- /* IO_CACHE of the info file - set only during init or end */
- IO_CACHE info_file;
-
- /*
- When we restart slave thread we need to have access to the previously
- created temporary tables. Modified only on init/end and by the SQL
- thread, read only by SQL thread.
- */
- TABLE *save_temporary_tables;
-
- /*
- standard lock acquistion order to avoid deadlocks:
- run_lock, data_lock, relay_log.LOCK_log, relay_log.LOCK_index
- */
- pthread_mutex_t data_lock,run_lock;
-
- /*
- start_cond is broadcast when SQL thread is started
- stop_cond - when stopped
- data_cond - when data protected by data_lock changes
- */
- pthread_cond_t start_cond, stop_cond, data_cond;
-
- /* parent master info structure */
- struct st_master_info *mi;
-
- /*
- Needed to deal properly with cur_log getting closed and re-opened with
- a different log under our feet
- */
- uint32 cur_log_old_open_count;
-
- /*
- Let's call a group (of events) :
- - a transaction
- or
- - an autocommiting query + its associated events (INSERT_ID,
- TIMESTAMP...)
- We need these rli coordinates :
- - relay log name and position of the beginning of the group we currently are
- executing. Needed to know where we have to restart when replication has
- stopped in the middle of a group (which has been rolled back by the slave).
- - relay log name and position just after the event we have just
- executed. This event is part of the current group.
- Formerly we only had the immediately above coordinates, plus a 'pending'
- variable, but this dealt wrong with the case of a transaction starting on a
- relay log and finishing (commiting) on another relay log. Case which can
- happen when, for example, the relay log gets rotated because of
- max_binlog_size.
- */
- char group_relay_log_name[FN_REFLEN];
- ulonglong group_relay_log_pos;
- char event_relay_log_name[FN_REFLEN];
- ulonglong event_relay_log_pos;
- ulonglong future_event_relay_log_pos;
-
- /*
- Original log name and position of the group we're currently executing
- (whose coordinates are group_relay_log_name/pos in the relay log)
- in the master's binlog. These concern the *group*, because in the master's
- binlog the log_pos that comes with each event is the position of the
- beginning of the group.
- */
- char group_master_log_name[FN_REFLEN];
- volatile my_off_t group_master_log_pos;
-
- /*
- Handling of the relay_log_space_limit optional constraint.
- ignore_log_space_limit is used to resolve a deadlock between I/O and SQL
- threads, the SQL thread sets it to unblock the I/O thread and make it
- temporarily forget about the constraint.
- */
- ulonglong log_space_limit,log_space_total;
- bool ignore_log_space_limit;
-
- /*
- When it commits, InnoDB internally stores the master log position it has
- processed so far; the position to store is the one of the end of the
- committing event (the COMMIT query event, or the event if in autocommit
- mode).
- */
-#if MYSQL_VERSION_ID < 40100
- ulonglong future_master_log_pos;
-#else
- ulonglong future_group_master_log_pos;
-#endif
-
- time_t last_master_timestamp;
-
- /*
- Needed for problems when slave stops and we want to restart it
- skipping one or more events in the master log that have caused
- errors, and have been manually applied by DBA already.
- */
- volatile uint32 slave_skip_counter;
- volatile ulong abort_pos_wait; /* Incremented on change master */
- volatile ulong slave_run_id; /* Incremented on slave start */
- pthread_mutex_t log_space_lock;
- pthread_cond_t log_space_cond;
- THD * sql_thd;
- int last_slave_errno;
-#ifndef DBUG_OFF
- int events_till_abort;
-#endif
- char last_slave_error[MAX_SLAVE_ERRMSG];
-
- /* if not set, the value of other members of the structure are undefined */
- bool inited;
- volatile bool abort_slave;
- volatile uint slave_running;
-
- /*
- Condition and its parameters from START SLAVE UNTIL clause.
-
- UNTIL condition is tested with is_until_satisfied() method that is
- called by exec_relay_log_event(). is_until_satisfied() caches the result
- of the comparison of log names because log names don't change very often;
- this cache is invalidated by parts of code which change log names with
- notify_*_log_name_updated() methods. (They need to be called only if SQL
- thread is running).
- */
-
- enum {UNTIL_NONE= 0, UNTIL_MASTER_POS, UNTIL_RELAY_POS} until_condition;
- char until_log_name[FN_REFLEN];
- ulonglong until_log_pos;
- /* extension extracted from log_name and converted to int */
- ulong until_log_name_extension;
- /*
- Cached result of comparison of until_log_name and current log name
- -2 means unitialised, -1,0,1 are comarison results
- */
- enum
- {
- UNTIL_LOG_NAMES_CMP_UNKNOWN= -2, UNTIL_LOG_NAMES_CMP_LESS= -1,
- UNTIL_LOG_NAMES_CMP_EQUAL= 0, UNTIL_LOG_NAMES_CMP_GREATER= 1
- } until_log_names_cmp_result;
-
- char cached_charset[6];
- /*
- trans_retries varies between 0 to slave_transaction_retries and counts how
- many times the slave has retried the present transaction; gets reset to 0
- when the transaction finally succeeds. retried_trans is a cumulative
- counter: how many times the slave has retried a transaction (any) since
- slave started.
- */
- ulong trans_retries, retried_trans;
-
- /*
- If the end of the hot relay log is made of master's events ignored by the
- slave I/O thread, these two keep track of the coords (in the master's
- binlog) of the last of these events seen by the slave I/O thread. If not,
- ign_master_log_name_end[0] == 0.
- As they are like a Rotate event read/written from/to the relay log, they
- are both protected by rli->relay_log.LOCK_log.
- */
- char ign_master_log_name_end[FN_REFLEN];
- ulonglong ign_master_log_pos_end;
-
- st_relay_log_info();
- ~st_relay_log_info();
-
- /*
- Invalidate cached until_log_name and group_relay_log_name comparison
- result. Should be called after any update of group_realy_log_name if
- there chances that sql_thread is running.
- */
- inline void notify_group_relay_log_name_update()
- {
- if (until_condition==UNTIL_RELAY_POS)
- until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
- }
-
- /*
- The same as previous but for group_master_log_name.
- */
- inline void notify_group_master_log_name_update()
- {
- if (until_condition==UNTIL_MASTER_POS)
- until_log_names_cmp_result= UNTIL_LOG_NAMES_CMP_UNKNOWN;
- }
-
- inline void inc_event_relay_log_pos()
- {
- event_relay_log_pos= future_event_relay_log_pos;
- }
-
- void inc_group_relay_log_pos(ulonglong log_pos,
- bool skip_lock=0);
-
- int wait_for_pos(THD* thd, String* log_name, longlong log_pos,
- longlong timeout);
- void close_temporary_tables();
-
- /* Check if UNTIL condition is satisfied. See slave.cc for more. */
- bool is_until_satisfied();
- inline ulonglong until_pos()
- {
- return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_pos :
- group_relay_log_pos);
- }
- /*
- Last charset (6 bytes) seen by slave SQL thread is cached here; it helps
- the thread save 3 get_charset() per Query_log_event if the charset is not
- changing from event to event (common situation).
- When the 6 bytes are equal to 0 is used to mean "cache is invalidated".
- */
- void cached_charset_invalidate();
- bool cached_charset_compare(char *charset);
-} RELAY_LOG_INFO;
-
-
-Log_event* next_event(RELAY_LOG_INFO* rli);
+static Log_event* next_event(RELAY_LOG_INFO* rli);
/*****************************************************************************
@@ -427,7 +171,7 @@ typedef struct st_master_info
uint port;
uint connect_retry;
#ifndef DBUG_OFF
- int events_till_abort;
+ int events_till_disconnect;
#endif
bool inited;
volatile bool abort_slave;
@@ -474,17 +218,11 @@ typedef struct st_master_info
int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len);
-#define MAX_SLAVE_ERRMSG 1024
-
#define RPL_LOG_NAME (rli->group_master_log_name[0] ? rli->group_master_log_name :\
"FIRST")
#define IO_RPL_LOG_NAME (mi->master_log_name[0] ? mi->master_log_name :\
"FIRST")
-/* masks for start/stop operations on io and sql slave threads */
-#define SLAVE_IO 1
-#define SLAVE_SQL 2
-
/*
If the following is set, if first gives an error, second will be
tried. Otherwise, if first fails, we fail.
@@ -533,7 +271,8 @@ bool show_binlog_info(THD* thd);
const char *print_slave_db_safe(const char *db);
int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code);
void skip_load_data_infile(NET* net);
-void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...);
+void slave_print_msg(enum loglevel level, RELAY_LOG_INFO* rli,
+ int err_code, const char* msg, ...);
void end_slave(); /* clean up */
void init_master_info_with_options(MASTER_INFO* mi);
@@ -579,8 +318,12 @@ extern my_string master_ssl_ca, master_ssl_capath, master_ssl_cert,
extern I_List<THD> threads;
-#endif
-#else
+#endif /* HAVE_REPLICATION */
+
+/* masks for start/stop operations on io and sql slave threads */
#define SLAVE_IO 1
#define SLAVE_SQL 2
-#endif /* HAVE_REPLICATION */
+
+#endif
+
+
diff --git a/sql/sp.cc b/sql/sp.cc
index 81164131910..c85c1f2afef 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -585,14 +585,14 @@ db_create_routine(THD *thd, int type, sp_head *sp)
}
ret= SP_OK;
- if (table->file->write_row(table->record[0]))
+ if (table->file->ha_write_row(table->record[0]))
ret= SP_WRITE_ROW_FAILED;
else if (mysql_bin_log.is_open())
{
thd->clear_error();
/* Such a statement can always go directly to binlog, no trans cache */
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
}
}
@@ -618,7 +618,7 @@ db_drop_routine(THD *thd, int type, sp_name *name)
DBUG_RETURN(SP_OPEN_TABLE_FAILED);
if ((ret= db_find_routine_aux(thd, type, name, table)) == SP_OK)
{
- if (table->file->delete_row(table->record[0]))
+ if (table->file->ha_delete_row(table->record[0]))
ret= SP_DELETE_ROW_FAILED;
}
close_thread_tables(thd);
@@ -653,7 +653,7 @@ db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
table->field[MYSQL_PROC_FIELD_COMMENT]->store(chistics->comment.str,
chistics->comment.length,
system_charset_info);
- if ((table->file->update_row(table->record[1],table->record[0])))
+ if ((table->file->ha_update_row(table->record[1],table->record[0])))
ret= SP_WRITE_ROW_FAILED;
}
close_thread_tables(thd);
@@ -873,7 +873,7 @@ sp_drop_db_routines(THD *thd, char *db)
do
{
- if (! table->file->delete_row(table->record[0]))
+ if (! table->file->ha_delete_row(table->record[0]))
deleted= TRUE; /* We deleted something */
else
{
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 4a252fc4d86..63d1388473e 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -695,6 +695,9 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
/*
StoredRoutinesBinlogging
+ This paragraph applies only to statement-based binlogging. Row-based
+ binlogging does not need anything special like this.
+
Top-down overview:
1. Statements
@@ -1258,56 +1261,62 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
thd->spcont= nctx;
- binlog_save_options= thd->options;
- need_binlog_call= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
+ /*
+ If row-based binlogging, we don't need to binlog the function's call, let
+ each substatement be binlogged its way.
+ */
+ need_binlog_call= mysql_bin_log.is_open() &&
+ (thd->options & OPTION_BIN_LOG) && !binlog_row_based;
if (need_binlog_call)
{
reset_dynamic(&thd->user_var_events);
mysql_bin_log.start_union_events(thd);
+ binlog_save_options= thd->options;
+ thd->options&= ~OPTION_BIN_LOG;
}
-
- thd->options&= ~OPTION_BIN_LOG;
+
err_status= execute(thd);
- thd->options= binlog_save_options;
-
- if (need_binlog_call)
- mysql_bin_log.stop_union_events(thd);
- if (need_binlog_call && thd->binlog_evt_union.unioned_events)
+ if (need_binlog_call)
{
- char buf[256];
- String bufstr(buf, sizeof(buf), &my_charset_bin);
- bufstr.length(0);
- bufstr.append(STRING_WITH_LEN("DO "));
- append_identifier(thd, &bufstr, m_name.str, m_name.length);
- bufstr.append('(');
- for (uint i=0; i < argcount; i++)
- {
- String str_value_holder;
- String *str_value;
-
- if (i)
- bufstr.append(',');
-
- str_value= sp_get_item_value(param_values[i], &str_value_holder);
-
- if (str_value)
- bufstr.append(*str_value);
- else
- bufstr.append(STRING_WITH_LEN("NULL"));
- }
- bufstr.append(')');
-
- Query_log_event qinfo(thd, bufstr.ptr(), bufstr.length(),
- thd->binlog_evt_union.unioned_events_trans, FALSE);
- if (mysql_bin_log.write(&qinfo) &&
- thd->binlog_evt_union.unioned_events_trans)
+ mysql_bin_log.stop_union_events(thd);
+ thd->options= binlog_save_options;
+ if (thd->binlog_evt_union.unioned_events)
{
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
- "Invoked ROUTINE modified a transactional table but MySQL "
- "failed to reflect this change in the binary log");
+ char buf[256];
+ String bufstr(buf, sizeof(buf), &my_charset_bin);
+ bufstr.length(0);
+ bufstr.append(STRING_WITH_LEN("DO "));
+ append_identifier(thd, &bufstr, m_name.str, m_name.length);
+ bufstr.append('(');
+ for (uint i=0; i < argcount; i++)
+ {
+ String str_value_holder;
+ String *str_value;
+
+ if (i)
+ bufstr.append(',');
+
+ str_value= sp_get_item_value(param_values[i], &str_value_holder);
+
+ if (str_value)
+ bufstr.append(*str_value);
+ else
+ bufstr.append(STRING_WITH_LEN("NULL"));
+ }
+ bufstr.append(')');
+
+ Query_log_event qinfo(thd, bufstr.ptr(), bufstr.length(),
+ thd->binlog_evt_union.unioned_events_trans, FALSE);
+ if (mysql_bin_log.write(&qinfo) &&
+ thd->binlog_evt_union.unioned_events_trans)
+ {
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "Invoked ROUTINE modified a transactional table but MySQL "
+ "failed to reflect this change in the binary log");
+ }
+ reset_dynamic(&thd->user_var_events);
}
- reset_dynamic(&thd->user_var_events);
}
if (m_type == TYPE_ENUM_FUNCTION && !err_status)
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 5ee7bf8fd58..42e99bbd1bc 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1468,8 +1468,7 @@ bool change_password(THD *thd, const char *host, const char *user,
acl_user->host.hostname ? acl_user->host.hostname : "",
new_password));
thd->clear_error();
- Query_log_event qinfo(thd, buff, query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length, FALSE, FALSE);
}
end:
close_thread_tables(thd);
@@ -1654,7 +1653,7 @@ static bool update_user_table(THD *thd, TABLE *table,
}
store_record(table,record[1]);
table->field[2]->store(new_password, new_password_len, system_charset_info);
- if ((error=table->file->update_row(table->record[1],table->record[0])))
+ if ((error=table->file->ha_update_row(table->record[1],table->record[0])))
{
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
DBUG_RETURN(1);
@@ -1871,14 +1870,14 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
*/
table->file->ha_retrieve_all_cols();
if (cmp_record(table,record[1]) &&
- (error=table->file->update_row(table->record[1],table->record[0])))
+ (error=table->file->ha_update_row(table->record[1],table->record[0])))
{ // This should never happen
table->file->print_error(error,MYF(0)); /* purecov: deadcode */
error= -1; /* purecov: deadcode */
goto end; /* purecov: deadcode */
}
}
- else if ((error=table->file->write_row(table->record[0]))) // insert
+ else if ((error=table->file->ha_write_row(table->record[0]))) // insert
{ // This should never happen
if (error && error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE) /* purecov: inspected */
@@ -1988,16 +1987,17 @@ static int replace_db_table(TABLE *table, const char *db,
if (rights)
{
table->file->ha_retrieve_all_cols();
- if ((error=table->file->update_row(table->record[1],table->record[0])))
+ if ((error=table->file->ha_update_row(table->record[1],
+ table->record[0])))
goto table_error; /* purecov: deadcode */
}
else /* must have been a revoke of all privileges */
{
- if ((error = table->file->delete_row(table->record[1])))
+ if ((error = table->file->ha_delete_row(table->record[1])))
goto table_error; /* purecov: deadcode */
}
}
- else if (rights && (error=table->file->write_row(table->record[0])))
+ else if (rights && (error=table->file->ha_write_row(table->record[0])))
{
if (error && error != HA_ERR_FOUND_DUPP_KEY) /* purecov: inspected */
goto table_error; /* purecov: deadcode */
@@ -2365,9 +2365,9 @@ static int replace_column_table(GRANT_TABLE *g_t,
{
GRANT_COLUMN *grant_column;
if (privileges)
- error=table->file->update_row(table->record[1],table->record[0]);
+ error=table->file->ha_update_row(table->record[1],table->record[0]);
else
- error=table->file->delete_row(table->record[1]);
+ error=table->file->ha_delete_row(table->record[1]);
if (error)
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
@@ -2382,7 +2382,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
else // new grant
{
GRANT_COLUMN *grant_column;
- if ((error=table->file->write_row(table->record[0])))
+ if ((error=table->file->ha_write_row(table->record[0])))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
result= -1; /* purecov: inspected */
@@ -2434,8 +2434,8 @@ static int replace_column_table(GRANT_TABLE *g_t,
if (privileges)
{
int tmp_error;
- if ((tmp_error=table->file->update_row(table->record[1],
- table->record[0])))
+ if ((tmp_error=table->file->ha_update_row(table->record[1],
+ table->record[0])))
{ /* purecov: deadcode */
table->file->print_error(tmp_error,MYF(0)); /* purecov: deadcode */
result= -1; /* purecov: deadcode */
@@ -2447,7 +2447,7 @@ static int replace_column_table(GRANT_TABLE *g_t,
else
{
int tmp_error;
- if ((tmp_error = table->file->delete_row(table->record[1])))
+ if ((tmp_error = table->file->ha_delete_row(table->record[1])))
{ /* purecov: deadcode */
table->file->print_error(tmp_error,MYF(0)); /* purecov: deadcode */
result= -1; /* purecov: deadcode */
@@ -2555,15 +2555,15 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table,
{
if (store_table_rights || store_col_rights)
{
- if ((error=table->file->update_row(table->record[1],table->record[0])))
+ if ((error=table->file->ha_update_row(table->record[1],table->record[0])))
goto table_error; /* purecov: deadcode */
}
- else if ((error = table->file->delete_row(table->record[1])))
+ else if ((error = table->file->ha_delete_row(table->record[1])))
goto table_error; /* purecov: deadcode */
}
else
{
- error=table->file->write_row(table->record[0]);
+ error=table->file->ha_write_row(table->record[0]);
if (error && error != HA_ERR_FOUND_DUPP_KEY)
goto table_error; /* purecov: deadcode */
}
@@ -2672,15 +2672,15 @@ static int replace_routine_table(THD *thd, GRANT_NAME *grant_name,
{
if (store_proc_rights)
{
- if ((error=table->file->update_row(table->record[1],table->record[0])))
+ if ((error=table->file->ha_update_row(table->record[1],table->record[0])))
goto table_error;
}
- else if ((error= table->file->delete_row(table->record[1])))
+ else if ((error= table->file->ha_delete_row(table->record[1])))
goto table_error;
}
else
{
- error=table->file->write_row(table->record[0]);
+ error=table->file->ha_write_row(table->record[0]);
if (error && error != HA_ERR_FOUND_DUPP_KEY)
goto table_error;
}
@@ -3119,6 +3119,16 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
}
grant_option=TRUE;
thd->mem_root= old_root;
+ /*
+ This flush is here only becuase there is code that writes rows to
+ system tables after executing a binlog_query().
+
+ TODO: Ensure that no writes are executed after a binlog_query() by
+ moving the writes to before calling binlog_query(). Then remove
+ this line (and add an assert inside send_ok() that checks that
+ everything is in a consistent state).
+ */
+ thd->binlog_flush_pending_rows_event(true);
rw_unlock(&LOCK_grant);
if (!result && !no_error)
send_ok(thd);
@@ -4670,13 +4680,13 @@ static int modify_grant_table(TABLE *table, Field *host_field,
system_charset_info);
user_field->store(user_to->user.str, user_to->user.length,
system_charset_info);
- if ((error= table->file->update_row(table->record[1], table->record[0])))
+ if ((error= table->file->ha_update_row(table->record[1], table->record[0])))
table->file->print_error(error, MYF(0));
}
else
{
/* delete */
- if ((error=table->file->delete_row(table->record[0])))
+ if ((error=table->file->ha_delete_row(table->record[0])))
table->file->print_error(error, MYF(0));
}
@@ -5683,7 +5693,7 @@ void update_schema_privilege(TABLE *table, char *buff, const char* db,
table->field[i++]->store(column, col_length, cs);
table->field[i++]->store(priv, priv_length, cs);
table->field[i]->store(is_grantable, strlen(is_grantable), cs);
- table->file->write_row(table->record[0]);
+ table->file->ha_write_row(table->record[0]);
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 8f0f0d779e4..b9cd1afcd26 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1029,6 +1029,19 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
/* Fallthrough */
}
+ /*
+ For RBR: before calling close_thread_tables(), storage engines
+ should autocommit. Hence if there is a a pending event, it belongs
+ to a non-transactional engine, which writes directly to the table,
+ and should therefore be flushed before unlocking and closing the
+ tables. The test above for locked tables will not be triggered
+ since RBR locks and unlocks tables on a per-event basis.
+
+ TODO (WL#3023): Change the semantics so that RBR does not lock and
+ unlock tables on a per-event basis.
+ */
+ thd->binlog_flush_pending_rows_event(true);
+
if (thd->lock)
{
mysql_unlock_tables(thd, thd->lock);
@@ -1171,7 +1184,8 @@ void close_temporary_tables(THD *thd)
next=table->next;
close_temporary(table, 1, 1);
}
- if (query && found_user_tables && mysql_bin_log.is_open())
+ if (query && found_user_tables && mysql_bin_log.is_open() &&
+ !binlog_row_based) // CREATE TEMP TABLE not binlogged if row-based
{
/* The -1 is to remove last ',' */
thd->clear_error();
@@ -2038,6 +2052,8 @@ static bool reopen_table(TABLE *table)
tmp.keys_in_use_for_query= tmp.s->keys_in_use;
tmp.used_keys= tmp.s->keys_for_keyread;
+ tmp.s->table_map_id= table->s->table_map_id;
+
/* Get state */
tmp.in_use= thd;
tmp.reginfo.lock_type=table->reginfo.lock_type;
@@ -2343,6 +2359,48 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name)
/*
+ Function to assign a new table map id to a table.
+
+ PARAMETERS
+
+ table - Pointer to table structure
+
+ PRE-CONDITION(S)
+
+ table is non-NULL
+ The LOCK_open mutex is locked
+
+ POST-CONDITION(S)
+
+ table->s->table_map_id is given a value that with a high certainty
+ is not used by any other table.
+
+ table->s->table_map_id is not ULONG_MAX.
+ */
+static void assign_new_table_id(TABLE *table)
+{
+ static ulong last_table_id= ULONG_MAX;
+
+ DBUG_ENTER("assign_new_table_id(TABLE*)");
+
+ /* Preconditions */
+ DBUG_ASSERT(table != NULL);
+ safe_mutex_assert_owner(&LOCK_open);
+
+ ulong tid= ++last_table_id; /* get next id */
+ /* There is one reserved number that cannot be used. */
+ if (unlikely(tid == ULONG_MAX))
+ tid= ++last_table_id;
+ table->s->table_map_id= tid;
+ DBUG_PRINT("info", ("table_id=%lu", tid));
+
+ /* Post conditions */
+ DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
+
+ DBUG_VOID_RETURN;
+}
+
+/*
Load a table definition from file and open unireg table
SYNOPSIS
@@ -2490,7 +2548,21 @@ retry:
goto err;
break;
}
-
+
+ /*
+ We assign a new table id under the protection of the LOCK_open
+ mutex. We assign a new table id here instead of inside openfrm()
+ since that function can be used without acquiring any lock (e.g.,
+ inside ha_create_table()). Insted of creatint a new mutex and
+ using it for the sole purpose of serializing accesses to a static
+ variable, we assign the table id here.
+
+ CAVEAT. This means that the table cannot be used for
+ binlogging/replication purposes, unless open_table() has been called
+ directly or indirectly.
+ */
+ assign_new_table_id(entry);
+
if (Table_triggers_list::check_n_load(thd, share->db.str,
share->table_name.str, entry, 0))
{
@@ -2511,10 +2583,11 @@ retry:
uint query_buf_size= 20 + share->db.length + share->table_name.length +1;
if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME))))
{
+ /* this DELETE FROM is needed even with row-based binlogging */
end = strxmov(strmov(query, "DELETE FROM `"),
share->db.str,"`.`",share->table_name.str,"`", NullS);
- Query_log_event qinfo(thd, query, (ulong)(end-query), 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ query, (ulong)(end-query), FALSE, FALSE);
my_free(query, MYF(0));
}
else
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
new file mode 100644
index 00000000000..cc0e9714d85
--- /dev/null
+++ b/sql/sql_binlog.cc
@@ -0,0 +1,135 @@
+/* Copyright (C) 2005 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "mysql_priv.h"
+#include "base64.h"
+
+/*
+ Execute a BINLOG statement
+
+ TODO: This currently assumes a MySQL 5.x binlog.
+ When we'll have binlog with a different format, to execute the
+ BINLOG command properly the server will need to know which format
+ the BINLOG command's event is in. mysqlbinlog should then send
+ the Format_description_log_event of the binlog it reads and the
+ server thread should cache this format into
+ rli->description_event_for_exec.
+*/
+
+void mysql_client_binlog_statement(THD* thd)
+{
+ DBUG_PRINT("info",("binlog base64: '%*s'",
+ (thd->lex->comment.length < 2048 ?
+ thd->lex->comment.length : 2048),
+ thd->lex->comment.str));
+
+ /*
+ Temporarily turn off send_ok, since different events handle this
+ differently
+ */
+ my_bool nsok= thd->net.no_send_ok;
+ thd->net.no_send_ok= TRUE;
+
+ const my_size_t coded_len= thd->lex->comment.length + 1;
+ const my_size_t event_len= base64_needed_decoded_length(coded_len);
+ DBUG_ASSERT(coded_len > 0);
+
+ /*
+ Allocation
+ */
+ if (!thd->rli_fake)
+ thd->rli_fake= new RELAY_LOG_INFO;
+
+ const Format_description_log_event *desc=
+ new Format_description_log_event(4);
+
+ const char *error= 0;
+ char *buf= (char *) my_malloc(event_len, MYF(MY_WME));
+ Log_event *ev;
+ int res;
+
+ /*
+ Out of memory check
+ */
+ if (!(thd->rli_fake && desc && buf))
+ {
+ my_error(ER_OUTOFMEMORY, MYF(0), 1); /* needed 1 bytes */
+ goto end;
+ }
+
+ thd->rli_fake->sql_thd= thd;
+ thd->rli_fake->no_storage= TRUE;
+
+ res= base64_decode(thd->lex->comment.str, coded_len, buf);
+
+ DBUG_PRINT("info",("binlog base64 decoded_len=%d, event_len=%d\n",
+ res, uint4korr(buf + EVENT_LEN_OFFSET)));
+ /*
+ Note that 'res' is the correct event length, 'event_len' was
+ calculated based on the base64-string that possibly contained
+ extra spaces, so it can be longer than the real event.
+ */
+ if (res < EVENT_LEN_OFFSET
+ || (uint) res != uint4korr(buf+EVENT_LEN_OFFSET))
+ {
+ my_error(ER_SYNTAX_ERROR, MYF(0));
+ goto end;
+ }
+
+ ev= Log_event::read_log_event(buf, res, &error, desc);
+
+ DBUG_PRINT("info",("binlog base64 err=%s", error));
+ if (!ev)
+ {
+ /*
+ This could actually be an out-of-memory, but it is more
+ likely causes by a bad statement
+ */
+ my_error(ER_SYNTAX_ERROR, MYF(0));
+ goto end;
+ }
+
+ DBUG_PRINT("info",("ev->get_type_code()=%d", ev->get_type_code()));
+ DBUG_PRINT("info",("buf+EVENT_TYPE_OFFSET=%d", buf+EVENT_TYPE_OFFSET));
+
+ ev->thd= thd;
+ if (ev->exec_event(thd->rli_fake))
+ {
+ my_error(ER_UNKNOWN_ERROR, MYF(0), "Error executing BINLOG statement");
+ goto end;
+ }
+
+ /*
+ Restore setting of no_send_ok
+ */
+ thd->net.no_send_ok= nsok;
+
+ DBUG_PRINT("info",("binlog base64 execution finished successfully"));
+ send_ok(thd);
+
+end:
+ /*
+ Restore setting of no_send_ok
+ */
+ thd->net.no_send_ok= nsok;
+
+ if (ev)
+ delete ev;
+ if (desc)
+ delete desc;
+ if (buf)
+ my_free(buf, MYF(0));
+}
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index a28324c5e28..08d89228a72 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -27,6 +27,8 @@
#endif
#include "mysql_priv.h"
+#include <my_bitmap.h>
+#include "log_event.h"
#include <m_ctype.h>
#include <sys/stat.h>
#include <thr_alarm.h>
@@ -174,7 +176,7 @@ Open_tables_state::Open_tables_state(ulong version_arg)
THD::THD()
:Statement(CONVENTIONAL_EXECUTION, 0, ALLOC_ROOT_MIN_BLOCK_SIZE, 0),
- Open_tables_state(refresh_version),
+ Open_tables_state(refresh_version), rli_fake(0),
lock_id(&main_lock_id),
user_time(0), in_sub_stmt(0), global_read_lock(0), is_fatal_error(0),
rand_used(0), time_zone_used(0),
@@ -227,6 +229,9 @@ THD::THD()
ull=0;
system_thread= cleanup_done= abort_on_warning= no_warnings_for_error= 0;
peer_port= 0; // For SHOW PROCESSLIST
+#ifdef HAVE_ROW_BASED_REPLICATION
+ transaction.m_pending_rows_event= 0;
+#endif
#ifdef __WIN__
real_id = 0;
#endif
@@ -440,6 +445,11 @@ THD::~THD()
#ifndef DBUG_OFF
dbug_sentry= THD_SENTRY_GONE;
#endif
+#ifndef EMBEDDED_LIBRARY
+ if (rli_fake)
+ delete rli_fake;
+#endif
+
DBUG_VOID_RETURN;
}
@@ -1959,7 +1969,8 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
backup->client_capabilities= client_capabilities;
backup->savepoints= transaction.savepoints;
- if (!lex->requires_prelocking() || is_update_query(lex->sql_command))
+ if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) &&
+ !binlog_row_based)
options&= ~OPTION_BIN_LOG;
/* Disable result sets */
client_capabilities &= ~CLIENT_MULTI_RESULTS;
@@ -2101,3 +2112,439 @@ void xid_cache_delete(XID_STATE *xid_state)
pthread_mutex_unlock(&LOCK_xid_cache);
}
+/*
+ Implementation of interface to write rows to the binary log through the
+ thread. The thread is responsible for writing the rows it has
+ inserted/updated/deleted.
+*/
+
+#ifndef MYSQL_CLIENT
+#ifdef HAVE_ROW_BASED_REPLICATION
+
+/*
+ Template member function for ensuring that there is an rows log
+ event of the apropriate type before proceeding.
+
+ PRE CONDITION:
+ - Events of type 'RowEventT' have the type code 'type_code'.
+
+ POST CONDITION:
+ If a non-NULL pointer is returned, the pending event for thread 'thd' will
+ be an event of type 'RowEventT' (which have the type code 'type_code')
+ will either empty or have enough space to hold 'needed' bytes. In
+ addition, the columns bitmap will be correct for the row, meaning that
+ the pending event will be flushed if the columns in the event differ from
+ the columns suppled to the function.
+
+ RETURNS
+ If no error, a non-NULL pending event (either one which already existed or
+ the newly created one).
+ If error, NULL.
+ */
+
+template <class RowsEventT> Rows_log_event*
+THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
+ MY_BITMAP const* cols,
+ my_size_t colcnt,
+ my_size_t needed,
+ bool is_transactional)
+{
+ /* Pre-conditions */
+ DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
+
+ /* Fetch the type code for the RowsEventT template parameter */
+ int const type_code= RowsEventT::TYPE_CODE;
+
+ /*
+ There is no good place to set up the transactional data, so we
+ have to do it here.
+ */
+ if (binlog_setup_trx_data())
+ return NULL;
+
+ Rows_log_event* pending= binlog_get_pending_rows_event();
+
+ if (unlikely(pending && !pending->is_valid()))
+ return NULL;
+
+ /*
+ Check if the current event is non-NULL and a write-rows
+ event. Also check if the table provided is mapped: if it is not,
+ then we have switched to writing to a new table.
+ If there is no pending event, we need to create one. If there is a pending
+ event, but it's not about the same table id, or not of the same type
+ (between Write, Update and Delete), or not the same affected columns, or
+ going to be too big, flush this event to disk and create a new pending
+ event.
+ */
+ if (!pending ||
+ pending->server_id != serv_id ||
+ pending->get_table_id() != table->s->table_map_id ||
+ pending->get_type_code() != type_code ||
+ pending->get_data_size() + needed > opt_binlog_rows_event_max_size ||
+ pending->get_width() != colcnt ||
+ !bitmap_cmp(pending->get_cols(), cols))
+ {
+ /* Create a new RowsEventT... */
+ Rows_log_event* const
+ ev= new RowsEventT(this, table, table->s->table_map_id, cols,
+ is_transactional);
+ if (unlikely(!ev))
+ return NULL;
+ ev->server_id= serv_id; // I don't like this, it's too easy to forget.
+ /*
+ flush the pending event and replace it with the newly created
+ event...
+ */
+ if (unlikely(mysql_bin_log.flush_and_set_pending_rows_event(this, ev)))
+ {
+ delete ev;
+ return NULL;
+ }
+
+ return ev; /* This is the new pending event */
+ }
+ return pending; /* This is the current pending event */
+}
+
+/*
+ Instansiate the versions we need, we have -fno-implicit-template as
+ compiling option.
+*/
+template Rows_log_event*
+THD::binlog_prepare_pending_rows_event<Write_rows_log_event>
+(TABLE*, uint32, MY_BITMAP const*, my_size_t colcnt, size_t, bool);
+
+template Rows_log_event*
+THD::binlog_prepare_pending_rows_event<Delete_rows_log_event>
+(TABLE*, uint32, MY_BITMAP const*, my_size_t colcnt, size_t, bool);
+
+template Rows_log_event*
+THD::binlog_prepare_pending_rows_event<Update_rows_log_event>
+(TABLE*, uint32, MY_BITMAP const*, my_size_t colcnt, size_t, bool);
+
+static char const*
+field_type_name(enum_field_types type)
+{
+ switch (type)
+ {
+ case MYSQL_TYPE_DECIMAL:
+ return "MYSQL_TYPE_DECIMAL";
+ case MYSQL_TYPE_TINY:
+ return "MYSQL_TYPE_TINY";
+ case MYSQL_TYPE_SHORT:
+ return "MYSQL_TYPE_SHORT";
+ case MYSQL_TYPE_LONG:
+ return "MYSQL_TYPE_LONG";
+ case MYSQL_TYPE_FLOAT:
+ return "MYSQL_TYPE_FLOAT";
+ case MYSQL_TYPE_DOUBLE:
+ return "MYSQL_TYPE_DOUBLE";
+ case MYSQL_TYPE_NULL:
+ return "MYSQL_TYPE_NULL";
+ case MYSQL_TYPE_TIMESTAMP:
+ return "MYSQL_TYPE_TIMESTAMP";
+ case MYSQL_TYPE_LONGLONG:
+ return "MYSQL_TYPE_LONGLONG";
+ case MYSQL_TYPE_INT24:
+ return "MYSQL_TYPE_INT24";
+ case MYSQL_TYPE_DATE:
+ return "MYSQL_TYPE_DATE";
+ case MYSQL_TYPE_TIME:
+ return "MYSQL_TYPE_TIME";
+ case MYSQL_TYPE_DATETIME:
+ return "MYSQL_TYPE_DATETIME";
+ case MYSQL_TYPE_YEAR:
+ return "MYSQL_TYPE_YEAR";
+ case MYSQL_TYPE_NEWDATE:
+ return "MYSQL_TYPE_NEWDATE";
+ case MYSQL_TYPE_VARCHAR:
+ return "MYSQL_TYPE_VARCHAR";
+ case MYSQL_TYPE_BIT:
+ return "MYSQL_TYPE_BIT";
+ case MYSQL_TYPE_NEWDECIMAL:
+ return "MYSQL_TYPE_NEWDECIMAL";
+ case MYSQL_TYPE_ENUM:
+ return "MYSQL_TYPE_ENUM";
+ case MYSQL_TYPE_SET:
+ return "MYSQL_TYPE_SET";
+ case MYSQL_TYPE_TINY_BLOB:
+ return "MYSQL_TYPE_TINY_BLOB";
+ case MYSQL_TYPE_MEDIUM_BLOB:
+ return "MYSQL_TYPE_MEDIUM_BLOB";
+ case MYSQL_TYPE_LONG_BLOB:
+ return "MYSQL_TYPE_LONG_BLOB";
+ case MYSQL_TYPE_BLOB:
+ return "MYSQL_TYPE_BLOB";
+ case MYSQL_TYPE_VAR_STRING:
+ return "MYSQL_TYPE_VAR_STRING";
+ case MYSQL_TYPE_STRING:
+ return "MYSQL_TYPE_STRING";
+ case MYSQL_TYPE_GEOMETRY:
+ return "MYSQL_TYPE_GEOMETRY";
+ }
+ return "Unknown";
+}
+
+my_size_t THD::max_row_length_blob(TABLE *table, const byte *data) const
+{
+ my_size_t length= 0;
+ TABLE_SHARE *table_s= table->s;
+ uint* const beg= table_s->blob_field;
+ uint* const end= beg + table_s->blob_fields;
+
+ for (uint *ptr= beg ; ptr != end ; ++ptr)
+ {
+ Field_blob* const blob= (Field_blob*) table->field[*ptr];
+ length+= blob->get_length(data + blob->offset()) + 2;
+ }
+
+ return length;
+}
+
+my_size_t THD::pack_row(TABLE *table, MY_BITMAP const* cols, byte *row_data,
+ const byte *record) const
+{
+ Field **p_field= table->field, *field= *p_field;
+ int n_null_bytes= table->s->null_bytes;
+ my_ptrdiff_t const offset= record - (byte*) table->record[0];
+
+ memcpy(row_data, record, n_null_bytes);
+ byte *ptr= row_data+n_null_bytes;
+
+ for (int i= 0 ; field ; i++, p_field++, field= *p_field)
+ {
+ if (bitmap_is_set(cols,i))
+ ptr= field->pack(ptr, field->ptr + offset);
+ }
+
+ /*
+ my_ptrdiff_t is signed, size_t is unsigned. Assert that the
+ conversion will work correctly.
+ */
+ DBUG_ASSERT(ptr - row_data >= 0);
+ return (static_cast<size_t>(ptr - row_data));
+}
+
+int THD::binlog_write_row(TABLE* table, bool is_trans,
+ MY_BITMAP const* cols, my_size_t colcnt,
+ byte const *record)
+{
+ DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
+
+ /*
+ Pack records into format for transfer. We are allocating more
+ memory than needed, but that doesn't matter.
+ */
+ bool error= 0;
+ byte *row_data= table->write_row_record;
+ my_size_t const max_len= max_row_length(table, record);
+
+ /*
+ * Allocate room for a row (if needed)
+ */
+ if (!row_data)
+ {
+ if (!table->s->blob_fields)
+ {
+ /* multiply max_len by 2 so it can be used for update_row as well */
+ table->write_row_record= alloc_root(&table->mem_root, 2*max_len);
+ if (!table->write_row_record)
+ return HA_ERR_OUT_OF_MEM;
+ row_data= table->write_row_record;
+ }
+ else if (unlikely(!(row_data= my_malloc(max_len, MYF(MY_WME)))))
+ return HA_ERR_OUT_OF_MEM;
+ }
+ my_size_t const len= pack_row(table, cols, row_data, record);
+
+ Rows_log_event* const
+ ev= binlog_prepare_pending_rows_event<Write_rows_log_event>
+ (table, server_id, cols, colcnt, len, is_trans);
+
+ /* add_row_data copies row_data to internal buffer */
+ error= likely(ev != 0) ? ev->add_row_data(row_data,len) : HA_ERR_OUT_OF_MEM ;
+
+ if (table->write_row_record == 0)
+ my_free(row_data, MYF(MY_WME));
+
+ return error;
+}
+
+int THD::binlog_update_row(TABLE* table, bool is_trans,
+ MY_BITMAP const* cols, my_size_t colcnt,
+ const byte *before_record,
+ const byte *after_record)
+{
+ DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
+
+ bool error= 0;
+ my_size_t const before_maxlen = max_row_length(table, before_record);
+ my_size_t const after_maxlen = max_row_length(table, after_record);
+
+ byte *row_data= table->write_row_record;
+ byte *before_row, *after_row;
+ if (row_data != 0)
+ {
+ before_row= row_data;
+ after_row= before_row + before_maxlen;
+ }
+ else
+ {
+ if (unlikely(!(row_data= my_multi_malloc(MYF(MY_WME),
+ &before_row, before_maxlen,
+ &after_row, after_maxlen,
+ NULL))))
+ return HA_ERR_OUT_OF_MEM;
+ }
+
+ my_size_t const before_size= pack_row(table, cols, before_row,
+ before_record);
+ my_size_t const after_size= pack_row(table, cols, after_row,
+ after_record);
+
+ Rows_log_event* const
+ ev= binlog_prepare_pending_rows_event<Update_rows_log_event>
+ (table, server_id, cols, colcnt, before_size + after_size, is_trans);
+
+ error= (unlikely(!ev)) || ev->add_row_data(before_row, before_size) ||
+ ev->add_row_data(after_row, after_size);
+
+ if (!table->write_row_record)
+ {
+ /* add_row_data copies row_data to internal buffer */
+ my_free(row_data, MYF(MY_WME));
+ }
+
+ return error;
+}
+
+int THD::binlog_delete_row(TABLE* table, bool is_trans,
+ MY_BITMAP const* cols, my_size_t colcnt,
+ byte const *record)
+{
+ DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
+
+ /*
+ Pack records into format for transfer. We are allocating more
+ memory than needed, but that doesn't matter.
+ */
+ bool error= 0;
+ my_size_t const max_len= max_row_length(table, record);
+ byte *row_data= table->write_row_record;
+ if (!row_data && unlikely(!(row_data= my_malloc(max_len, MYF(MY_WME)))))
+ return HA_ERR_OUT_OF_MEM;
+ my_size_t const len= pack_row(table, cols, row_data, record);
+
+ Rows_log_event* const
+ ev= binlog_prepare_pending_rows_event<Delete_rows_log_event>
+ (table, server_id, cols, colcnt, len, is_trans);
+
+ error= (unlikely(!ev)) || ev->add_row_data(row_data, len);
+
+ /* add_row_data copies row_data */
+ if (table->write_row_record == 0)
+ my_free(row_data, MYF(MY_WME));
+
+ return error;
+}
+
+
+int THD::binlog_flush_pending_rows_event(bool stmt_end)
+{
+ DBUG_ENTER("THD::binlog_flush_pending_rows_event");
+ if (!binlog_row_based || !mysql_bin_log.is_open())
+ DBUG_RETURN(0);
+
+ /*
+ Mark the event as the last event of a statement if the stmt_end
+ flag is set.
+ */
+ int error= 0;
+ if (Rows_log_event *pending= binlog_get_pending_rows_event())
+ {
+ if (stmt_end)
+ {
+ pending->set_flags(Rows_log_event::STMT_END_F);
+ pending->flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
+ }
+
+ /*
+ We only bother to set the pending event if it is non-NULL. This
+ is essential for correctness, since there is not necessarily a
+ trx_data created for the thread if the pending event is NULL.
+ */
+ error= mysql_bin_log.flush_and_set_pending_rows_event(this, 0);
+ }
+
+ DBUG_RETURN(error);
+}
+
+
+void THD::binlog_delete_pending_rows_event()
+{
+ if (Rows_log_event *pending= binlog_get_pending_rows_event())
+ {
+ delete pending;
+ binlog_set_pending_rows_event(0);
+ }
+}
+
+#endif /* HAVE_ROW_BASED_REPLICATION */
+
+/*
+ Member function that will log query, either row-based or
+ statement-based depending on the value of the 'binlog_row_based'
+ variable and the value of the 'qtype' flag.
+
+ This function should be called after the all calls to ha_*_row()
+ functions have been issued, but before tables are unlocked and
+ closed.
+
+ RETURN VALUE
+ Error code, or 0 if no error.
+*/
+int THD::binlog_query(THD::enum_binlog_query_type qtype,
+ char const *query, ulong query_len,
+ bool is_trans, bool suppress_use)
+{
+ DBUG_ENTER("THD::binlog_query");
+ DBUG_ASSERT(query && mysql_bin_log.is_open());
+ int error= binlog_flush_pending_rows_event(true);
+ switch (qtype)
+ {
+ case THD::MYSQL_QUERY_TYPE:
+ /*
+ Using this query type is a conveniece hack, since we have been
+ moving back and forth between using RBR for replication of
+ system tables and not using it.
+
+ Make sure to change in check_table_binlog_row_based() according
+ to how you treat this.
+ */
+ case THD::ROW_QUERY_TYPE:
+ if (binlog_row_based)
+ DBUG_RETURN(binlog_flush_pending_rows_event(true));
+ /* Otherwise, we fall through */
+ case THD::STMT_QUERY_TYPE:
+ /*
+ Most callers of binlog_query() ignore the error code, assuming
+ that the statement will always be written to the binlog. In
+ case of error above, we therefore just continue and write the
+ statement to the binary log.
+ */
+ {
+ Query_log_event qinfo(this, query, query_len, is_trans, suppress_use);
+ qinfo.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
+ DBUG_RETURN(mysql_bin_log.write(&qinfo));
+ }
+ break;
+
+ case THD::QUERY_TYPE_COUNT:
+ default:
+ DBUG_ASSERT(0 <= qtype && qtype < QUERY_TYPE_COUNT);
+ }
+ DBUG_RETURN(0);
+}
+
+#endif /* !defined(MYSQL_CLIENT) */
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 60dc9a4cbad..1ef3322bc8f 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -21,19 +21,20 @@
#pragma interface /* gcc class implementation */
#endif
-// TODO: create log.h and move all the log header stuff there
+#include "log.h"
+#include "rpl_rli.h"
+#include "rpl_tblmap.h"
class Query_log_event;
class Load_log_event;
class Slave_log_event;
-class Format_description_log_event;
class sp_rcontext;
class sp_cache;
+class Rows_log_event;
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY, RNEXT_SAME };
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_UPDATE };
-enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN};
enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON,
DELAY_KEY_WRITE_ALL };
@@ -50,117 +51,6 @@ extern const char **errmesg;
#define TC_HEURISTIC_RECOVER_ROLLBACK 2
extern uint tc_heuristic_recover;
-/*
- Transaction Coordinator log - a base abstract class
- for two different implementations
-*/
-class TC_LOG
-{
- public:
- int using_heuristic_recover();
- TC_LOG() {}
- virtual ~TC_LOG() {}
-
- virtual int open(const char *opt_name)=0;
- virtual void close()=0;
- virtual int log(THD *thd, my_xid xid)=0;
- virtual void unlog(ulong cookie, my_xid xid)=0;
-};
-
-class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
-{
- public:
- int open(const char *opt_name) { return 0; }
- void close() { }
- int log(THD *thd, my_xid xid) { return 1; }
- void unlog(ulong cookie, my_xid xid) { }
-};
-
-#ifdef HAVE_MMAP
-class TC_LOG_MMAP: public TC_LOG
-{
- public: // only to keep Sun Forte on sol9x86 happy
- typedef enum {
- POOL, // page is in pool
- ERROR, // last sync failed
- DIRTY // new xids added since last sync
- } PAGE_STATE;
-
- private:
- typedef struct st_page {
- struct st_page *next; // page a linked in a fifo queue
- my_xid *start, *end; // usable area of a page
- my_xid *ptr; // next xid will be written here
- int size, free; // max and current number of free xid slots on the page
- int waiters; // number of waiters on condition
- PAGE_STATE state; // see above
- pthread_mutex_t lock; // to access page data or control structure
- pthread_cond_t cond; // to wait for a sync
- } PAGE;
-
- char logname[FN_REFLEN];
- File fd;
- my_off_t file_length;
- uint npages, inited;
- uchar *data;
- struct st_page *pages, *syncing, *active, *pool, *pool_last;
- /*
- note that, e.g. LOCK_active is only used to protect
- 'active' pointer, to protect the content of the active page
- one has to use active->lock.
- Same for LOCK_pool and LOCK_sync
- */
- pthread_mutex_t LOCK_active, LOCK_pool, LOCK_sync;
- pthread_cond_t COND_pool, COND_active;
-
- public:
- TC_LOG_MMAP(): inited(0) {}
- int open(const char *opt_name);
- void close();
- int log(THD *thd, my_xid xid);
- void unlog(ulong cookie, my_xid xid);
- int recover();
-
- private:
- void get_active_from_pool();
- int sync();
- int overflow();
-};
-#else
-#define TC_LOG_MMAP TC_LOG_DUMMY
-#endif
-
-extern TC_LOG *tc_log;
-extern TC_LOG_MMAP tc_log_mmap;
-extern TC_LOG_DUMMY tc_log_dummy;
-
-/* log info errors */
-#define LOG_INFO_EOF -1
-#define LOG_INFO_IO -2
-#define LOG_INFO_INVALID -3
-#define LOG_INFO_SEEK -4
-#define LOG_INFO_MEM -6
-#define LOG_INFO_FATAL -7
-#define LOG_INFO_IN_USE -8
-
-/* bitmap to SQL_LOG::close() */
-#define LOG_CLOSE_INDEX 1
-#define LOG_CLOSE_TO_BE_OPENED 2
-#define LOG_CLOSE_STOP_EVENT 4
-
-struct st_relay_log_info;
-
-typedef struct st_log_info
-{
- char log_file_name[FN_REFLEN];
- my_off_t index_file_offset, index_file_start_offset;
- my_off_t pos;
- bool fatal; // if the purge happens to give us a negative offset
- pthread_mutex_t lock;
- st_log_info():fatal(0) { pthread_mutex_init(&lock, MY_MUTEX_INIT_FAST);}
- ~st_log_info() { pthread_mutex_destroy(&lock);}
-} LOG_INFO;
-
typedef struct st_user_var_events
{
user_var_entry *user_var_event;
@@ -173,188 +63,6 @@ typedef struct st_user_var_events
#define RP_LOCK_LOG_IS_ALREADY_LOCKED 1
#define RP_FORCE_ROTATE 2
-class Log_event;
-
-/*
- TODO split MYSQL_LOG into base MYSQL_LOG and
- MYSQL_QUERY_LOG, MYSQL_SLOW_LOG, MYSQL_BIN_LOG
- most of the code from MYSQL_LOG should be in the MYSQL_BIN_LOG
- only (TC_LOG included)
-
- TODO use mmap instead of IO_CACHE for binlog
- (mmap+fsync is two times faster than write+fsync)
-*/
-
-class MYSQL_LOG: public TC_LOG
-{
- private:
- /* LOCK_log and LOCK_index are inited by init_pthread_objects() */
- pthread_mutex_t LOCK_log, LOCK_index;
- pthread_mutex_t LOCK_prep_xids;
- pthread_cond_t COND_prep_xids;
- pthread_cond_t update_cond;
- ulonglong bytes_written;
- time_t last_time,query_start;
- IO_CACHE log_file;
- IO_CACHE index_file;
- char *name;
- char time_buff[20],db[NAME_LEN+1];
- char log_file_name[FN_REFLEN],index_file_name[FN_REFLEN];
- /*
- The max size before rotation (usable only if log_type == LOG_BIN: binary
- logs and relay logs).
- For a binlog, max_size should be max_binlog_size.
- For a relay log, it should be max_relay_log_size if this is non-zero,
- max_binlog_size otherwise.
- max_size is set in init(), and dynamically changed (when one does SET
- GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and
- fix_max_relay_log_size).
- */
- ulong max_size;
- ulong prepared_xids; /* for tc log - number of xids to remember */
- volatile enum_log_type log_type;
- enum cache_type io_cache_type;
- // current file sequence number for load data infile binary logging
- uint file_id;
- uint open_count; // For replication
- int readers_count;
- bool write_error, inited;
- bool need_start_event;
- /*
- no_auto_events means we don't want any of these automatic events :
- Start/Rotate/Stop. That is, in 4.x when we rotate a relay log, we don't
- want a Rotate_log event to be written to the relay log. When we start a
- relay log etc. So in 4.x this is 1 for relay logs, 0 for binlogs.
- In 5.0 it's 0 for relay logs too!
- */
- bool no_auto_events;
- friend class Log_event;
-
-public:
- /*
- These describe the log's format. This is used only for relay logs.
- _for_exec is used by the SQL thread, _for_queue by the I/O thread. It's
- necessary to have 2 distinct objects, because the I/O thread may be reading
- events in a different format from what the SQL thread is reading (consider
- the case of a master which has been upgraded from 5.0 to 5.1 without doing
- RESET MASTER, or from 4.x to 5.0).
- */
- Format_description_log_event *description_event_for_exec,
- *description_event_for_queue;
-
- MYSQL_LOG();
- /*
- note that there's no destructor ~MYSQL_LOG() !
- The reason is that we don't want it to be automatically called
- on exit() - but only during the correct shutdown process
- */
-
- int open(const char *opt_name);
- void close();
- int log(THD *thd, my_xid xid);
- void unlog(ulong cookie, my_xid xid);
- int recover(IO_CACHE *log, Format_description_log_event *fdle);
- void reset_bytes_written()
- {
- bytes_written = 0;
- }
- void harvest_bytes_written(ulonglong* counter)
- {
-#ifndef DBUG_OFF
- char buf1[22],buf2[22];
-#endif
- DBUG_ENTER("harvest_bytes_written");
- (*counter)+=bytes_written;
- DBUG_PRINT("info",("counter: %s bytes_written: %s", llstr(*counter,buf1),
- llstr(bytes_written,buf2)));
- bytes_written=0;
- DBUG_VOID_RETURN;
- }
- void set_max_size(ulong max_size_arg);
- void signal_update();
- void wait_for_update(THD* thd, bool master_or_slave);
- void set_need_start_event() { need_start_event = 1; }
- void init(enum_log_type log_type_arg,
- enum cache_type io_cache_type_arg,
- bool no_auto_events_arg, ulong max_size);
- void init_pthread_objects();
- void cleanup();
- bool open(const char *log_name,
- enum_log_type log_type,
- const char *new_name,
- enum cache_type io_cache_type_arg,
- bool no_auto_events_arg, ulong max_size,
- bool null_created);
- const char *generate_name(const char *log_name, const char *suffix,
- bool strip_ext, char *buff);
- /* simplified open_xxx wrappers for the gigantic open above */
- bool open_query_log(const char *log_name)
- {
- char buf[FN_REFLEN];
- return open(generate_name(log_name, ".log", 0, buf),
- LOG_NORMAL, 0, WRITE_CACHE, 0, 0, 0);
- }
- bool open_slow_log(const char *log_name)
- {
- char buf[FN_REFLEN];
- return open(generate_name(log_name, "-slow.log", 0, buf),
- LOG_NORMAL, 0, WRITE_CACHE, 0, 0, 0);
- }
- bool open_index_file(const char *index_file_name_arg,
- const char *log_name);
- void new_file(bool need_lock);
- bool write(THD *thd, enum enum_server_command command,
- const char *format,...);
- bool write(THD *thd, const char *query, uint query_length,
- time_t query_start=0);
- bool write(Log_event* event_info); // binary log write
- bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event);
-
- void start_union_events(THD *thd);
- void stop_union_events(THD *thd);
- bool is_query_in_union(THD *thd, query_id_t query_id_param);
-
- /*
- v stands for vector
- invoked as appendv(buf1,len1,buf2,len2,...,bufn,lenn,0)
- */
- bool appendv(const char* buf,uint len,...);
- bool append(Log_event* ev);
-
- int generate_new_name(char *new_name,const char *old_name);
- void make_log_name(char* buf, const char* log_ident);
- bool is_active(const char* log_file_name);
- int update_log_index(LOG_INFO* linfo, bool need_update_threads);
- void rotate_and_purge(uint flags);
- bool flush_and_sync();
- int purge_logs(const char *to_log, bool included,
- bool need_mutex, bool need_update_threads,
- ulonglong *decrease_log_space);
- int purge_logs_before_date(time_t purge_time);
- int purge_first_log(struct st_relay_log_info* rli, bool included);
- bool reset_logs(THD* thd);
- void close(uint exiting);
-
- // iterating through the log index file
- int find_log_pos(LOG_INFO* linfo, const char* log_name,
- bool need_mutex);
- int find_next_log(LOG_INFO* linfo, bool need_mutex);
- int get_current_log(LOG_INFO* linfo);
- uint next_file_id();
- inline bool is_open() { return log_type != LOG_CLOSED; }
- inline char* get_index_fname() { return index_file_name;}
- inline char* get_log_fname() { return log_file_name; }
- inline char* get_name() { return name; }
- inline pthread_mutex_t* get_log_lock() { return &LOCK_log; }
- inline IO_CACHE* get_log_file() { return &log_file; }
-
- inline void lock_index() { pthread_mutex_lock(&LOCK_index);}
- inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);}
- inline IO_CACHE *get_index_file() { return &index_file;}
- inline uint32 get_open_count() { return open_count; }
-};
-
-
typedef struct st_copy_info {
ha_rows records;
ha_rows deleted;
@@ -461,28 +169,6 @@ public:
#include "sql_lex.h" /* Must be here */
-/* Needed to be able to have an I_List of char* strings in mysqld.cc. */
-
-class i_string: public ilink
-{
-public:
- const char* ptr;
- i_string():ptr(0) { }
- i_string(const char* s) : ptr(s) {}
-};
-
-/* needed for linked list of two strings for replicate-rewrite-db */
-class i_string_pair: public ilink
-{
-public:
- const char* key;
- const char* val;
- i_string_pair():key(0),val(0) { }
- i_string_pair(const char* key_arg, const char* val_arg) :
- key(key_arg),val(val_arg) {}
-};
-
-
class delayed_insert;
class select_result;
@@ -1102,6 +788,9 @@ class THD :public Statement,
public Open_tables_state
{
public:
+ /* Used to execute base64 coded binlog events in MySQL server */
+ RELAY_LOG_INFO* rli_fake;
+
/*
Constant for THD::where initialization in the beginning of every query.
@@ -1206,12 +895,96 @@ public:
/* container for handler's private per-connection data */
void *ha_data[MAX_HA];
+
+#ifdef HAVE_ROW_BASED_REPLICATION
+#ifndef MYSQL_CLIENT
+
+ /*
+ Public interface to write rows to the binlog
+ */
+ int binlog_write_row(TABLE* table, bool is_transactional,
+ MY_BITMAP const* cols, my_size_t colcnt,
+ const byte *buf);
+ int binlog_delete_row(TABLE* table, bool is_transactional,
+ MY_BITMAP const* cols, my_size_t colcnt,
+ const byte *buf);
+ int binlog_update_row(TABLE* table, bool is_transactional,
+ MY_BITMAP const* cols, my_size_t colcnt,
+ const byte *old_data, const byte *new_data);
+
+ void set_server_id(uint32 sid) { server_id = sid; }
+
+ /*
+ Member functions to handle pending event for row-level logging.
+ */
+ template <class RowsEventT> Rows_log_event*
+ binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
+ MY_BITMAP const* cols,
+ my_size_t colcnt,
+ my_size_t needed,
+ bool is_transactional);
+ Rows_log_event* binlog_get_pending_rows_event() const;
+ void binlog_set_pending_rows_event(Rows_log_event* ev);
+ int binlog_setup_trx_data();
+
+ my_size_t max_row_length_blob(TABLE* table, const byte *data) const;
+ my_size_t max_row_length(TABLE* table, const byte *data) const
+ {
+ TABLE_SHARE *table_s= table->s;
+ my_size_t length= table_s->reclength + 2 * table_s->fields;
+ if (table_s->blob_fields == 0)
+ return length;
+
+ return (length+max_row_length_blob(table,data));
+ }
+
+ my_size_t pack_row(TABLE* table, MY_BITMAP const* cols, byte *row_data,
+ const byte *data) const;
+
+ int binlog_flush_pending_rows_event(bool stmt_end);
+ void binlog_delete_pending_rows_event();
+
+#endif
+#endif /* HAVE_ROW_BASED_REPLICATION */
+#ifndef MYSQL_CLIENT
+ enum enum_binlog_query_type {
+ /*
+ The query can be logged row-based or statement-based
+ */
+ ROW_QUERY_TYPE,
+
+ /*
+ The query has to be logged statement-based
+ */
+ STMT_QUERY_TYPE,
+
+ /*
+ The query represents a change to a table in the "mysql"
+ database and is currently mapped to ROW_QUERY_TYPE.
+ */
+ MYSQL_QUERY_TYPE,
+ QUERY_TYPE_COUNT
+ };
+
+ int binlog_query(enum_binlog_query_type qtype,
+ char const *query, ulong query_len,
+ bool is_trans, bool suppress_use);
+#endif
+
+public:
+
struct st_transactions {
SAVEPOINT *savepoints;
THD_TRANS all; // Trans since BEGIN WORK
THD_TRANS stmt; // Trans for current statement
bool on; // see ha_enable_transaction()
+ XID xid; // transaction identifier
+ enum xa_states xa_state; // used by external XA only
XID_STATE xid_state;
+#ifdef HAVE_ROW_BASED_REPLICATION
+ Rows_log_event *m_pending_rows_event;
+#endif
+
/*
Tables changed in transaction (that must be invalidated in query cache).
List contain only transactional tables, that not invalidated in query
@@ -1768,6 +1541,7 @@ class select_create: public select_insert {
HA_CREATE_INFO *create_info;
MYSQL_LOCK *lock;
Field **field;
+ bool create_table_written;
public:
select_create (TABLE_LIST *table,
HA_CREATE_INFO *create_info_par,
@@ -1776,9 +1550,11 @@ public:
List<Item> &select_fields,enum_duplicates duplic, bool ignore)
:select_insert (NULL, NULL, &select_fields, 0, 0, duplic, ignore), create_table(table),
extra_fields(&fields_par),keys(&keys_par), create_info(create_info_par),
- lock(0)
+ lock(0), create_table_written(FALSE)
{}
int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
+
+ void binlog_show_create_table();
void store_values(List<Item> &values);
void send_error(uint errcode,const char *err);
bool send_eof();
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index a9c3504250e..745139924ab 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -40,6 +40,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
ha_rows deleted;
uint usable_index= MAX_KEY;
SELECT_LEX *select_lex= &thd->lex->select_lex;
+ bool ha_delete_row_bypassed= 0;
DBUG_ENTER("mysql_delete");
if (open_and_lock_tables(thd, table_list))
@@ -77,15 +78,18 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
!(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
!(table->triggers && table->triggers->has_delete_triggers()))
{
- deleted= table->file->records;
+ ha_rows const maybe_deleted= table->file->records;
if (!(error=table->file->delete_all_rows()))
{
error= -1; // ok
+ deleted= maybe_deleted;
+ ha_delete_row_bypassed= 1;
goto cleanup;
}
if (error != HA_ERR_WRONG_COMMAND)
{
table->file->print_error(error,MYF(0));
+ ha_delete_row_bypassed= 1;
error=0;
goto cleanup;
}
@@ -211,7 +215,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
break;
}
- if (!(error= table->file->delete_row(table->record[0])))
+ if (!(error= table->file->ha_delete_row(table->record[0])))
{
deleted++;
if (table->triggers &&
@@ -293,10 +297,24 @@ cleanup:
{
if (error < 0)
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_table, FALSE);
- if (mysql_bin_log.write(&qinfo) && transactional_table)
+
+ /*
+ If 'handler::delete_all_rows()' was called, we replicate
+ statement-based; otherwise, 'ha_delete_row()' was used to
+ delete specific rows which we might log row-based.
+ */
+ THD::enum_binlog_query_type const
+ query_type(ha_delete_row_bypassed ?
+ THD::STMT_QUERY_TYPE :
+ THD::ROW_QUERY_TYPE);
+ int log_result= thd->binlog_query(query_type,
+ thd->query, thd->query_length,
+ transactional_table, FALSE);
+
+ if (log_result && transactional_table)
+ {
error=1;
+ }
}
if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
@@ -592,7 +610,7 @@ bool multi_delete::send_data(List<Item> &values)
TRG_ACTION_BEFORE, FALSE))
DBUG_RETURN(1);
table->status|= STATUS_DELETED;
- if (!(error=table->file->delete_row(table->record[0])))
+ if (!(error=table->file->ha_delete_row(table->record[0])))
{
deleted++;
if (table->triggers &&
@@ -705,7 +723,7 @@ int multi_delete::do_deletes()
local_error= 1;
break;
}
- if ((local_error=table->file->delete_row(table->record[0])))
+ if ((local_error=table->file->ha_delete_row(table->record[0])))
{
table->file->print_error(local_error,MYF(0));
break;
@@ -772,10 +790,13 @@ bool multi_delete::send_eof()
{
if (local_error == 0)
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_tables, FALSE);
- if (mysql_bin_log.write(&qinfo) && !normal_tables)
+ if (thd->binlog_query(THD::ROW_QUERY_TYPE,
+ thd->query, thd->query_length,
+ transactional_tables, FALSE) &&
+ !normal_tables)
+ {
local_error=1; // Log write failed: roll back the SQL statement
+ }
}
if (!transactional_tables)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
@@ -880,10 +901,13 @@ end:
{
if (mysql_bin_log.is_open())
{
+ /*
+ TRUNCATE must always be statement-based binlogged (not row-based) so
+ we don't test binlog_row_based.
+ */
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length,
- 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
}
send_ok(thd); // This should return record count
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 72a2f4a4f91..e053f06df55 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -21,6 +21,7 @@
#include "sp_head.h"
#include "sql_trigger.h"
#include "sql_select.h"
+#include "sql_show.h"
static int check_null_fields(THD *thd,TABLE *entry);
#ifndef EMBEDDED_LIBRARY
@@ -576,10 +577,13 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
{
if (error <= 0)
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_table, FALSE);
- if (mysql_bin_log.write(&qinfo) && transactional_table)
- error=1;
+ if (thd->binlog_query(THD::ROW_QUERY_TYPE,
+ thd->query, thd->query_length,
+ transactional_table, FALSE) &&
+ transactional_table)
+ {
+ error=1;
+ }
}
if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
@@ -945,10 +949,11 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
DBUG_ENTER("write_record");
info->records++;
+
if (info->handle_duplicates == DUP_REPLACE ||
info->handle_duplicates == DUP_UPDATE)
{
- while ((error=table->file->write_row(table->record[0])))
+ while ((error=table->file->ha_write_row(table->record[0])))
{
uint key_nr;
if (error != HA_WRITE_SKIP)
@@ -1032,7 +1037,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
thd->clear_next_insert_id= 0;
thd->next_insert_id= 0;
}
- if ((error=table->file->update_row(table->record[1],table->record[0])))
+ if ((error=table->file->ha_update_row(table->record[1],table->record[0])))
{
if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore)
goto ok_or_after_trg_err;
@@ -1071,8 +1076,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
thd->clear_next_insert_id= 0;
thd->next_insert_id= 0;
}
- if ((error=table->file->update_row(table->record[1],
- table->record[0])))
+ if ((error=table->file->ha_update_row(table->record[1],
+ table->record[0])))
goto err;
info->deleted++;
trg_error= (table->triggers &&
@@ -1089,7 +1094,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, TRUE))
goto before_trg_err;
- if ((error=table->file->delete_row(table->record[1])))
+ if ((error=table->file->ha_delete_row(table->record[1])))
goto err;
info->deleted++;
if (!table->file->has_transactions())
@@ -1110,7 +1115,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
table->triggers->process_triggers(thd, TRG_EVENT_INSERT,
TRG_ACTION_AFTER, TRUE));
}
- else if ((error=table->file->write_row(table->record[0])))
+ else if ((error=table->file->ha_write_row(table->record[0])))
{
if (!info->ignore ||
(error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE))
@@ -1196,16 +1201,15 @@ int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
class delayed_row :public ilink {
public:
- char *record,*query;
+ char *record;
enum_duplicates dup;
time_t start_time;
bool query_start_used,last_insert_id_used,insert_id_used, ignore, log_query;
ulonglong last_insert_id;
timestamp_auto_set_type timestamp_field_type;
- uint query_length;
delayed_row(enum_duplicates dup_arg, bool ignore_arg, bool log_query_arg)
- :record(0), query(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg) {}
+ :record(0), dup(dup_arg), ignore(ignore_arg), log_query(log_query_arg) {}
~delayed_row()
{
x_free(record);
@@ -1215,6 +1219,9 @@ public:
class delayed_insert :public ilink {
uint locks_in_memory;
+ char *query;
+ ulong query_length;
+ ulong query_allocated;
public:
THD thd;
TABLE *table;
@@ -1228,7 +1235,7 @@ public:
TABLE_LIST table_list; // Argument
delayed_insert()
- :locks_in_memory(0),
+ :locks_in_memory(0), query(0), query_length(0), query_allocated(0),
table(0),tables_in_use(0),stacked_inserts(0), status(0), dead(0),
group_count(0)
{
@@ -1254,6 +1261,7 @@ public:
}
~delayed_insert()
{
+ my_free(query, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
/* The following is not really needed, but just for safety */
delayed_row *row;
while ((row=rows.get()))
@@ -1273,6 +1281,25 @@ public:
VOID(pthread_cond_broadcast(&COND_thread_count)); /* Tell main we are ready */
}
+ int set_query(char const *q, ulong qlen) {
+ if (q && qlen > 0)
+ {
+ if (query_allocated < qlen + 1)
+ {
+ ulong const flags(MY_WME|MY_FREE_ON_ERROR|MY_ALLOW_ZERO_PTR);
+ query= my_realloc(query, qlen + 1, MYF(flags));
+ if (query == 0)
+ return HA_ERR_OUT_OF_MEM;
+ query_allocated= qlen;
+ }
+ query_length= qlen;
+ memcpy(query, q, qlen + 1);
+ }
+ else
+ query_length= 0;
+ return 0;
+ }
+
/* The following is for checking when we can delete ourselves */
inline void lock()
{
@@ -1562,18 +1589,22 @@ static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic,
if (thd->killed || !(row= new delayed_row(duplic, ignore, log_on)))
goto err;
+#if 0
if (!query)
query_length=0;
- if (!(row->record= (char*) my_malloc(table->s->reclength+query_length+1,
- MYF(MY_WME))))
+#endif
+ if (!(row->record= (char*) my_malloc(table->s->reclength, MYF(MY_WME))))
goto err;
memcpy(row->record, table->record[0], table->s->reclength);
+ di->set_query(query, query_length);
+#if 0
if (query_length)
{
row->query= row->record+table->s->reclength;
memcpy(row->query,query,query_length+1);
}
row->query_length= query_length;
+#endif
row->start_time= thd->start_time;
row->query_start_used= thd->query_start_used;
row->last_insert_id_used= thd->last_insert_id_used;
@@ -1897,7 +1928,21 @@ bool delayed_insert::handle_inserts(void)
{
int error;
ulong max_rows;
- bool using_ignore=0, using_bin_log=mysql_bin_log.is_open();
+ bool using_ignore=0,
+ using_bin_log= mysql_bin_log.is_open();
+
+#if 0
+ /*
+ The actual text for the query is added to the first row in the
+ list. Since the row is destroyed, with all it's memory, we need
+ to take a copy of it to be able to log it after all rows have been
+ applied.
+ */
+ uint const query_length= rows.head()->query_length;
+ char *const query= static_cast<char*>(my_alloca(query_length+1));
+ memcpy(query, rows.head()->query, query_length);
+#endif
+
delayed_row *row;
DBUG_ENTER("handle_inserts");
@@ -1963,11 +2008,6 @@ bool delayed_insert::handle_inserts(void)
using_ignore=0;
table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
}
- if (row->query && row->log_query && using_bin_log)
- {
- Query_log_event qinfo(&thd, row->query, row->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
- }
if (table->s->blob_fields)
free_delayed_insert_blobs(table);
thread_safe_sub(delayed_rows_in_use,1,&LOCK_delayed_status);
@@ -1982,8 +2022,7 @@ bool delayed_insert::handle_inserts(void)
on this table until all entries has been processed
*/
if (group_count++ >= max_rows && (row= rows.head()) &&
- (!(row->log_query & using_bin_log) ||
- row->query))
+ (!(row->log_query & using_bin_log)))
{
group_count=0;
if (stacked_inserts || tables_in_use) // Let these wait a while
@@ -2019,6 +2058,10 @@ bool delayed_insert::handle_inserts(void)
thd.proc_info=0;
table->next_number_field=0;
pthread_mutex_unlock(&mutex);
+
+ /* After releasing the mutex, to prevent deadlocks. */
+ thd.binlog_query(THD::ROW_QUERY_TYPE, query, query_length, FALSE, FALSE);
+
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
{ // This shouldn't happen
table->file->print_error(error,MYF(0));
@@ -2216,6 +2259,16 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
check_that_all_fields_are_given_values(thd, table, table_list)) ||
table_list->prepare_where(thd, 0, TRUE) ||
table_list->prepare_check_option(thd));
+
+ /*
+ For non-transactional non-temporary tables, we set the
+ OPTION_STATUS_NO_TRANS_UPDATE flag here. The send_eof() function
+ is used by both the select_insert and the select_create classes,
+ so setting it there would clash.
+ */
+ if (!(table->file->has_transactions() || table->s->tmp_table))
+ thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
+
DBUG_RETURN(res);
}
@@ -2345,9 +2398,31 @@ void select_insert::send_error(uint errcode,const char *err)
table->file->end_bulk_insert();
/*
If at least one row has been inserted/modified and will stay in the table
- (the table doesn't have transactions) (example: we got a duplicate key
- error while inserting into a MyISAM table) we must write to the binlog (and
+ (the table doesn't have transactions) we must write to the binlog (and
the error code will make the slave stop).
+
+ For many errors (example: we got a duplicate key error while
+ inserting into a MyISAM table), no row will be added to the table,
+ so passing the error to the slave will not help since there will
+ be an error code mismatch (the inserts will succeed on the slave
+ with no error).
+
+ If we are using row-based replication we have two cases where this
+ code is executed: replication of CREATE-SELECT and replication of
+ INSERT-SELECT.
+
+ When replicating a CREATE-SELECT statement, we shall not write the
+ events to the binary log. To prevent the ha_rollback_stmt() below
+ from writing to the binary log, we have to pretend that the table
+ is transactional, even if it actually is not. Therefore, the
+ OPTION_STATUS_NO_TRANS_UPDATE is cleared in
+ select_create::prepare() and will remain cleared here.
+
+ When replicating INSERT-SELECT, we shall not write the events to
+ the binary log for transactional table, but shall write all events
+ if there is one or more writes to non-transactional tables. In
+ this case, the OPTION_STATUS_NO_TRANS_UPDATE is set if there is a
+ write to a non-transactional table, otherwise it is cleared.
*/
if ((info.copied || info.deleted || info.updated) &&
!table->file->has_transactions())
@@ -2356,11 +2431,10 @@ void select_insert::send_error(uint errcode,const char *err)
thd->insert_id(last_insert_id); // For binary log
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length,
- table->file->has_transactions(), FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
+ table->file->has_transactions(), FALSE);
}
- if (!table->s->tmp_table)
+ if (!binlog_row_based && !table->s->tmp_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
if (info.copied || info.deleted || info.updated)
@@ -2382,26 +2456,36 @@ bool select_insert::send_eof()
/*
We must invalidate the table in the query cache before binlog writing
- and ha_autocommit_or_rollback
- */
+ and ha_autocommit_or_rollback.
+
+ If nothing was inserted in the table, there is no need to emit a
+ ROLLBACK statement to the binary log, so in that case we clear
+ OPTION_STATUS_NO_TRANS_UPDATE.
+ Observe that select_insert::send_eof() is used by both
+ select_insert and select_create and that they set the flag in
+ different manners. See Note 1 below for more info.
+ */
if (info.copied || info.deleted || info.updated)
- {
query_cache_invalidate3(thd, table, 1);
- if (!(table->file->has_transactions() || table->s->tmp_table))
- thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
- }
+ else
+ thd->options&= ~OPTION_STATUS_NO_TRANS_UPDATE;
if (last_insert_id)
thd->insert_id(last_insert_id); // For binary log
- /* Write to binlog before commiting transaction */
+ /*
+ Write to binlog before commiting transaction. No statement will
+ be written by the binlog_query() below in RBR mode. All the
+ events are in the transaction cache and will be written when
+ ha_autocommit_or_rollback() is issued below.
+ */
if (mysql_bin_log.is_open())
{
if (!error)
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length,
- table->file->has_transactions(), FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::ROW_QUERY_TYPE,
+ thd->query, thd->query_length,
+ table->file->has_transactions(), FALSE);
}
if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error)
error=error2;
@@ -2467,8 +2551,62 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
}
+void
+select_create::binlog_show_create_table()
+{
+ /*
+ Note 1: In RBR mode, we generate a CREATE TABLE statement for the
+ created table by calling store_create_info() (behaves as SHOW
+ CREATE TABLE). In the event of an error, nothing should be
+ written to the binary log, even if the table is non-transactional;
+ therefore we pretend that the generated CREATE TABLE statement is
+ for a transactional table. The event will then be put in the
+ transaction cache, and any subsequent events (e.g., table-map
+ events and binrow events) will also be put there. We can then use
+ ha_autocommit_or_rollback() to either throw away the entire
+ kaboodle of events, or write them to the binary log.
+
+ We write the CREATE TABLE statement here and not in prepare()
+ since there potentially are sub-selects or accesses to information
+ schema that will do a close_thread_tables(), destroying the
+ statement transaction cache.
+
+ To ensure that the event kaboodle is not written to the binary log
+ on rollback, we clear the OPTION_STATUS_NO_TRANS_UPDATE bit of
+ thd->options.
+ */
+ DBUG_ASSERT(binlog_row_based && !create_table_written);
+
+ thd->options&= ~OPTION_STATUS_NO_TRANS_UPDATE;
+ char buf[2048];
+ String query(buf, sizeof(buf), system_charset_info);
+ query.length(0); // Have to zero it since constructor doesn't
+
+ TABLE_LIST tables;
+ memset(&tables, 0, sizeof(tables));
+ tables.table = table;
+
+ int result= store_create_info(thd, &tables, &query, create_info);
+ DBUG_ASSERT(result == 0); /* store_create_info() always return 0 */
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ query.ptr(), query.length(),
+ /* is_trans */ TRUE,
+ /* suppress_use */ FALSE);
+}
+
+
void select_create::store_values(List<Item> &values)
{
+ /*
+ Before writing the first row, we write the CREATE TABLE statement
+ to the binlog.
+ */
+ if (binlog_row_based && !create_table_written)
+ {
+ binlog_show_create_table();
+ create_table_written= TRUE;
+ }
+
fill_record_n_invoke_before_triggers(thd, field, values, 1,
table->triggers, TRG_EVENT_INSERT);
}
@@ -2488,6 +2626,16 @@ void select_create::send_error(uint errcode,const char *err)
bool select_create::send_eof()
{
+ /*
+ If no rows where written to the binary log, we write the CREATE
+ TABLE statement to the binlog.
+ */
+ if (binlog_row_based && !create_table_written)
+ {
+ binlog_show_create_table();
+ create_table_written= TRUE;
+ }
+
bool tmp=select_insert::send_eof();
if (tmp)
abort();
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 303245b38bd..00ba075e922 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -93,7 +93,8 @@ enum enum_sql_command {
SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER,
SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE,
SQLCOM_INSTALL_PLUGIN, SQLCOM_UNINSTALL_PLUGIN,
- SQLCOM_SHOW_AUTHORS, SQLCOM_SHOW_PLUGINS,
+ SQLCOM_SHOW_AUTHORS, SQLCOM_BINLOG_BASE64_EVENT,
+ SQLCOM_SHOW_PLUGINS,
/* This should be the last !!! */
SQLCOM_END
diff --git a/sql/sql_list.h b/sql/sql_list.h
index b2bcc4ea401..05f589a2c23 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -441,6 +441,28 @@ struct ilink
};
+/* Needed to be able to have an I_List of char* strings in mysqld.cc. */
+
+class i_string: public ilink
+{
+public:
+ const char* ptr;
+ i_string():ptr(0) { }
+ i_string(const char* s) : ptr(s) {}
+};
+
+/* needed for linked list of two strings for replicate-rewrite-db */
+class i_string_pair: public ilink
+{
+public:
+ const char* key;
+ const char* val;
+ i_string_pair():key(0),val(0) { }
+ i_string_pair(const char* key_arg, const char* val_arg) :
+ key(key_arg),val(val_arg) {}
+};
+
+
template <class T> class I_List_iterator;
/*
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 09bcb9cb9fe..70abe3e659c 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -414,38 +414,55 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
#ifndef EMBEDDED_LIBRARY
if (mysql_bin_log.is_open())
{
+#ifdef HAVE_ROW_BASED_REPLICATION
/*
- Make sure last block (the one which caused the error) gets logged.
- This is needed because otherwise after write of
- (to the binlog, not to read_info (which is a cache))
- Delete_file_log_event the bad block will remain in read_info (because
- pre_read is not called at the end of the last block; remember pre_read
- is called whenever a new block is read from disk).
- At the end of mysql_load(), the destructor of read_info will call
- end_io_cache() which will flush read_info, so we will finally have
- this in the binlog:
- Append_block # The last successfull block
- Delete_file
- Append_block # The failing block
- which is nonsense.
- Or could also be (for a small file)
- Create_file # The failing block
- which is nonsense (Delete_file is not written in this case, because:
- Create_file has not been written, so Delete_file is not written, then
- when read_info is destroyed end_io_cache() is called which writes
- Create_file.
+ We need to do the job that is normally done inside
+ binlog_query() here, which is to ensure that the pending event
+ is written before tables are unlocked and before any other
+ events are written. We also need to update the table map
+ version for the binary log to mark that table maps are invalid
+ after this point.
*/
- read_info.end_io_cache();
- /* If the file was not empty, wrote_create_file is true */
- if (lf_info.wrote_create_file)
+ if (binlog_row_based)
+ thd->binlog_flush_pending_rows_event(true);
+ else
+#endif
{
- if ((info.copied || info.deleted) && !transactional_table)
- write_execute_load_query_log_event(thd, handle_duplicates,
- ignore, transactional_table);
- else
+ /*
+ Make sure last block (the one which caused the error) gets
+ logged. This is needed because otherwise after write of (to
+ the binlog, not to read_info (which is a cache))
+ Delete_file_log_event the bad block will remain in read_info
+ (because pre_read is not called at the end of the last
+ block; remember pre_read is called whenever a new block is
+ read from disk). At the end of mysql_load(), the destructor
+ of read_info will call end_io_cache() which will flush
+ read_info, so we will finally have this in the binlog:
+
+ Append_block # The last successfull block
+ Delete_file
+ Append_block # The failing block
+ which is nonsense.
+ Or could also be (for a small file)
+ Create_file # The failing block
+ which is nonsense (Delete_file is not written in this case, because:
+ Create_file has not been written, so Delete_file is not written, then
+ when read_info is destroyed end_io_cache() is called which writes
+ Create_file.
+ */
+ read_info.end_io_cache();
+ /* If the file was not empty, wrote_create_file is true */
+ if (lf_info.wrote_create_file)
{
- Delete_file_log_event d(thd, db, transactional_table);
- mysql_bin_log.write(&d);
+ if ((info.copied || info.deleted) && !transactional_table)
+ write_execute_load_query_log_event(thd, handle_duplicates,
+ ignore, transactional_table);
+ else
+ {
+ Delete_file_log_event d(thd, db, transactional_table);
+ d.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
+ mysql_bin_log.write(&d);
+ }
}
}
}
@@ -462,15 +479,32 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
#ifndef EMBEDDED_LIBRARY
if (mysql_bin_log.is_open())
{
+#ifdef HAVE_ROW_BASED_REPLICATION
/*
- As already explained above, we need to call end_io_cache() or the last
- block will be logged only after Execute_load_query_log_event (which is
- wrong), when read_info is destroyed.
- */
- read_info.end_io_cache();
- if (lf_info.wrote_create_file)
- write_execute_load_query_log_event(thd, handle_duplicates,
- ignore, transactional_table);
+ We need to do the job that is normally done inside
+ binlog_query() here, which is to ensure that the pending event
+ is written before tables are unlocked and before any other
+ events are written. We also need to update the table map
+ version for the binary log to mark that table maps are invalid
+ after this point.
+ */
+ if (binlog_row_based)
+ thd->binlog_flush_pending_rows_event(true);
+ else
+#endif
+ {
+ /*
+ As already explained above, we need to call end_io_cache() or the last
+ block will be logged only after Execute_load_query_log_event (which is
+ wrong), when read_info is destroyed.
+ */
+ read_info.end_io_cache();
+ if (lf_info.wrote_create_file)
+ {
+ write_execute_load_query_log_event(thd, handle_duplicates,
+ ignore, transactional_table);
+ }
+ }
}
#endif /*!EMBEDDED_LIBRARY*/
if (transactional_table)
@@ -499,6 +533,7 @@ static bool write_execute_load_query_log_event(THD *thd,
(duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
(ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
transactional_table, FALSE);
+ e.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F;
return mysql_bin_log.write(&e);
}
@@ -910,7 +945,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
if (get_it_from_net)
cache.read_function = _my_b_net_read;
- if (mysql_bin_log.is_open())
+ if (!binlog_row_based && mysql_bin_log.is_open())
cache.pre_read = cache.pre_close =
(IO_CACHE_CALLBACK) log_loaded_block;
#endif
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index cf098f1b414..839e1dbd65f 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3712,8 +3712,8 @@ end_with_restore_list:
{
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
}
send_ok(thd);
}
@@ -3730,8 +3730,8 @@ end_with_restore_list:
{
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
}
send_ok(thd);
}
@@ -3748,8 +3748,8 @@ end_with_restore_list:
{
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
}
send_ok(thd);
}
@@ -3764,8 +3764,8 @@ end_with_restore_list:
{
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
}
send_ok(thd);
}
@@ -3844,8 +3844,8 @@ end_with_restore_list:
if (!res && mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
}
}
else
@@ -3864,8 +3864,8 @@ end_with_restore_list:
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
}
if (lex->sql_command == SQLCOM_GRANT)
{
@@ -4161,12 +4161,12 @@ end_with_restore_list:
db, name,
lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
{
- close_thread_tables(thd);
if (sp_grant_privileges(thd, db, name,
lex->sql_command == SQLCOM_CREATE_PROCEDURE))
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_PROC_AUTO_GRANT_FAIL,
ER(ER_PROC_AUTO_GRANT_FAIL));
+ close_thread_tables(thd);
}
#endif
send_ok(thd);
@@ -4394,8 +4394,8 @@ end_with_restore_list:
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
}
send_ok(thd);
break;
@@ -4483,8 +4483,8 @@ end_with_restore_list:
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
}
send_ok(thd);
break;
@@ -4608,8 +4608,8 @@ end_with_restore_list:
buff.append(STRING_WITH_LEN(" AS "));
buff.append(first_table->source.str, first_table->source.length);
- Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ buff.ptr(), buff.length(), FALSE, FALSE);
}
break;
}
@@ -4622,8 +4622,8 @@ end_with_restore_list:
mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
}
break;
}
@@ -4826,15 +4826,24 @@ end_with_restore_list:
if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment)))
send_ok(thd);
break;
+ case SQLCOM_BINLOG_BASE64_EVENT:
+ {
+#ifndef EMBEDDED_LIBRARY
+ mysql_client_binlog_statement(thd);
+#else /* EMBEDDED_LIBRARY */
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "embedded");
+#endif /* EMBEDDED_LIBRARY */
+ break;
+ }
default:
DBUG_ASSERT(0); /* Impossible */
send_ok(thd);
break;
}
thd->proc_info="query end";
- /* Two binlog-related cleanups: */
/*
+ Binlog-related cleanup:
Reset system variables temporarily modified by SET ONE SHOT.
Exception: If this is a SET, do nothing. This is to allow
@@ -5571,7 +5580,6 @@ void mysql_init_multi_delete(LEX *lex)
lex->query_tables_last= &lex->query_tables;
}
-
/*
When you modify mysql_parse(), you may need to mofify
mysql_test_parse_for_slave() in this same file.
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 591289f6ee1..82bd6b2c499 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -625,7 +625,7 @@ my_bool mysql_install_plugin(THD *thd, LEX_STRING *name, LEX_STRING *dl)
restore_record(table, s->default_values);
table->field[0]->store(name->str, name->length, system_charset_info);
table->field[1]->store(dl->str, dl->length, files_charset_info);
- error= table->file->write_row(table->record[0]);
+ error= table->file->ha_write_row(table->record[0]);
if (error)
{
table->file->print_error(error, MYF(0));
@@ -694,7 +694,7 @@ my_bool mysql_uninstall_plugin(THD *thd, LEX_STRING *name)
HA_READ_KEY_EXACT))
{
int error;
- if ((error= table->file->delete_row(table->record[0])))
+ if ((error= table->file->ha_delete_row(table->record[0])))
{
table->file->print_error(error, MYF(0));
goto err;
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 2c8c732fe86..a1bbb69bc17 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -84,8 +84,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ thd->query, thd->query_length, FALSE, FALSE);
}
send_ok(thd);
}
diff --git a/sql/sql_repl.h b/sql/sql_repl.h
index ba64e626adc..789de64da85 100644
--- a/sql/sql_repl.h
+++ b/sql/sql_repl.h
@@ -14,6 +14,8 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#include "rpl_filter.h"
+
#ifdef HAVE_REPLICATION
#include "slave.h"
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 7b12069b8ec..f2833f94400 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9288,11 +9288,11 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
*/
while (!table->file->rnd_next(new_table.record[1]))
{
- if ((write_err=new_table.file->write_row(new_table.record[1])))
+ if ((write_err=new_table.file->ha_write_row(new_table.record[1])))
goto err;
}
/* copy row that filled HEAP table */
- if ((write_err=new_table.file->write_row(table->record[0])))
+ if ((write_err=new_table.file->ha_write_row(table->record[0])))
{
if (write_err != HA_ERR_FOUND_DUPP_KEY &&
write_err != HA_ERR_FOUND_DUPP_UNIQUE || !ignore_last_dupp_key_error)
@@ -10691,7 +10691,7 @@ end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{
int error;
join->found_records++;
- if ((error=table->file->write_row(table->record[0])))
+ if ((error=table->file->ha_write_row(table->record[0])))
{
if (error == HA_ERR_FOUND_DUPP_KEY ||
error == HA_ERR_FOUND_DUPP_UNIQUE)
@@ -10753,8 +10753,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{ /* Update old record */
restore_record(table,record[1]);
update_tmptable_sum_func(join->sum_funcs,table);
- if ((error=table->file->update_row(table->record[1],
- table->record[0])))
+ if ((error=table->file->ha_update_row(table->record[1],
+ table->record[0])))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
@@ -10777,7 +10777,7 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
}
init_tmptable_sum_functions(join->sum_funcs);
copy_funcs(join->tmp_table_param.items_to_copy);
- if ((error=table->file->write_row(table->record[0])))
+ if ((error=table->file->ha_write_row(table->record[0])))
{
if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
error, 0))
@@ -10813,7 +10813,7 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
copy_fields(&join->tmp_table_param); // Groups are copied twice.
copy_funcs(join->tmp_table_param.items_to_copy);
- if (!(error=table->file->write_row(table->record[0])))
+ if (!(error=table->file->ha_write_row(table->record[0])))
join->send_records++; // New group
else
{
@@ -10829,8 +10829,8 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
}
restore_record(table,record[1]);
update_tmptable_sum_func(join->sum_funcs,table);
- if ((error=table->file->update_row(table->record[1],
- table->record[0])))
+ if ((error=table->file->ha_update_row(table->record[1],
+ table->record[0])))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
@@ -10873,7 +10873,7 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
join->sum_funcs_end[send_group_parts]);
if (!join->having || join->having->val_int())
{
- int error= table->file->write_row(table->record[0]);
+ int error= table->file->ha_write_row(table->record[0]);
if (error && create_myisam_from_heap(join->thd, table,
&join->tmp_table_param,
error, 0))
@@ -11735,7 +11735,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
}
if (having && !having->val_int())
{
- if ((error=file->delete_row(record)))
+ if ((error=file->ha_delete_row(record)))
goto err;
error=file->rnd_next(record);
continue;
@@ -11762,7 +11762,7 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
}
if (compare_record(table, first_field) == 0)
{
- if ((error=file->delete_row(record)))
+ if ((error=file->ha_delete_row(record)))
goto err;
}
else if (!found)
@@ -11859,7 +11859,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
}
if (having && !having->val_int())
{
- if ((error=file->delete_row(record)))
+ if ((error=file->ha_delete_row(record)))
goto err;
continue;
}
@@ -11876,7 +11876,7 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table,
if (hash_search(&hash, org_key_pos, key_length))
{
/* Duplicated found ; Remove the row */
- if ((error=file->delete_row(record)))
+ if ((error=file->ha_delete_row(record)))
goto err;
}
else
@@ -13702,7 +13702,7 @@ int JOIN::rollup_write_data(uint idx, TABLE *table)
item->save_in_result_field(1);
}
copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
- if ((error= table->file->write_row(table->record[0])))
+ if ((error= table->file->ha_write_row(table->record[0])))
{
if (create_myisam_from_heap(thd, table, &tmp_table_param,
error, 0))
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index d3649aa5f6b..42345afbd0d 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -19,6 +19,7 @@
#include "mysql_priv.h"
#include "sql_select.h" // For select_describe
+#include "sql_show.h"
#include "repl_failsafe.h"
#include "sp.h"
#include "sp_head.h"
@@ -37,10 +38,6 @@ static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
grant_names, NULL};
#endif
-static int
-store_create_info(THD *thd, TABLE_LIST *table_list, String *packet);
-static int
-view_store_create_info(THD *thd, TABLE_LIST *table, String *buff);
static bool schema_table_store_record(THD *thd, TABLE *table);
@@ -540,7 +537,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
buffer.length(0);
if ((table_list->view ?
view_store_create_info(thd, table_list, &buffer) :
- store_create_info(thd, table_list, &buffer)))
+ store_create_info(thd, table_list, &buffer, NULL)))
DBUG_RETURN(TRUE);
List<Item> field_list;
@@ -719,7 +716,7 @@ mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd)
DBUG_PRINT("enter",("table: %s",table_list->table->s->table_name.str));
protocol->prepare_for_resend();
- if (store_create_info(thd, table_list, packet))
+ if (store_create_info(thd, table_list, packet, NULL))
DBUG_RETURN(-1);
if (fd < 0)
@@ -872,8 +869,31 @@ static void append_directory(THD *thd, String *packet, const char *dir_type,
#define LIST_PROCESS_HOST_LEN 64
-static int
-store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
+/*
+ Build a CREATE TABLE statement for a table.
+
+ SYNOPSIS
+ store_create_info()
+ thd The thread
+ table_list A list containing one table to write statement
+ for.
+ packet Pointer to a string where statement will be
+ written.
+ create_info_arg Pointer to create information that can be used
+ to tailor the format of the statement. Can be
+ NULL, in which case only SQL_MODE is considered
+ when building the statement.
+
+ NOTE
+ Currently always return 0, but might return error code in the
+ future.
+
+ RETURN
+ 0 OK
+ */
+int
+store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
+ HA_CREATE_INFO *create_info_arg)
{
List<Item> field_list;
char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], *end;
@@ -1108,10 +1128,17 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
packet->append(STRING_WITH_LEN("\n)"));
if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode)
{
- if (thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
- packet->append(STRING_WITH_LEN(" TYPE="));
- else
- packet->append(STRING_WITH_LEN(" ENGINE="));
+ /*
+ IF check_create_info
+ THEN add ENGINE only if it was used when creating the table
+ */
+ if (!create_info_arg ||
+ (create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
+ {
+ if (thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
+ packet->append(STRING_WITH_LEN(" TYPE="));
+ else
+ packet->append(STRING_WITH_LEN(" ENGINE="));
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (table->part_info)
packet->append(ha_resolve_storage_engine_name(
@@ -1119,19 +1146,28 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet)
else
packet->append(file->table_type());
#else
- packet->append(file->table_type());
+ packet->append(file->table_type());
#endif
+ }
if (share->table_charset &&
!(thd->variables.sql_mode & MODE_MYSQL323) &&
!(thd->variables.sql_mode & MODE_MYSQL40))
{
- packet->append(STRING_WITH_LEN(" DEFAULT CHARSET="));
- packet->append(share->table_charset->csname);
- if (!(share->table_charset->state & MY_CS_PRIMARY))
+ /*
+ IF check_create_info
+ THEN add DEFAULT CHARSET only if it was used when creating the table
+ */
+ if (!create_info_arg ||
+ (create_info_arg->used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
{
- packet->append(STRING_WITH_LEN(" COLLATE="));
- packet->append(table->s->table_charset->name);
+ packet->append(STRING_WITH_LEN(" DEFAULT CHARSET="));
+ packet->append(share->table_charset->csname);
+ if (!(share->table_charset->state & MY_CS_PRIMARY))
+ {
+ packet->append(STRING_WITH_LEN(" COLLATE="));
+ packet->append(table->s->table_charset->name);
+ }
}
}
@@ -1236,7 +1272,6 @@ view_store_options(THD *thd, TABLE_LIST *table, String *buff)
buff->append(STRING_WITH_LEN("SQL SECURITY INVOKER "));
}
-
/*
Append DEFINER clause to the given buffer.
@@ -1259,7 +1294,7 @@ void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
}
-static int
+int
view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
{
my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
@@ -1924,7 +1959,7 @@ typedef struct st_index_field_values
static bool schema_table_store_record(THD *thd, TABLE *table)
{
int error;
- if ((error= table->file->write_row(table->record[0])))
+ if ((error= table->file->ha_write_row(table->record[0])))
{
if (create_myisam_from_heap(thd, table,
table->pos_in_table_list->schema_table_param,
diff --git a/sql/sql_show.h b/sql/sql_show.h
new file mode 100644
index 00000000000..6fce5e94ca3
--- /dev/null
+++ b/sql/sql_show.h
@@ -0,0 +1,17 @@
+
+#ifndef SQL_SHOW_H
+#define SQL_SHOW_H
+
+/* Forward declarations */
+class String;
+class THD;
+struct st_ha_create_information;
+struct st_table_list;
+typedef st_ha_create_information HA_CREATE_INFO;
+typedef st_table_list TABLE_LIST;
+
+int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
+ HA_CREATE_INFO *create_info_arg);
+int view_store_create_info(THD *thd, TABLE_LIST *table, String *buff);
+
+#endif /* SQL_SHOW_H */
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 0e811d63b36..3ac0d3ae466 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -22,6 +22,7 @@
#include <my_dir.h>
#include "sp_head.h"
#include "sql_trigger.h"
+#include "sql_show.h"
#ifdef __WIN__
#include <io.h>
@@ -53,14 +54,15 @@ static bool check_engine(THD *thd, const char *table_name,
file
*/
-static void write_bin_log(THD *thd, bool clear_error)
+static void write_bin_log(THD *thd, bool clear_error,
+ char const* query, ulong query_length)
{
if (mysql_bin_log.is_open())
{
if (clear_error)
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
- mysql_bin_log.write(&qinfo);
+ thd->binlog_query(THD::STMT_QUERY_TYPE,
+ query, query_length, FALSE, FALSE);
}
}
@@ -277,9 +279,19 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
char path[FN_REFLEN], *alias;
String wrong_tables;
int error;
+ int non_temp_tables_count= 0;
bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
+ String built_query;
DBUG_ENTER("mysql_rm_table_part2");
+ if (binlog_row_based && !dont_log_query)
+ {
+ built_query.set_charset(system_charset_info);
+ if (if_exists)
+ built_query.append("DROP TABLE IF EXISTS ");
+ else
+ built_query.append("DROP TABLE ");
+ }
/*
If we have the table in the definition cache, we don't have to check the
.frm file to find if the table is a normal table (not view) and what
@@ -313,6 +325,30 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
continue; // removed temporary table
}
+ /*
+ If row-based replication is used and the table is not a
+ temporary table, we add the table name to the drop statement
+ being built. The string always end in a comma and the comma
+ will be chopped off before being written to the binary log.
+ */
+ if (binlog_row_based && !dont_log_query)
+ {
+ ++non_temp_tables_count;
+ /*
+ Don't write the database name if it is the current one (or if
+ thd->db is NULL).
+ */
+ built_query.append("`");
+ if (thd->db == NULL || strcmp(db,thd->db) != 0)
+ {
+ built_query.append(db);
+ built_query.append("`.`");
+ }
+
+ built_query.append(table->table_name);
+ built_query.append("`,");
+ }
+
error=0;
table_type= table->db_type;
if (!drop_temporary)
@@ -401,12 +437,48 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
if (some_tables_deleted || tmp_table_deleted || !error)
{
query_cache_invalidate3(thd, tables, 0);
- if (!dont_log_query && mysql_bin_log.is_open())
+ if (!dont_log_query)
{
- if (!error)
- thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
- mysql_bin_log.write(&qinfo);
+ if (!binlog_row_based ||
+ non_temp_tables_count > 0 && !tmp_table_deleted)
+ {
+ /*
+ In this case, we are either using statement-based
+ replication or using row-based replication but have only
+ deleted one or more non-temporary tables (and no temporary
+ tables). In this case, we can write the original query into
+ the binary log.
+ */
+ write_bin_log(thd, !error, thd->query, thd->query_length);
+ }
+ else if (binlog_row_based &&
+ non_temp_tables_count > 0 &&
+ tmp_table_deleted)
+ {
+ /*
+ In this case we have deleted both temporary and
+ non-temporary tables, so:
+ - since we have deleted a non-temporary table we have to
+ binlog the statement, but
+ - since we have deleted a temporary table we cannot binlog
+ the statement (since the table has not been created on the
+ slave, this might cause the slave to stop).
+
+ Instead, we write a built statement, only containing the
+ non-temporary tables, to the binary log
+ */
+ built_query.chop(); // Chop of the last comma
+ built_query.append(" /* generated by server */");
+ write_bin_log(thd, !error, built_query.ptr(), built_query.length());
+ }
+ /*
+ The remaining cases are:
+ - no tables where deleted and
+ - only temporary tables where deleted and row-based
+ replication is used.
+ In both these cases, nothing should be written to the binary
+ log.
+ */
}
}
@@ -1837,13 +1909,17 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
}
thd->tmp_table_used= 1;
}
- if (!internal_tmp_table && mysql_bin_log.is_open())
- {
- thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
- mysql_bin_log.write(&qinfo);
- }
+ /*
+ Don't write statement if:
+ - It is an internal temporary table,
+ - Row-based logging is used and it we are creating a temporary table, or
+ - The binary log is not open.
+ */
+ if (!internal_tmp_table &&
+ !(binlog_row_based &&
+ (create_info->options & HA_LEX_CREATE_TMP_TABLE)))
+ write_bin_log(thd, TRUE, thd->query, thd->query_length);
error= FALSE;
unlock_and_end:
VOID(pthread_mutex_unlock(&LOCK_open));
@@ -2982,8 +3058,63 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
goto err; /* purecov: inspected */
}
- // Must be written before unlock
- write_bin_log(thd, TRUE);
+ /*
+ We have to write the query before we unlock the tables.
+ */
+ if (binlog_row_based)
+ {
+ /*
+ Since temporary tables are not replicated under row-based
+ replication, CREATE TABLE ... LIKE ... needs special
+ treatement. We have four cases to consider, according to the
+ following decision table:
+
+ ==== ========= ========= ==============================
+ Case Target Source Write to binary log
+ ==== ========= ========= ==============================
+ 1 normal normal Original statement
+ 2 normal temporary Generated statement
+ 3 temporary normal Nothing
+ 4 temporary temporary Nothing
+ ==== ========= ========= ==============================
+
+ The variable 'tmp_table' below is used to see if the source
+ table is a temporary table: if it is set, then the source table
+ was a temporary table and we can take apropriate actions.
+ */
+ if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
+ {
+ if (tmp_table) // Case 2
+ {
+ char buf[2048];
+ String query(buf, sizeof(buf), system_charset_info);
+ query.length(0); // Have to zero it since constructor doesn't
+ TABLE *table_ptr;
+ int error;
+
+ /*
+ Let's open and lock the table: it will be closed (and
+ unlocked) by close_thread_tables() at the end of the
+ statement anyway.
+ */
+ if (!(table_ptr= open_ltable(thd, table, TL_READ_NO_INSERT)))
+ goto err;
+
+ int result= store_create_info(thd, table, &query, create_info);
+
+ DBUG_ASSERT(result == 0); // store_create_info() always return 0
+ write_bin_log(thd, TRUE, query.ptr(), query.length());
+ }
+ else // Case 1
+ write_bin_log(thd, TRUE, thd->query, thd->query_length);
+ }
+ /*
+ Case 3 and 4 does nothing under RBR
+ */
+ }
+ else if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
+ write_bin_log(thd, TRUE, thd->query, thd->query_length);
+
res= FALSE;
goto err;
@@ -3089,7 +3220,7 @@ mysql_discard_or_import_tablespace(THD *thd,
error=1;
if (error)
goto err;
- write_bin_log(thd, FALSE);
+ write_bin_log(thd, FALSE, thd->query, thd->query_length);
err:
close_thread_tables(thd);
thd->tablespace_op=FALSE;
@@ -4057,7 +4188,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
}
if (!error)
{
- write_bin_log(thd, TRUE);
+ write_bin_log(thd, TRUE, thd->query, thd->query_length);
if (do_send_ok)
send_ok(thd);
}
@@ -4472,7 +4603,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (!error)
{
close_thread_tables(thd);
- write_bin_log(thd, FALSE);
+ write_bin_log(thd, FALSE, thd->query, thd->query_length);
send_ok(thd);
DBUG_RETURN(FALSE);
}
@@ -4609,7 +4740,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
my_free((gptr) new_table,MYF(0));
goto err;
}
- write_bin_log(thd, TRUE);
+ /* We don't replicate alter table statement on temporary tables */
+ if (!binlog_row_based)
+ write_bin_log(thd, TRUE, thd->query, thd->query_length);
goto end_temporary;
}
@@ -4751,7 +4884,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
goto err;
}
thd->proc_info="end";
- write_bin_log(thd, TRUE);
+
+ DBUG_ASSERT(!(mysql_bin_log.is_open() && binlog_row_based &&
+ (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
+ write_bin_log(thd, TRUE, thd->query, thd->query_length);
VOID(pthread_cond_broadcast(&COND_refresh));
VOID(pthread_mutex_unlock(&LOCK_open));
/*
@@ -4928,7 +5064,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
{
copy_ptr->do_copy(copy_ptr);
}
- if ((error=to->file->write_row((byte*) to->record[0])))
+ if ((error=to->file->ha_write_row((byte*) to->record[0])))
{
if ((!ignore &&
handle_duplicates != DUP_REPLACE) ||
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 367803f4c86..77bfba5ba28 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -455,7 +455,7 @@ int mysql_create_function(THD *thd,udf_func *udf)
table->field[2]->store(u_d->dl,(uint) strlen(u_d->dl), system_charset_info);
if (table->s->fields >= 4) // If not old func format
table->field[3]->store((longlong) u_d->type, TRUE);
- error = table->file->write_row(table->record[0]);
+ error = table->file->ha_write_row(table->record[0]);
close_thread_tables(thd);
if (error)
@@ -514,7 +514,7 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name)
HA_READ_KEY_EXACT))
{
int error;
- if ((error = table->file->delete_row(table->record[0])))
+ if ((error = table->file->ha_delete_row(table->record[0])))
table->file->print_error(error, MYF(0));
}
close_thread_tables(thd);
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index dee88af7d83..e80aaecfd64 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -62,7 +62,7 @@ bool select_union::send_data(List<Item> &values)
if (thd->net.report_error)
return 1;
- if ((error= table->file->write_row(table->record[0])))
+ if ((error= table->file->ha_write_row(table->record[0])))
{
/* create_myisam_from_heap will generate error if needed */
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE &&
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 3aa6e7fc874..bd001cd9a06 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -355,6 +355,9 @@ int mysql_update(THD *thd,
/* If quick select is used, initialize it before retrieving rows. */
if (select && select->quick && select->quick->reset())
goto err;
+
+ table->file->try_semi_consistent_read(1);
+
if (used_index == MAX_KEY || (select && select->quick))
init_read_record(&info,thd,table,select,0,1);
else
@@ -367,6 +370,9 @@ int mysql_update(THD *thd,
{
if (!(select && select->skip_record()))
{
+ if (table->file->was_semi_consistent_read())
+ continue; /* repeat the read of the same row if it still exists */
+
table->file->position(table->record[0]);
if (my_b_write(&tempfile,table->file->ref,
table->file->ref_length))
@@ -386,6 +392,7 @@ int mysql_update(THD *thd,
if (thd->killed && !error)
error= 1; // Aborted
limit= tmp_limit;
+ table->file->try_semi_consistent_read(0);
end_read_record(&info);
/* Change select to use tempfile */
@@ -420,6 +427,7 @@ int mysql_update(THD *thd,
if (select && select->quick && select->quick->reset())
goto err;
+ table->file->try_semi_consistent_read(1);
init_read_record(&info,thd,table,select,0,1);
updated= found= 0;
@@ -435,10 +443,14 @@ int mysql_update(THD *thd,
(MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES)));
will_batch= !table->file->start_bulk_update();
+
while (!(error=info.read_record(&info)) && !thd->killed)
{
if (!(select && select->skip_record()))
{
+ if (table->file->was_semi_consistent_read())
+ continue; /* repeat the read of the same row if it still exists */
+
store_record(table,record[1]);
if (fill_record_n_invoke_before_triggers(thd, fields, values, 0,
table->triggers,
@@ -498,8 +510,8 @@ int mysql_update(THD *thd,
else
{
/* Non-batched update */
- error= table->file->update_row((byte*) table->record[1],
- (byte*) table->record[0]);
+ error= table->file->ha_update_row((byte*) table->record[1],
+ (byte*) table->record[0]);
}
if (!error)
{
@@ -594,6 +606,7 @@ int mysql_update(THD *thd,
updated-= dup_key_found;
if (will_batch)
table->file->end_bulk_update();
+ table->file->try_semi_consistent_read(0);
end_read_record(&info);
free_io_cache(table); // If ORDER BY
delete select;
@@ -624,10 +637,13 @@ int mysql_update(THD *thd,
{
if (error < 0)
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_table, FALSE);
- if (mysql_bin_log.write(&qinfo) && transactional_table)
+ if (thd->binlog_query(THD::ROW_QUERY_TYPE,
+ thd->query, thd->query_length,
+ transactional_table, FALSE) &&
+ transactional_table)
+ {
error=1; // Rollback update
+ }
}
if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
@@ -1364,8 +1380,8 @@ bool multi_update::send_data(List<Item> &not_used_values)
*/
main_table->file->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
}
- if ((error=table->file->update_row(table->record[1],
- table->record[0])))
+ if ((error=table->file->ha_update_row(table->record[1],
+ table->record[0])))
{
updated--;
if (!ignore || error != HA_ERR_FOUND_DUPP_KEY)
@@ -1400,7 +1416,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
memcpy((char*) tmp_table->field[0]->ptr,
(char*) table->file->ref, table->file->ref_length);
/* Write row, ignoring duplicated updates to a row */
- if (error= tmp_table->file->write_row(tmp_table->record[0]))
+ if (error= tmp_table->file->ha_write_row(tmp_table->record[0]))
{
if (error != HA_ERR_FOUND_DUPP_KEY &&
error != HA_ERR_FOUND_DUPP_UNIQUE &&
@@ -1517,8 +1533,8 @@ int multi_update::do_updates(bool from_send_error)
if (compare_record(table, thd->query_id))
{
- if ((local_error=table->file->update_row(table->record[1],
- table->record[0])))
+ if ((local_error=table->file->ha_update_row(table->record[1],
+ table->record[0])))
{
if (!ignore || local_error != HA_ERR_FOUND_DUPP_KEY)
goto err;
@@ -1597,10 +1613,13 @@ bool multi_update::send_eof()
{
if (local_error == 0)
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_tables, FALSE);
- if (mysql_bin_log.write(&qinfo) && trans_safe)
+ if (thd->binlog_query(THD::ROW_QUERY_TYPE,
+ thd->query, thd->query_length,
+ transactional_tables, FALSE) &&
+ trans_safe)
+ {
local_error= 1; // Rollback update
+ }
}
if (!transactional_tables)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 4518f9e8de1..bc41178e1be 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -897,6 +897,7 @@ statement:
alter
| analyze
| backup
+ | binlog_base64_event
| call
| change
| check
@@ -4400,6 +4401,13 @@ analyze:
{}
;
+binlog_base64_event:
+ BINLOG_SYM TEXT_STRING_sys
+ {
+ Lex->sql_command = SQLCOM_BINLOG_BASE64_EVENT;
+ Lex->comment= $2;
+ }
+
check:
CHECK_SYM table_or_tables
{
diff --git a/sql/table.cc b/sql/table.cc
index f9c6344e88f..bf208918346 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1206,6 +1206,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
outparam->in_use= thd;
outparam->s= share;
outparam->db_stat= db_stat;
+ outparam->write_row_record= NULL;
init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
*root_ptr= &outparam->mem_root;
@@ -1396,6 +1397,25 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
*root_ptr= old_root;
thd->status_var.opened_tables++;
+#ifdef HAVE_REPLICATION
+
+ /*
+ This constant is used to mark that no table map version has been
+ assigned. No arithmetic is done on the value: it will be
+ overwritten with a value taken from MYSQL_BIN_LOG.
+ */
+ share->table_map_version= ~(ulonglong)0;
+
+ /*
+ Since openfrm() can be called without any locking (for example,
+ ha_create_table... functions), we do not assign a table map id
+ here. Instead we assign a value that is not used elsewhere, and
+ then assign a table map id inside open_table() under the
+ protection of the LOCK_open mutex.
+ */
+ share->table_map_id= ULONG_MAX;
+#endif
+
DBUG_RETURN (0);
err:
diff --git a/sql/table.h b/sql/table.h
index d81eb6afe91..c8b9db1b2a5 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -189,7 +189,8 @@ typedef struct st_table_share
bool is_view;
bool name_lock, replace_with_name_lock;
bool waiting_on_cond; /* Protection against free */
-
+ ulong table_map_id; /* for row-based replication */
+ ulonglong table_map_version;
/*
TRUE if this is a system table like 'mysql.proc', which we want to be
able to open and lock even when we already have some tables open and
@@ -220,6 +221,8 @@ struct st_table {
Field **field; /* Pointer to fields */
byte *record[2]; /* Pointer to records */
+ byte *write_row_record; /* Used as optimisation in
+ THD::write_row */
byte *insert_values; /* used by INSERT ... UPDATE */
key_map quick_keys, used_keys, keys_in_use_for_query;
KEY *key_info; /* data of keys in database */
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 20b1f1d7145..86e579bc007 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -64,14 +64,6 @@ lock_clust_rec_some_has_impl(
dict_index_t* index, /* in: clustered index */
const ulint* offsets);/* in: rec_get_offsets(rec, index) */
/*****************************************************************
-Resets the lock bits for a single record. Releases transactions
-waiting for lock requests here. */
-
-void
-lock_rec_reset_and_release_wait(
-/*============================*/
- rec_t* rec); /* in: record whose locks bits should be reset */
-/*****************************************************************
Makes a record to inherit the locks of another record as gap type
locks, but does not reset the lock bits of the other record. Also
waiting lock requests on rec are inherited as GRANTED gap locks. */
@@ -427,6 +419,18 @@ lock_is_on_table(
/*=============*/
/* out: TRUE if there are lock(s) */
dict_table_t* table); /* in: database table in dictionary cache */
+/*****************************************************************
+Removes a granted record lock of a transaction from the queue and grants
+locks to other transactions waiting in the queue if they now are entitled
+to a lock. */
+
+void
+lock_rec_unlock(
+/*============*/
+ trx_t* trx, /* in: transaction that has set a record
+ lock */
+ rec_t* rec, /* in: record */
+ ulint lock_mode); /* in: LOCK_S or LOCK_X */
/*************************************************************************
Releases a table lock.
Releases possible other transactions waiting for this lock. */
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index b5da4634d98..4062179483d 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -612,6 +612,31 @@ struct row_prebuilt_struct {
that was decided in ha_innodb.cc,
::store_lock(), ::external_lock(),
etc. */
+ ulint row_read_type; /* ROW_READ_WITH_LOCKS if row locks
+ should be the obtained for records
+ under an UPDATE or DELETE cursor.
+ If innodb_locks_unsafe_for_binlog
+ is TRUE, this can be set to
+ ROW_READ_TRY_SEMI_CONSISTENT, so that
+ if the row under an UPDATE or DELETE
+ cursor was locked by another
+ transaction, InnoDB will resort
+ to reading the last committed value
+ ('semi-consistent read'). Then,
+ this field will be set to
+ ROW_READ_DID_SEMI_CONSISTENT to
+ indicate that. If the row does not
+ match the WHERE condition, MySQL will
+ invoke handler::unlock_row() to
+ clear the flag back to
+ ROW_READ_TRY_SEMI_CONSISTENT and
+ to simply skip the row. If
+ the row matches, the next call to
+ row_search_for_mysql() will lock
+ the row.
+ This eliminates lock waits in some
+ cases; note that this breaks
+ serializability. */
ulint mysql_prefix_len;/* byte offset of the end of
the last requested column */
ulint mysql_row_len; /* length in bytes of a row in the
@@ -657,6 +682,11 @@ struct row_prebuilt_struct {
#define ROW_RETRIEVE_PRIMARY_KEY 1
#define ROW_RETRIEVE_ALL_COLS 2
+/* Values for row_read_type */
+#define ROW_READ_WITH_LOCKS 0
+#define ROW_READ_TRY_SEMI_CONSISTENT 1
+#define ROW_READ_DID_SEMI_CONSISTENT 2
+
#ifndef UNIV_NONINL
#include "row0mysql.ic"
diff --git a/storage/innobase/include/row0vers.h b/storage/innobase/include/row0vers.h
index 079d841f7f3..fafbe9a2402 100644
--- a/storage/innobase/include/row0vers.h
+++ b/storage/innobase/include/row0vers.h
@@ -92,6 +92,32 @@ row_vers_build_for_consistent_read(
record does not exist in the view, that is,
it was freshly inserted afterwards */
+/*********************************************************************
+Constructs the last committed version of a clustered index record,
+which should be seen by a semi-consistent read. */
+
+ulint
+row_vers_build_for_semi_consistent_read(
+/*====================================*/
+ /* out: DB_SUCCESS or DB_MISSING_HISTORY */
+ rec_t* rec, /* in: record in a clustered index; the
+ caller must have a latch on the page; this
+ latch locks the top of the stack of versions
+ of this records */
+ mtr_t* mtr, /* in: mtr holding the latch on rec */
+ dict_index_t* index, /* in: the clustered index */
+ ulint** offsets,/* in/out: offsets returned by
+ rec_get_offsets(rec, index) */
+ mem_heap_t** offset_heap,/* in/out: memory heap from which
+ the offsets are allocated */
+ mem_heap_t* in_heap,/* in: memory heap from which the memory for
+ old_vers is allocated; memory for possible
+ intermediate versions is allocated and freed
+ locally within the function */
+ rec_t** old_vers);/* out, own: rec, old version, or NULL if the
+ record does not exist in the view, that is,
+ it was freshly inserted afterwards */
+
#ifndef UNIV_NONINL
#include "row0vers.ic"
diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
index ae42dc31f82..a3d388f981d 100644
--- a/storage/innobase/lock/lock0lock.c
+++ b/storage/innobase/lock/lock0lock.c
@@ -2386,7 +2386,7 @@ lock_rec_free_all_from_discard_page(
/*****************************************************************
Resets the lock bits for a single record. Releases transactions waiting for
lock requests here. */
-
+static
void
lock_rec_reset_and_release_wait(
/*============================*/
@@ -3748,6 +3748,72 @@ lock_table_dequeue(
/*=========================== LOCK RELEASE ==============================*/
+/*****************************************************************
+Removes a granted record lock of a transaction from the queue and grants
+locks to other transactions waiting in the queue if they now are entitled
+to a lock. */
+
+void
+lock_rec_unlock(
+/*============*/
+ trx_t* trx, /* in: transaction that has set a record
+ lock */
+ rec_t* rec, /* in: record */
+ ulint lock_mode) /* in: LOCK_S or LOCK_X */
+{
+ lock_t* lock;
+ ulint heap_no;
+
+ ut_ad(trx && rec);
+
+ mutex_enter(&kernel_mutex);
+
+ heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec));
+
+ lock = lock_rec_get_first(rec);
+
+ /* Remove the record lock */
+
+ while (lock != NULL) {
+ if (lock->trx == trx && lock_get_mode(lock) == lock_mode) {
+ ut_a(!lock_get_wait(lock));
+
+ lock_rec_reset_nth_bit(lock, heap_no);
+
+ break;
+ }
+
+ lock = lock_rec_get_next(rec, lock);
+ }
+
+ if (UNIV_UNLIKELY(lock == NULL)) {
+ mutex_exit(&kernel_mutex);
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: Error: unlock row could not find a %lu mode lock on the record\n",
+ (ulong)lock_mode);
+
+ return;
+ }
+
+ /* Check if we can now grant waiting lock requests */
+
+ lock = lock_rec_get_first(rec);
+
+ while (lock != NULL) {
+ if (lock_get_wait(lock)
+ && !lock_rec_has_to_wait_in_queue(lock)) {
+
+ /* Grant the lock */
+ lock_grant(lock);
+ }
+
+ lock = lock_rec_get_next(rec, lock);
+ }
+
+ mutex_exit(&kernel_mutex);
+}
+
/*************************************************************************
Releases a table lock.
Releases possible other transactions waiting for this lock. */
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 82f7daf2ed8..1a67ea26f5a 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -626,6 +626,8 @@ row_create_prebuilt(
prebuilt->select_lock_type = LOCK_NONE;
prebuilt->stored_select_lock_type = 99999999;
+ prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
+
prebuilt->sel_graph = NULL;
prebuilt->search_tuple = dtuple_create(heap,
@@ -1486,11 +1488,7 @@ row_unlock_for_mysql(
rec = btr_pcur_get_rec(pcur);
- mutex_enter(&kernel_mutex);
-
- lock_rec_reset_and_release_wait(rec);
-
- mutex_exit(&kernel_mutex);
+ lock_rec_unlock(trx, rec, prebuilt->select_lock_type);
mtr_commit(&mtr);
@@ -1520,11 +1518,7 @@ row_unlock_for_mysql(
rec = btr_pcur_get_rec(clust_pcur);
- mutex_enter(&kernel_mutex);
-
- lock_rec_reset_and_release_wait(rec);
-
- mutex_exit(&kernel_mutex);
+ lock_rec_unlock(trx, rec, prebuilt->select_lock_type);
mtr_commit(&mtr);
}
diff --git a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
index 1b66f14f5d7..b08d27d2916 100644
--- a/storage/innobase/row/row0sel.c
+++ b/storage/innobase/row/row0sel.c
@@ -536,6 +536,41 @@ row_sel_build_prev_vers(
}
/*************************************************************************
+Builds the last committed version of a clustered index record for a
+semi-consistent read. */
+static
+ulint
+row_sel_build_committed_vers_for_mysql(
+/*===================================*/
+ /* out: DB_SUCCESS or error code */
+ dict_index_t* clust_index, /* in: clustered index */
+ row_prebuilt_t* prebuilt, /* in: prebuilt struct */
+ rec_t* rec, /* in: record in a clustered index */
+ ulint** offsets, /* in/out: offsets returned by
+ rec_get_offsets(rec, clust_index) */
+ mem_heap_t** offset_heap, /* in/out: memory heap from which
+ the offsets are allocated */
+ rec_t** old_vers, /* out: old version, or NULL if the
+ record does not exist in the view:
+ i.e., it was freshly inserted
+ afterwards */
+ mtr_t* mtr) /* in: mtr */
+{
+ ulint err;
+
+ if (prebuilt->old_vers_heap) {
+ mem_heap_empty(prebuilt->old_vers_heap);
+ } else {
+ prebuilt->old_vers_heap = mem_heap_create(200);
+ }
+
+ err = row_vers_build_for_semi_consistent_read(rec, mtr, clust_index,
+ offsets, offset_heap,
+ prebuilt->old_vers_heap, old_vers);
+ return(err);
+}
+
+/*************************************************************************
Tests the conditions which determine when the index segment we are searching
through has been exhausted. */
UNIV_INLINE
@@ -3066,7 +3101,6 @@ row_search_for_mysql(
rec_t* rec;
rec_t* result_rec;
rec_t* clust_rec;
- rec_t* old_vers;
ulint err = DB_SUCCESS;
ibool unique_search = FALSE;
ibool unique_search_from_clust_index = FALSE;
@@ -3077,6 +3111,11 @@ row_search_for_mysql(
locking SELECT, and the isolation
level is <= TRX_ISO_READ_COMMITTED,
then this is set to FALSE */
+ ibool did_semi_consistent_read = FALSE;
+ /* if the returned record was locked
+ and we did a semi-consistent read
+ (fetch the newest committed version),
+ then this is set to TRUE */
#ifdef UNIV_SEARCH_DEBUG
ulint cnt = 0;
#endif /* UNIV_SEARCH_DEBUG */
@@ -3163,7 +3202,7 @@ cursor lock count is done correctly. See bugs #12263 and #12456!
trx->search_latch_timeout = BTR_SEA_TIMEOUT;
}
- /* Reset the new record lock info if we srv_locks_unsafe_for_binlog
+ /* Reset the new record lock info if srv_locks_unsafe_for_binlog
is set. Then we are able to remove the record locks set here on an
individual row. */
@@ -3431,9 +3470,28 @@ shortcut_fails_too_big_rec:
clust_index = dict_table_get_first_index(index->table);
if (UNIV_LIKELY(direction != 0)) {
- if (!sel_restore_position_for_mysql(&same_user_rec,
- BTR_SEARCH_LEAF,
- pcur, moves_up, &mtr)) {
+ ibool need_to_process = sel_restore_position_for_mysql(
+ &same_user_rec, BTR_SEARCH_LEAF,
+ pcur, moves_up, &mtr);
+
+ if (UNIV_UNLIKELY(need_to_process)) {
+ if (UNIV_UNLIKELY(prebuilt->row_read_type
+ == ROW_READ_DID_SEMI_CONSISTENT)) {
+ /* We did a semi-consistent read,
+ but the record was removed in
+ the meantime. */
+ prebuilt->row_read_type
+ = ROW_READ_TRY_SEMI_CONSISTENT;
+ }
+ } else if (UNIV_LIKELY(prebuilt->row_read_type
+ != ROW_READ_DID_SEMI_CONSISTENT)) {
+
+ /* The cursor was positioned on the record
+ that we returned previously. If we need
+ to repeat a semi-consistent read as a
+ pessimistic locking read, the record
+ cannot be skipped. */
+
goto next_rec;
}
@@ -3751,7 +3809,64 @@ no_gap_lock:
prebuilt->select_lock_type,
lock_type, thr);
- if (err != DB_SUCCESS) {
+ switch (err) {
+ rec_t* old_vers;
+ case DB_SUCCESS:
+ break;
+ case DB_LOCK_WAIT:
+ if (UNIV_LIKELY(prebuilt->row_read_type
+ != ROW_READ_TRY_SEMI_CONSISTENT)
+ || index != clust_index) {
+
+ goto lock_wait_or_error;
+ }
+
+ /* The following call returns 'offsets'
+ associated with 'old_vers' */
+ err = row_sel_build_committed_vers_for_mysql(
+ clust_index, prebuilt, rec,
+ &offsets, &heap,
+ &old_vers, &mtr);
+
+ if (err != DB_SUCCESS) {
+
+ goto lock_wait_or_error;
+ }
+
+ mutex_enter(&kernel_mutex);
+ if (trx->was_chosen_as_deadlock_victim) {
+ mutex_exit(&kernel_mutex);
+
+ goto lock_wait_or_error;
+ }
+ if (UNIV_LIKELY(trx->wait_lock != NULL)) {
+ lock_cancel_waiting_and_release(
+ trx->wait_lock);
+ trx_reset_new_rec_lock_info(trx);
+ } else {
+ mutex_exit(&kernel_mutex);
+
+ /* The lock was granted while we were
+ searching for the last committed version.
+ Do a normal locking read. */
+
+ offsets = rec_get_offsets(rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ err = DB_SUCCESS;
+ break;
+ }
+ mutex_exit(&kernel_mutex);
+
+ if (old_vers == NULL) {
+ /* The row was not yet committed */
+
+ goto next_rec;
+ }
+
+ did_semi_consistent_read = TRUE;
+ rec = old_vers;
+ break;
+ default:
goto lock_wait_or_error;
}
@@ -3775,6 +3890,7 @@ no_gap_lock:
&& !lock_clust_rec_cons_read_sees(rec, index,
offsets, trx->read_view)) {
+ rec_t* old_vers;
/* The following call returns 'offsets'
associated with 'old_vers' */
err = row_sel_build_prev_vers_for_mysql(
@@ -3821,14 +3937,13 @@ no_gap_lock:
/* The record is delete-marked: we can skip it */
if (srv_locks_unsafe_for_binlog
- && prebuilt->select_lock_type != LOCK_NONE) {
+ && prebuilt->select_lock_type != LOCK_NONE
+ && !did_semi_consistent_read) {
/* No need to keep a lock on a delete-marked record
if we do not want to use next-key locking. */
row_unlock_for_mysql(prebuilt, TRUE);
-
- trx_reset_new_rec_lock_info(trx);
}
goto next_rec;
@@ -3882,8 +3997,6 @@ requires_clust_rec:
locking. */
row_unlock_for_mysql(prebuilt, TRUE);
-
- trx_reset_new_rec_lock_info(trx);
}
goto next_rec;
@@ -3977,7 +4090,7 @@ got_row:
a unique search. */
if (!unique_search_from_clust_index
- || prebuilt->select_lock_type == LOCK_X
+ || prebuilt->select_lock_type != LOCK_NONE
|| prebuilt->used_in_HANDLER) {
/* Inside an update always store the cursor position */
@@ -3990,6 +4103,19 @@ got_row:
goto normal_return;
next_rec:
+ /* Reset the old and new "did semi-consistent read" flags. */
+ if (UNIV_UNLIKELY(prebuilt->row_read_type
+ == ROW_READ_DID_SEMI_CONSISTENT)) {
+ prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
+ }
+ did_semi_consistent_read = FALSE;
+
+ if (UNIV_UNLIKELY(srv_locks_unsafe_for_binlog)
+ && prebuilt->select_lock_type != LOCK_NONE) {
+
+ trx_reset_new_rec_lock_info(trx);
+ }
+
/*-------------------------------------------------------------*/
/* PHASE 5: Move the cursor to the next index record */
@@ -4042,8 +4168,14 @@ not_moved:
goto rec_loop;
lock_wait_or_error:
- /*-------------------------------------------------------------*/
+ /* Reset the old and new "did semi-consistent read" flags. */
+ if (UNIV_UNLIKELY(prebuilt->row_read_type
+ == ROW_READ_DID_SEMI_CONSISTENT)) {
+ prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
+ }
+ did_semi_consistent_read = FALSE;
+ /*-------------------------------------------------------------*/
btr_pcur_store_position(pcur, &mtr);
mtr_commit(&mtr);
@@ -4126,6 +4258,20 @@ func_exit:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
+
+ /* Set or reset the "did semi-consistent read" flag on return.
+ The flag did_semi_consistent_read is set if and only if
+ the record being returned was fetched with a semi-consistent read. */
+ ut_ad(prebuilt->row_read_type != ROW_READ_WITH_LOCKS
+ || !did_semi_consistent_read);
+
+ if (UNIV_UNLIKELY(prebuilt->row_read_type != ROW_READ_WITH_LOCKS)) {
+ if (UNIV_UNLIKELY(did_semi_consistent_read)) {
+ prebuilt->row_read_type = ROW_READ_DID_SEMI_CONSISTENT;
+ } else {
+ prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
+ }
+ }
return(err);
}
diff --git a/storage/innobase/row/row0vers.c b/storage/innobase/row/row0vers.c
index 8e747423047..b32ab8822f4 100644
--- a/storage/innobase/row/row0vers.c
+++ b/storage/innobase/row/row0vers.c
@@ -490,3 +490,141 @@ row_vers_build_for_consistent_read(
return(err);
}
+
+/*********************************************************************
+Constructs the last committed version of a clustered index record,
+which should be seen by a semi-consistent read. */
+
+ulint
+row_vers_build_for_semi_consistent_read(
+/*====================================*/
+ /* out: DB_SUCCESS or DB_MISSING_HISTORY */
+ rec_t* rec, /* in: record in a clustered index; the
+ caller must have a latch on the page; this
+ latch locks the top of the stack of versions
+ of this records */
+ mtr_t* mtr, /* in: mtr holding the latch on rec */
+ dict_index_t* index, /* in: the clustered index */
+ ulint** offsets,/* in/out: offsets returned by
+ rec_get_offsets(rec, index) */
+ mem_heap_t** offset_heap,/* in/out: memory heap from which
+ the offsets are allocated */
+ mem_heap_t* in_heap,/* in: memory heap from which the memory for
+ old_vers is allocated; memory for possible
+ intermediate versions is allocated and freed
+ locally within the function */
+ rec_t** old_vers)/* out, own: rec, old version, or NULL if the
+ record does not exist in the view, that is,
+ it was freshly inserted afterwards */
+{
+ rec_t* version;
+ mem_heap_t* heap = NULL;
+ byte* buf;
+ ulint err;
+ dulint rec_trx_id;
+
+ ut_ad(index->type & DICT_CLUSTERED);
+ ut_ad(mtr_memo_contains(mtr, buf_block_align(rec), MTR_MEMO_PAGE_X_FIX)
+ || mtr_memo_contains(mtr, buf_block_align(rec),
+ MTR_MEMO_PAGE_S_FIX));
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED));
+#endif /* UNIV_SYNC_DEBUG */
+
+ ut_ad(rec_offs_validate(rec, index, *offsets));
+
+ rw_lock_s_lock(&(purge_sys->latch));
+ /* The S-latch on purge_sys prevents the purge view from
+ changing. Thus, if we have an uncommitted transaction at
+ this point, then purge cannot remove its undo log even if
+ the transaction could commit now. */
+
+ version = rec;
+
+ for (;;) {
+ trx_t* version_trx;
+ mem_heap_t* heap2;
+ rec_t* prev_version;
+ dulint version_trx_id;
+
+ version_trx_id = row_get_rec_trx_id(
+ version, index, *offsets);
+ if (rec == version) {
+ rec_trx_id = version_trx_id;
+ }
+
+ mutex_enter(&kernel_mutex);
+ version_trx = trx_get_on_id(version_trx_id);
+ mutex_exit(&kernel_mutex);
+
+ if (!version_trx
+ || version_trx->conc_state == TRX_NOT_STARTED
+ || version_trx->conc_state == TRX_COMMITTED_IN_MEMORY) {
+
+ /* We found a version that belongs to a
+ committed transaction: return it. */
+
+ if (rec == version) {
+ *old_vers = rec;
+ err = DB_SUCCESS;
+ break;
+ }
+
+ /* We assume that a rolled-back transaction stays in
+ TRX_ACTIVE state until all the changes have been
+ rolled back and the transaction is removed from
+ the global list of transactions. */
+
+ if (!ut_dulint_cmp(rec_trx_id, version_trx_id)) {
+ /* The transaction was committed while
+ we searched for earlier versions.
+ Return the current version as a
+ semi-consistent read. */
+
+ version = rec;
+ *offsets = rec_get_offsets(version,
+ index, *offsets,
+ ULINT_UNDEFINED, offset_heap);
+ }
+
+ buf = mem_heap_alloc(in_heap, rec_offs_size(*offsets));
+ *old_vers = rec_copy(buf, version, *offsets);
+ rec_offs_make_valid(*old_vers, index, *offsets);
+ err = DB_SUCCESS;
+
+ break;
+ }
+
+ heap2 = heap;
+ heap = mem_heap_create(1024);
+
+ err = trx_undo_prev_version_build(rec, mtr, version, index,
+ *offsets, heap, &prev_version);
+ if (heap2) {
+ mem_heap_free(heap2); /* free version */
+ }
+
+ if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
+ break;
+ }
+
+ if (prev_version == NULL) {
+ /* It was a freshly inserted version */
+ *old_vers = NULL;
+ err = DB_SUCCESS;
+
+ break;
+ }
+
+ version = prev_version;
+ *offsets = rec_get_offsets(version, index, *offsets,
+ ULINT_UNDEFINED, offset_heap);
+ }/* for (;;) */
+
+ if (heap) {
+ mem_heap_free(heap);
+ }
+ rw_lock_s_unlock(&(purge_sys->latch));
+
+ return(err);
+}