summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeppo Jaakola <seppo.jaakola@codership.com>2013-05-24 15:29:01 +0300
committerSeppo Jaakola <seppo.jaakola@codership.com>2013-05-24 15:29:01 +0300
commit48af4be62a077f5edfadc9b5ea4f6c8c4b00c469 (patch)
tree18ed52e4c23fdea08f654e611ddd30ee760c1377
parente95fdb74ab85bf24b805c1d4ead8c3d3a791b79a (diff)
parent421c885446ddf7a996cecb0d3831f7b1a10d3701 (diff)
downloadmariadb-git-48af4be62a077f5edfadc9b5ea4f6c8c4b00c469.tar.gz
References: MDEV-4572 - merge with mariaDB 5.5.30
-rw-r--r--.bzrignore1
-rw-r--r--CMakeLists.txt6
-rw-r--r--VERSION2
-rw-r--r--client/mysql.cc18
-rw-r--r--client/mysqlbinlog.cc4
-rw-r--r--client/mysqldump.c17
-rw-r--r--cmake/cpack_rpm.cmake34
-rw-r--r--cmake/install_layout.cmake10
-rw-r--r--cmake/os/WindowsCache.cmake1
-rw-r--r--config.h.cmake1
-rw-r--r--configure.cmake12
-rw-r--r--extra/my_print_defaults.c48
-rw-r--r--extra/yassl/src/handshake.cpp8
-rw-r--r--include/myisamchk.h4
-rw-r--r--include/mysql/service_my_snprintf.h1
-rw-r--r--include/mysqld_default_groups.h8
-rw-r--r--include/thread_pool_priv.h1
-rw-r--r--include/welcome_copyright_notice.h4
-rw-r--r--libmysql/CMakeLists.txt13
-rw-r--r--libmysql/get_password.c31
-rw-r--r--libmysql/libmysql_rpm_version.in2
-rw-r--r--mysql-test/CMakeLists.txt6
-rw-r--r--mysql-test/collections/default.daily2
-rw-r--r--mysql-test/collections/default.experimental5
-rw-r--r--mysql-test/collections/default.push11
-rw-r--r--mysql-test/collections/default.release.in8
-rw-r--r--mysql-test/include/get_binlog_dump_thread_id.inc22
-rw-r--r--mysql-test/lib/My/SafeProcess/CMakeLists.txt2
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_process.cc15
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_process.pl166
-rw-r--r--mysql-test/lib/mtr_cases.pm13
-rw-r--r--mysql-test/lib/mtr_report.pm12
-rwxr-xr-xmysql-test/mysql-test-run.pl139
-rw-r--r--mysql-test/r/bug13633383.result10
-rw-r--r--mysql-test/r/ddl_i18n_koi8r.result16
-rw-r--r--mysql-test/r/ddl_i18n_utf8.result16
-rw-r--r--mysql-test/r/derived.result13
-rw-r--r--mysql-test/r/derived_view.result51
-rw-r--r--mysql-test/r/func_group.result2
-rw-r--r--mysql-test/r/gis-rtree.result4
-rw-r--r--mysql-test/r/gis.result24
-rw-r--r--mysql-test/r/group_by.result244
-rw-r--r--mysql-test/r/group_min_max.result104
-rw-r--r--mysql-test/r/group_min_max_innodb.result2
-rw-r--r--mysql-test/r/having.result4
-rw-r--r--mysql-test/r/innodb_ext_key.result94
-rw-r--r--mysql-test/r/join_cache.result2
-rw-r--r--mysql-test/r/join_nested.result22
-rw-r--r--mysql-test/r/join_nested_jcl6.result24
-rw-r--r--mysql-test/r/join_outer.result2
-rw-r--r--mysql-test/r/join_outer_jcl6.result2
-rw-r--r--mysql-test/r/multi_update.result53
-rw-r--r--mysql-test/r/myisam-metadata.result12
-rw-r--r--mysql-test/r/myisam.result29
-rw-r--r--mysql-test/r/mysql.result2
-rw-r--r--mysql-test/r/mysqlbinlog-innodb.result4
-rw-r--r--mysql-test/r/mysqlbinlog.result32
-rw-r--r--mysql-test/r/mysqldump.result24
-rw-r--r--mysql-test/r/row.result4
-rw-r--r--mysql-test/r/select.result20
-rw-r--r--mysql-test/r/select_jcl6.result20
-rw-r--r--mysql-test/r/select_pkeycache.result20
-rw-r--r--mysql-test/r/subselect.result6
-rw-r--r--mysql-test/r/subselect3.result4
-rw-r--r--mysql-test/r/subselect3_jcl6.result4
-rw-r--r--mysql-test/r/subselect_mat.result2
-rw-r--r--mysql-test/r/subselect_mat_cost_bugs.result2
-rw-r--r--mysql-test/r/subselect_no_mat.result6
-rw-r--r--mysql-test/r/subselect_no_scache.result6
-rw-r--r--mysql-test/r/subselect_sj.result28
-rw-r--r--mysql-test/r/subselect_sj2.result2
-rw-r--r--mysql-test/r/subselect_sj2_jcl6.result2
-rw-r--r--mysql-test/r/subselect_sj2_mat.result266
-rw-r--r--mysql-test/r/subselect_sj_jcl6.result28
-rw-r--r--mysql-test/r/subselect_sj_mat.result46
-rw-r--r--mysql-test/r/type_enum.result15
-rw-r--r--mysql-test/r/user_var-binlog.result2
-rw-r--r--mysql-test/r/user_var.result66
-rw-r--r--mysql-test/r/view.result4
-rw-r--r--mysql-test/suite/binlog/r/binlog_base64_flag.result2
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog2.result54
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result2
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result8
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result8
-rw-r--r--mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result2
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_annotate.result12
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result2
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result4
-rw-r--r--mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result2
-rw-r--r--mysql-test/suite/engines/funcs/disabled.def2
-rw-r--r--mysql-test/suite/engines/funcs/r/rpl_row_until.result250
-rw-r--r--mysql-test/suite/engines/funcs/t/rpl_row_until.test170
-rw-r--r--mysql-test/suite/heap/heap.result20
-rw-r--r--mysql-test/suite/heap/heap.test26
-rw-r--r--mysql-test/suite/innodb/disabled.def1
-rw-r--r--mysql-test/suite/innodb/r/innodb-index.result2
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug14147491.result17
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug14676111.result53
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug47777.result4
-rw-r--r--mysql-test/suite/innodb/r/innodb_mysql.result2
-rw-r--r--mysql-test/suite/innodb/t/innodb-zip.test4
-rw-r--r--mysql-test/suite/innodb/t/innodb.test5
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug14147491-master.opt1
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug14147491.test75
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug14676111.test128
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug47777.test6
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug53591.test4
-rw-r--r--mysql-test/suite/innodb/t/innodb_prefix_index_liftedlimit.test4
-rw-r--r--mysql-test/suite/maria/maria-gis-rtree-dynamic.result58
-rw-r--r--mysql-test/suite/maria/maria-gis-rtree-dynamic.test58
-rw-r--r--mysql-test/suite/maria/maria-gis-rtree-trans.result58
-rw-r--r--mysql-test/suite/maria/maria-gis-rtree-trans.test58
-rw-r--r--mysql-test/suite/maria/maria-gis-rtree.result58
-rw-r--r--mysql-test/suite/maria/maria-gis-rtree.test58
-rw-r--r--mysql-test/suite/maria/maria-recovery-rtree-ft.result2
-rw-r--r--mysql-test/suite/maria/maria-recovery-rtree-ft.test2
-rw-r--r--mysql-test/suite/maria/maria.result10
-rw-r--r--mysql-test/suite/maria/maria.test4
-rw-r--r--mysql-test/suite/parts/r/partition_alter4_innodb.result48
-rw-r--r--mysql-test/suite/perfschema/r/start_server_no_waits_history.result63
-rw-r--r--mysql-test/suite/perfschema/r/start_server_no_waits_history_long.result63
-rw-r--r--mysql-test/suite/perfschema/r/start_server_nothing.result122
-rw-r--r--mysql-test/suite/perfschema/t/start_server_no_waits_history-master.opt2
-rw-r--r--mysql-test/suite/perfschema/t/start_server_no_waits_history.test14
-rw-r--r--mysql-test/suite/perfschema/t/start_server_no_waits_history_long-master.opt2
-rw-r--r--mysql-test/suite/perfschema/t/start_server_no_waits_history_long.test14
-rw-r--r--mysql-test/suite/perfschema/t/start_server_nothing-master.opt19
-rw-r--r--mysql-test/suite/perfschema/t/start_server_nothing.test30
-rw-r--r--mysql-test/suite/rpl/disabled.def1
-rw-r--r--mysql-test/suite/rpl/r/replace.result22
-rw-r--r--mysql-test/suite/rpl/r/rpl_bug31076.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_hrtime.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_mdev382.result6
-rw-r--r--mysql-test/suite/rpl/r/rpl_report_port.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result10
-rw-r--r--mysql-test/suite/rpl/r/rpl_sp.result2
-rw-r--r--mysql-test/suite/rpl/r/semisync_memleak_4066.result6
-rw-r--r--mysql-test/suite/rpl/t/replace.test24
-rw-r--r--mysql-test/suite/rpl/t/rpl_bug31076.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_report_port.test6
-rw-r--r--mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock.test2
-rw-r--r--mysql-test/suite/rpl/t/semisync_memleak_4066.test19
-rw-r--r--mysql-test/suite/sys_vars/disabled.def1
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_limit_optimistic_insert_debug_basic.result58
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_max_changed_pages_basic.result (renamed from mysql-test/suite/sys_vars/r/innodb_changed_pages_limit_basic.result)0
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_print_all_deadlocks_basic.result22
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_trx_purge_view_update_only_debug_basic.result62
-rw-r--r--mysql-test/suite/sys_vars/r/ndb_log_update_as_write_basic.result14
-rw-r--r--mysql-test/suite/sys_vars/r/ndb_log_updated_only_basic.result14
-rw-r--r--mysql-test/suite/sys_vars/r/pseudo_slave_mode_basic.result119
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_limit_optimistic_insert_debug_basic.test50
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_max_changed_pages_basic.test (renamed from mysql-test/suite/sys_vars/t/innodb_changed_pages_limit_basic.test)0
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_print_all_deadlocks_basic.test48
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_trx_purge_view_update_only_debug_basic.test54
-rw-r--r--mysql-test/suite/sys_vars/t/ndb_log_update_as_write_basic.test216
-rw-r--r--mysql-test/suite/sys_vars/t/ndb_log_updated_only_basic.test216
-rw-r--r--mysql-test/suite/sys_vars/t/pseudo_slave_mode_basic.test168
-rw-r--r--mysql-test/t/bug13633383.test10
-rw-r--r--mysql-test/t/derived.test15
-rw-r--r--mysql-test/t/derived_view.test34
-rw-r--r--mysql-test/t/gis-rtree.test4
-rw-r--r--mysql-test/t/gis.test18
-rw-r--r--mysql-test/t/group_by.test74
-rw-r--r--mysql-test/t/group_min_max.test59
-rw-r--r--mysql-test/t/information_schema_all_engines-master.opt3
-rw-r--r--mysql-test/t/innodb_ext_key.test76
-rw-r--r--mysql-test/t/join_cache.test2
-rw-r--r--mysql-test/t/multi_update.test52
-rw-r--r--mysql-test/t/myisam-metadata.test49
-rw-r--r--mysql-test/t/myisam.test20
-rw-r--r--mysql-test/t/mysql.test9
-rw-r--r--mysql-test/t/mysqlshow.test2
-rw-r--r--mysql-test/t/select.test19
-rw-r--r--mysql-test/t/subselect_sj2_mat.test226
-rw-r--r--mysql-test/t/type_enum.test15
-rw-r--r--mysql-test/t/user_var.test81
-rw-r--r--mysys/errors.c6
-rw-r--r--mysys/mf_pack.c11
-rw-r--r--mysys/my_lib.c10
-rw-r--r--mysys/my_write.c16
-rw-r--r--mysys/thr_rwlock.c2
-rw-r--r--packaging/WiX/custom_ui.wxs4
-rw-r--r--packaging/rpm-uln/mysql.spec.sh37
-rw-r--r--plugin/auth_socket/CMakeLists.txt14
-rw-r--r--scripts/mysql_install_db.sh2
-rw-r--r--scripts/mysqld_multi.sh2
-rw-r--r--scripts/mysqld_safe.sh15
-rw-r--r--scripts/mysqldumpslow.sh2
-rw-r--r--sql/field.cc24
-rw-r--r--sql/field.h1
-rw-r--r--sql/ha_partition.cc22
-rw-r--r--sql/item_cmpfunc.cc114
-rw-r--r--sql/item_cmpfunc.h81
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/item_subselect.cc3
-rw-r--r--sql/item_sum.cc15
-rw-r--r--sql/item_xmlfunc.cc6
-rw-r--r--sql/log_event.cc18
-rw-r--r--sql/log_event.h18
-rw-r--r--sql/mdl.h10
-rw-r--r--sql/mysqld.cc48
-rw-r--r--sql/opt_range.cc105
-rw-r--r--sql/opt_subselect.cc13
-rw-r--r--sql/rpl_utility.cc9
-rw-r--r--sql/share/errmsg-utf8.txt14
-rw-r--r--sql/slave.cc6
-rw-r--r--sql/spatial.cc32
-rw-r--r--sql/spatial.h9
-rw-r--r--sql/sql_admin.cc36
-rw-r--r--sql/sql_base.cc76
-rw-r--r--sql/sql_base.h35
-rw-r--r--sql/sql_cache.cc22
-rw-r--r--sql/sql_class.cc79
-rw-r--r--sql/sql_class.h6
-rw-r--r--sql/sql_join_cache.cc2
-rw-r--r--sql/sql_lex.cc3
-rw-r--r--sql/sql_list.h4
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_repl.cc6
-rw-r--r--sql/sql_select.cc350
-rw-r--r--sql/sql_select.h22
-rw-r--r--sql/sql_string.cc2
-rw-r--r--sql/sql_table.cc255
-rw-r--r--sql/sql_truncate.cc3
-rw-r--r--sql/sql_update.cc9
-rw-r--r--sql/strfunc.cc2
-rw-r--r--sql/sys_vars.cc58
-rw-r--r--sql/table.cc4
-rw-r--r--sql/table.h32
-rw-r--r--sql/threadpool_unix.cc12
-rw-r--r--sql/transaction.cc20
-rw-r--r--sql/tztime.cc21
-rw-r--r--storage/archive/ha_archive.cc10
-rw-r--r--storage/heap/hp_delete.c54
-rw-r--r--storage/innobase/btr/btr0btr.c38
-rw-r--r--storage/innobase/btr/btr0cur.c8
-rw-r--r--storage/innobase/buf/buf0buf.c147
-rw-r--r--storage/innobase/buf/buf0flu.c24
-rw-r--r--storage/innobase/buf/buf0lru.c42
-rw-r--r--storage/innobase/dict/dict0load.c3
-rw-r--r--storage/innobase/fil/fil0fil.c65
-rw-r--r--storage/innobase/handler/ha_innodb.cc143
-rw-r--r--storage/innobase/handler/handler0alter.cc2
-rw-r--r--storage/innobase/include/btr0cur.h5
-rw-r--r--storage/innobase/include/btr0cur.ic13
-rw-r--r--storage/innobase/include/buf0buf.h29
-rw-r--r--storage/innobase/include/buf0buf.ic8
-rw-r--r--storage/innobase/include/buf0lru.h5
-rw-r--r--storage/innobase/include/data0type.ic32
-rw-r--r--storage/innobase/include/fil0fil.h15
-rw-r--r--storage/innobase/include/lock0lock.h15
-rw-r--r--storage/innobase/include/rem0rec.h80
-rw-r--r--storage/innobase/include/srv0srv.h14
-rw-r--r--storage/innobase/include/trx0purge.h4
-rw-r--r--storage/innobase/include/univ.i12
-rw-r--r--storage/innobase/lock/lock0lock.c265
-rw-r--r--storage/innobase/log/log0recv.c15
-rw-r--r--storage/innobase/rem/rem0rec.c257
-rw-r--r--storage/innobase/row/row0ins.c5
-rw-r--r--storage/innobase/row/row0merge.c117
-rw-r--r--storage/innobase/row/row0mysql.c7
-rw-r--r--storage/innobase/row/row0umod.c3
-rw-r--r--storage/innobase/row/row0undo.c2
-rw-r--r--storage/innobase/srv/srv0srv.c62
-rw-r--r--storage/innobase/trx/trx0purge.c17
-rw-r--r--storage/innobase/trx/trx0rec.c20
-rw-r--r--storage/maria/ha_maria.h1
-rw-r--r--storage/maria/ma_check.c8
-rw-r--r--storage/myisam/ha_myisam.cc2
-rw-r--r--storage/myisam/mi_open.c6
-rw-r--r--storage/myisam/mi_search.c15
-rw-r--r--storage/myisam/myisamchk.c16
-rw-r--r--storage/oqgraph/CMakeLists.txt1
-rw-r--r--storage/perfschema/pfs_events_waits.cc6
-rw-r--r--storage/xtradb/btr/btr0btr.c96
-rw-r--r--storage/xtradb/btr/btr0cur.c34
-rw-r--r--storage/xtradb/buf/buf0buf.c194
-rw-r--r--storage/xtradb/buf/buf0flu.c40
-rw-r--r--storage/xtradb/buf/buf0lru.c176
-rw-r--r--storage/xtradb/buf/buf0rea.c3
-rw-r--r--storage/xtradb/dict/dict0dict.c32
-rw-r--r--storage/xtradb/dict/dict0load.c3
-rw-r--r--storage/xtradb/fil/fil0fil.c143
-rw-r--r--storage/xtradb/handler/ha_innodb.cc274
-rw-r--r--storage/xtradb/handler/ha_innodb.h9
-rw-r--r--storage/xtradb/handler/handler0alter.cc10
-rw-r--r--storage/xtradb/handler/i_s.cc7
-rw-r--r--storage/xtradb/ibuf/ibuf0ibuf.c40
-rw-r--r--storage/xtradb/include/btr0cur.h7
-rw-r--r--storage/xtradb/include/btr0cur.ic13
-rw-r--r--storage/xtradb/include/buf0buf.h53
-rw-r--r--storage/xtradb/include/buf0buf.ic42
-rw-r--r--storage/xtradb/include/buf0lru.h5
-rw-r--r--storage/xtradb/include/data0type.ic32
-rw-r--r--storage/xtradb/include/dict0dict.h2
-rw-r--r--storage/xtradb/include/dict0dict.ic14
-rw-r--r--storage/xtradb/include/dict0mem.h7
-rw-r--r--storage/xtradb/include/fil0fil.h15
-rw-r--r--storage/xtradb/include/lock0lock.h15
-rw-r--r--storage/xtradb/include/log0online.h44
-rw-r--r--storage/xtradb/include/os0file.h2
-rw-r--r--storage/xtradb/include/page0zip.h8
-rw-r--r--storage/xtradb/include/rem0rec.h80
-rw-r--r--storage/xtradb/include/row0undo.h7
-rw-r--r--storage/xtradb/include/row0upd.ic3
-rw-r--r--storage/xtradb/include/srv0srv.h16
-rw-r--r--storage/xtradb/include/sync0sync.h2
-rw-r--r--storage/xtradb/include/trx0purge.h4
-rw-r--r--storage/xtradb/include/univ.i37
-rw-r--r--storage/xtradb/lock/lock0lock.c285
-rw-r--r--storage/xtradb/log/log0online.c319
-rw-r--r--storage/xtradb/log/log0recv.c20
-rw-r--r--storage/xtradb/os/os0file.c23
-rw-r--r--storage/xtradb/page/page0cur.c7
-rw-r--r--storage/xtradb/page/page0page.c24
-rw-r--r--storage/xtradb/page/page0zip.c157
-rw-r--r--storage/xtradb/rem/rem0rec.c257
-rw-r--r--storage/xtradb/row/row0ins.c5
-rw-r--r--storage/xtradb/row/row0merge.c117
-rw-r--r--storage/xtradb/row/row0mysql.c12
-rw-r--r--storage/xtradb/row/row0sel.c33
-rw-r--r--storage/xtradb/row/row0umod.c56
-rw-r--r--storage/xtradb/row/row0undo.c21
-rw-r--r--storage/xtradb/srv/srv0srv.c236
-rw-r--r--storage/xtradb/srv/srv0start.c5
-rw-r--r--storage/xtradb/trx/trx0purge.c17
-rw-r--r--storage/xtradb/trx/trx0rec.c20
-rw-r--r--storage/xtradb/trx/trx0trx.c6
-rw-r--r--strings/decimal.c4
-rw-r--r--strings/my_vsnprintf.c2
-rw-r--r--support-files/mysql.spec.sh1
-rw-r--r--support-files/rpm/server-postin.sh31
332 files changed, 8402 insertions, 3551 deletions
diff --git a/.bzrignore b/.bzrignore
index 5bafcee9b38..32c14cab73d 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1148,3 +1148,4 @@ sql/db.opt
./_CPack_Packages
./install_manifest_*.txt
typescript
+mysql-test/collections/default.release.done
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3e85e9d799e..10f32953f21 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -132,14 +132,10 @@ IF (NOT CPACK_GENERATOR)
ENDIF(WIN32)
ENDIF(NOT CPACK_GENERATOR)
-IF(DEB)
- SET(INSTALL_LAYOUT "DEB")
-ENDIF(DEB)
-
INCLUDE(mysql_version)
-INCLUDE(cpack_rpm)
INCLUDE(cpack_source_ignore_files)
INCLUDE(install_layout)
+INCLUDE(cpack_rpm)
# Add macros
INCLUDE(character_sets)
diff --git a/VERSION b/VERSION
index 1889f4c8aff..3c7056de633 100644
--- a/VERSION
+++ b/VERSION
@@ -1,4 +1,4 @@
MYSQL_VERSION_MAJOR=5
MYSQL_VERSION_MINOR=5
-MYSQL_VERSION_PATCH=29
+MYSQL_VERSION_PATCH=30
MYSQL_VERSION_EXTRA=
diff --git a/client/mysql.cc b/client/mysql.cc
index 67878b36227..ad792abc23f 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -2312,17 +2312,19 @@ static bool add_line(String &buffer,char *line,char *in_string,
{
uint length=(uint) (out-line);
- if (!truncated &&
- (length < 9 ||
- my_strnncoll (charset_info,
- (uchar *)line, 9, (const uchar *) "delimiter", 9)))
+ if (!truncated && (length < 9 ||
+ my_strnncoll (charset_info, (uchar *)line, 9,
+ (const uchar *) "delimiter", 9) ||
+ (*in_string || *ml_comment)))
{
/*
Don't add a new line in case there's a DELIMITER command to be
added to the glob buffer (e.g. on processing a line like
"<command>;DELIMITER <non-eof>") : similar to how a new line is
not added in the case when the DELIMITER is the first command
- entered with an empty glob buffer.
+ entered with an empty glob buffer. However, if the delimiter is
+ part of a string or a comment, the new line should be added. (e.g.
+ SELECT '\ndelimiter\n';\n)
*/
*out++='\n';
length++;
@@ -4723,7 +4725,13 @@ put_info(const char *str,INFO_TYPE info_type, uint error, const char *sqlstate)
if (info_type == INFO_ERROR)
{
if (!opt_nobeep)
+ {
+#ifdef _WIN32
+ MessageBeep(MB_ICONWARNING);
+#else
putchar('\a'); /* This should make a bell */
+#endif
+ }
vidattr(A_STANDOUT);
if (error)
{
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 777e68902dd..2dae59af9ea 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -2430,6 +2430,8 @@ int main(int argc, char** argv)
else
load_processor.init_by_cur_dir();
+ fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;\n");
+
fprintf(result_file,
"/*!40019 SET @@session.max_insert_delayed_threads=0*/;\n");
@@ -2480,6 +2482,8 @@ int main(int argc, char** argv)
"/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n"
"/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");
+ fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;\n");
+
if (tmpdir.list)
free_tmpdir(&tmpdir);
if (result_file != stdout)
diff --git a/client/mysqldump.c b/client/mysqldump.c
index c4dda927c68..11bb74ae1d7 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -2298,7 +2298,6 @@ static uint dump_routines_for_db(char *db)
const char *routine_type[]= {"FUNCTION", "PROCEDURE"};
char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3];
char *routine_name;
- char *query_str;
int i;
FILE *sql_file= md_result_file;
MYSQL_RES *routine_res, *routine_list_res;
@@ -2392,17 +2391,6 @@ static uint dump_routines_for_db(char *db)
fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;\n",
routine_type[i], routine_name);
- query_str= cover_definer_clause(row[2], strlen(row[2]),
- C_STRING_WITH_LEN("50020"),
- C_STRING_WITH_LEN("50003"),
- C_STRING_WITH_LEN(" FUNCTION"));
-
- if (!query_str)
- query_str= cover_definer_clause(row[2], strlen(row[2]),
- C_STRING_WITH_LEN("50020"),
- C_STRING_WITH_LEN("50003"),
- C_STRING_WITH_LEN(" PROCEDURE"));
-
if (mysql_num_fields(routine_res) >= 6)
{
if (switch_db_collation(sql_file, db_name_buff, ";",
@@ -2440,9 +2428,9 @@ static uint dump_routines_for_db(char *db)
fprintf(sql_file,
"DELIMITER ;;\n"
- "/*!50003 %s */;;\n"
+ "%s ;;\n"
"DELIMITER ;\n",
- (const char *) (query_str != NULL ? query_str : row[2]));
+ (const char *) row[2]);
restore_sql_mode(sql_file, ";");
@@ -2457,7 +2445,6 @@ static uint dump_routines_for_db(char *db)
}
}
- my_free(query_str);
}
} /* end of routine printing */
mysql_free_result(routine_res);
diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake
index 0e74b336880..d58b1095cf3 100644
--- a/cmake/cpack_rpm.cmake
+++ b/cmake/cpack_rpm.cmake
@@ -2,7 +2,7 @@ IF(RPM)
SET(CPACK_GENERATOR "RPM")
SET(CPACK_RPM_PACKAGE_DEBUG 1)
-SET(INSTALL_LAYOUT "RPM")
+SET(CPACK_PACKAGING_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX})
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.7)
SET(CPACK_RPM_COMPONENT_INSTALL ON)
@@ -47,9 +47,13 @@ MariaDB bug reports should be submitted through https://mariadb.atlassian.net/
SET(CPACK_RPM_SPEC_MORE_DEFINE "
%define mysql_vendor ${CPACK_PACKAGE_VENDOR}
%define mysqlversion ${MYSQL_NO_DASH_VERSION}
-%define mysqldatadir /var/lib/mysql
+%define mysqlbasedir ${CMAKE_INSTALL_PREFIX}
+%define mysqldatadir ${INSTALL_MYSQLDATADIR}
%define mysqld_user mysql
%define mysqld_group mysql
+%define _bindir ${CMAKE_INSTALL_PREFIX}/${INSTALL_BINDIR}
+%define _sbindir ${CMAKE_INSTALL_PREFIX}/${INSTALL_SBINDIR}
+%define _sysconfdir ${INSTALL_SYSCONFDIR}
")
# this creative hack is described here: http://www.cmake.org/pipermail/cmake/2012-January/048416.html
@@ -66,18 +70,18 @@ SET(ignored
"%ignore /etc"
"%ignore /etc/init.d"
"%ignore /etc/logrotate.d"
- "%ignore /usr"
- "%ignore /usr/bin"
- "%ignore /usr/include"
- "%ignore /usr/lib"
- "%ignore /usr/lib64"
- "%ignore /usr/sbin"
- "%ignore /usr/share"
- "%ignore /usr/share/aclocal"
- "%ignore /usr/share/doc"
- "%ignore /usr/share/man"
- "%ignore /usr/share/man/man1*"
- "%ignore /usr/share/man/man8*"
+ "%ignore ${CMAKE_INSTALL_PREFIX}"
+ "%ignore ${CMAKE_INSTALL_PREFIX}/bin"
+ "%ignore ${CMAKE_INSTALL_PREFIX}/include"
+ "%ignore ${CMAKE_INSTALL_PREFIX}/lib"
+ "%ignore ${CMAKE_INSTALL_PREFIX}/lib64"
+ "%ignore ${CMAKE_INSTALL_PREFIX}/sbin"
+ "%ignore ${CMAKE_INSTALL_PREFIX}/share"
+ "%ignore ${CMAKE_INSTALL_PREFIX}/share/aclocal"
+ "%ignore ${CMAKE_INSTALL_PREFIX}/share/doc"
+ "%ignore ${CMAKE_INSTALL_PREFIX}/share/man"
+ "%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man1*"
+ "%ignore ${CMAKE_INSTALL_PREFIX}/share/man/man8*"
)
SET(CPACK_RPM_server_USER_FILELIST ${ignored} "%config(noreplace) /etc/my.cnf.d/*")
@@ -101,7 +105,7 @@ SET(CPACK_RPM_devel_PACKAGE_OBSOLETES "mysql-devel MySQL-devel MySQL-OurDelta-de
SET(CPACK_RPM_devel_PACKAGE_PROVIDES "MariaDB-devel MySQL-devel mysql-devel")
SET(CPACK_RPM_server_PACKAGE_OBSOLETES "MariaDB mysql mysql-server MySQL-server MySQL-OurDelta-server")
-SET(CPACK_RPM_server_PACKAGE_PROVIDES "MariaDB MariaDB-server MySQL-server config(MariaDB-server) msqlormysql mysql mysql-server")
+SET(CPACK_RPM_server_PACKAGE_PROVIDES "MariaDB MariaDB-server MySQL-server config(MariaDB-server) msqlormysql mysql mysql(x86-32) mysql(x86-64) mysql-server")
SET(CPACK_RPM_server_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES} galera")
SET(CPACK_RPM_server_PRE_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-prein.sh)
SET(CPACK_RPM_server_PRE_UNINSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-preun.sh)
diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake
index 0542b8d2e21..22b0255a22a 100644
--- a/cmake/install_layout.cmake
+++ b/cmake/install_layout.cmake
@@ -67,7 +67,13 @@
# http://forge.mysql.com/wiki/CMake#Fine-tuning_installation_paths
IF(NOT INSTALL_LAYOUT)
- SET(INSTALL_LAYOUT "STANDALONE")
+ IF(DEB)
+ SET(INSTALL_LAYOUT "DEB")
+ ELSEIF(RPM)
+ SET(INSTALL_LAYOUT "RPM")
+ ELSE()
+ SET(INSTALL_LAYOUT "STANDALONE")
+ ENDIF()
ENDIF()
SET(INSTALL_LAYOUT "${INSTALL_LAYOUT}"
@@ -187,7 +193,7 @@ SET(INSTALL_SHAREDIR_DEB "share")
SET(INSTALL_MYSQLSHAREDIR_DEB "share/mysql")
SET(INSTALL_MYSQLTESTDIR_DEB "mysql-test")
SET(INSTALL_SQLBENCHDIR_DEB ".")
-SET(INSTALL_SUPPORTFILESDIR_DEB "support-files")
+SET(INSTALL_SUPPORTFILESDIR_DEB "share/mysql")
#
SET(INSTALL_MYSQLDATADIR_DEB "/var/lib/mysql")
SET(INSTALL_PLUGINTESTDIR_DEB ${plugin_tests})
diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake
index b93a1c12a2e..83ea3b0f3b3 100644
--- a/cmake/os/WindowsCache.cmake
+++ b/cmake/os/WindowsCache.cmake
@@ -267,6 +267,7 @@ SET(HAVE_SYNCH_H CACHE INTERNAL "")
SET(HAVE_SYSENT_H CACHE INTERNAL "")
SET(HAVE_SYS_CDEFS_H CACHE INTERNAL "")
SET(HAVE_SYS_DIR_H CACHE INTERNAL "")
+SET(HAVE_SYS_EVENT_H CACHE INTERNAL "")
SET(HAVE_SYS_ERRLIST CACHE INTERNAL "")
SET(HAVE_SYS_FILE_H CACHE INTERNAL "")
SET(HAVE_SYS_FPU_H CACHE INTERNAL "")
diff --git a/config.h.cmake b/config.h.cmake
index e6ec8b23b58..f8fa5093bbf 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -45,6 +45,7 @@
#cmakedefine HAVE_IA64INTRIN_H 1
#cmakedefine HAVE_IEEEFP_H 1
#cmakedefine HAVE_INTTYPES_H 1
+#cmakedefine HAVE_KQUEUE 1
#cmakedefine HAVE_LIMITS_H 1
#cmakedefine HAVE_LINUX_UNISTD_H 1
#cmakedefine HAVE_LOCALE_H 1
diff --git a/configure.cmake b/configure.cmake
index 05fa80e852f..812baf2c35e 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -160,6 +160,7 @@ IF(UNIX)
SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} wrap)
CHECK_C_SOURCE_COMPILES(
"
+ #include <sys/types.h>
#include <tcpd.h>
int allow_severity = 0;
int deny_severity = 0;
@@ -217,6 +218,7 @@ CHECK_INCLUDE_FILES (sched.h HAVE_SCHED_H)
CHECK_INCLUDE_FILES (select.h HAVE_SELECT_H)
CHECK_INCLUDE_FILES (semaphore.h HAVE_SEMAPHORE_H)
CHECK_INCLUDE_FILES ("sys/types.h;sys/dir.h" HAVE_SYS_DIR_H)
+CHECK_INCLUDE_FILES ("sys/types.h;sys/event.h" HAVE_SYS_EVENT_H)
CHECK_INCLUDE_FILES (sys/ndir.h HAVE_SYS_NDIR_H)
CHECK_INCLUDE_FILES (sys/pte.h HAVE_SYS_PTE_H)
CHECK_INCLUDE_FILES (stddef.h HAVE_STDDEF_H)
@@ -230,13 +232,13 @@ CHECK_INCLUDE_FILES (sys/cdefs.h HAVE_SYS_CDEFS_H)
CHECK_INCLUDE_FILES (sys/file.h HAVE_SYS_FILE_H)
CHECK_INCLUDE_FILES (sys/fpu.h HAVE_SYS_FPU_H)
CHECK_INCLUDE_FILES (sys/ioctl.h HAVE_SYS_IOCTL_H)
-CHECK_INCLUDE_FILES (sys/ipc.h HAVE_SYS_IPC_H)
-CHECK_INCLUDE_FILES (sys/malloc.h HAVE_SYS_MALLOC_H)
+CHECK_INCLUDE_FILES ("sys/types.h;sys/ipc.h" HAVE_SYS_IPC_H)
+CHECK_INCLUDE_FILES ("sys/types.h;sys/malloc.h" HAVE_SYS_MALLOC_H)
CHECK_INCLUDE_FILES (sys/mman.h HAVE_SYS_MMAN_H)
CHECK_INCLUDE_FILES (sys/prctl.h HAVE_SYS_PRCTL_H)
CHECK_INCLUDE_FILES (sys/resource.h HAVE_SYS_RESOURCE_H)
CHECK_INCLUDE_FILES (sys/select.h HAVE_SYS_SELECT_H)
-CHECK_INCLUDE_FILES (sys/shm.h HAVE_SYS_SHM_H)
+CHECK_INCLUDE_FILES ("sys/types.h;sys/shm.h" HAVE_SYS_SHM_H)
CHECK_INCLUDE_FILES (sys/socket.h HAVE_SYS_SOCKET_H)
CHECK_INCLUDE_FILES (sys/stat.h HAVE_SYS_STAT_H)
CHECK_INCLUDE_FILES (sys/stream.h HAVE_SYS_STREAM_H)
@@ -466,6 +468,10 @@ CHECK_FUNCTION_EXISTS (memalign HAVE_MEMALIGN)
CHECK_FUNCTION_EXISTS (chown HAVE_CHOWN)
CHECK_FUNCTION_EXISTS (nl_langinfo HAVE_NL_LANGINFO)
+IF(HAVE_SYS_EVENT_H)
+CHECK_FUNCTION_EXISTS (kqueue HAVE_KQUEUE)
+ENDIF()
+
#--------------------------------------------------------------------
# Support for WL#2373 (Use cycle counter for timing)
#--------------------------------------------------------------------
diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c
index 8a16e677cb9..7558d6d00ae 100644
--- a/extra/my_print_defaults.c
+++ b/extra/my_print_defaults.c
@@ -26,8 +26,13 @@
#include <my_sys.h>
#include <m_string.h>
#include <my_getopt.h>
+#include <mysql_version.h>
+#define load_default_groups mysqld_groups
+#include <mysqld_default_groups.h>
+#undef load_default_groups
+my_bool opt_mysqld;
const char *config_file="my"; /* Default config file */
uint verbose= 0, opt_defaults_file_used= 0;
const char *default_dbug_option="d:t:o,/tmp/my_print_defaults.trace";
@@ -78,6 +83,8 @@ static struct my_option my_long_options[] =
(void *)&my_defaults_extra_file,
(void *)&my_defaults_extra_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"mysqld", 0, "Read the same set of groups that the mysqld binary does.",
+ &opt_mysqld, &opt_mysqld, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"no-defaults", 'n', "Return an empty string (useful for scripts).",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"help", '?', "Display this help message and exit.",
@@ -98,11 +105,12 @@ static void usage(my_bool version)
return;
puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Prints all arguments that is give to some program using the default files");
- printf("Usage: %s [OPTIONS] groups\n", my_progname);
+ printf("Usage: %s [OPTIONS] [groups]\n", my_progname);
my_print_help(my_long_options);
my_print_default_files(config_file);
my_print_variables(my_long_options);
printf("\nExample usage:\n%s --defaults-file=example.cnf client client-server mysql\n", my_progname);
+ exit(0);
}
@@ -115,17 +123,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
opt_defaults_file_used= 1;
break;
case 'n':
- exit(0);
+ exit(0);
case 'I':
case '?':
- usage(0);
- exit(0);
+ usage(0);
case 'v':
verbose++;
break;
case 'V':
- usage(1);
- exit(0);
+ usage(1);
case '#':
DBUG_PUSH(argument ? argument : default_dbug_option);
break;
@@ -141,11 +147,6 @@ static int get_options(int *argc,char ***argv)
if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
exit(ho_error);
- if (*argc < 1)
- {
- usage(0);
- return 1;
- }
return 0;
}
@@ -153,9 +154,10 @@ static int get_options(int *argc,char ***argv)
int main(int argc, char **argv)
{
int count, error, args_used;
- char **load_default_groups, *tmp_arguments[6];
+ char **load_default_groups= 0, *tmp_arguments[6];
char **argument, **arguments, **org_argv;
char *defaults, *extra_defaults, *group_suffix;
+ int nargs, i= 0;
MY_INIT(argv[0]);
org_argv= argv;
@@ -169,13 +171,25 @@ int main(int argc, char **argv)
arguments[count]= 0;
/* Check out the args */
- if (!(load_default_groups=(char**) my_malloc((argc+1)*sizeof(char*),
- MYF(MY_WME))))
- exit(1);
if (get_options(&argc,&argv))
exit(1);
- memcpy((char*) load_default_groups, (char*) argv, (argc + 1) * sizeof(*argv));
+ nargs= argc + 1;
+ if (opt_mysqld)
+ nargs+= array_elements(mysqld_groups);
+
+ if (nargs < 2)
+ usage(0);
+
+ load_default_groups=(char**) my_malloc(nargs*sizeof(char*), MYF(MY_WME));
+ if (!load_default_groups)
+ exit(1);
+ if (opt_mysqld)
+ {
+ for (; mysqld_groups[i]; i++)
+ load_default_groups[i]= (char*) mysqld_groups[i];
+ }
+ memcpy(load_default_groups + i, argv, (argc + 1) * sizeof(*argv));
if ((error= load_defaults(config_file, (const char **) load_default_groups,
&count, &arguments)))
{
@@ -198,6 +212,6 @@ int main(int argc, char **argv)
puts(*argument);
my_free(load_default_groups);
free_defaults(arguments);
-
+ my_end(0);
exit(0);
}
diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp
index c1ee61d043e..c7dbaf86071 100644
--- a/extra/yassl/src/handshake.cpp
+++ b/extra/yassl/src/handshake.cpp
@@ -767,8 +767,14 @@ int DoProcessReply(SSL& ssl)
while (buffer.get_current() < hdr.length_ + RECORD_HEADER + offset) {
// each message in record, can be more than 1 if not encrypted
- if (ssl.getSecurity().get_parms().pending_ == false) // cipher on
+ if (ssl.getSecurity().get_parms().pending_ == false) { // cipher on
+ // sanity check for malicious/corrupted/illegal input
+ if (buffer.get_remaining() < hdr.length_) {
+ ssl.SetError(bad_input);
+ return 0;
+ }
decrypt_message(ssl, buffer, hdr.length_);
+ }
mySTL::auto_ptr<Message> msg(mf.CreateObject(hdr.type_));
if (!msg.get()) {
diff --git a/include/myisamchk.h b/include/myisamchk.h
index 9478936c748..0ee03c03c49 100644
--- a/include/myisamchk.h
+++ b/include/myisamchk.h
@@ -138,9 +138,9 @@ typedef struct st_handler_check_param
/* Following is used to check if rows are visible */
ulonglong max_trid, max_found_trid;
ulonglong not_visible_rows_found;
+ ulonglong sort_buffer_length;
ulonglong use_buffers; /* Used as param to getopt() */
- size_t read_buffer_length, write_buffer_length;
- size_t sort_buffer_length, sort_key_blocks;
+ size_t read_buffer_length, write_buffer_length, sort_key_blocks;
time_t backup_time; /* To sign backup files */
ulong rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY];
double new_rec_per_key_part[HA_MAX_KEY_SEG * HA_MAX_POSSIBLE_KEY];
diff --git a/include/mysql/service_my_snprintf.h b/include/mysql/service_my_snprintf.h
index 57b67f1416d..a7fd3e8a2c6 100644
--- a/include/mysql/service_my_snprintf.h
+++ b/include/mysql/service_my_snprintf.h
@@ -49,6 +49,7 @@
string will be quoted according to MySQL identifier quoting rules.
Both <width> and <precision> can be specified as numbers or '*'.
+ If an asterisk is used, an argument of type int is consumed.
<length modifier> can be 'l', 'll', or 'z'.
diff --git a/include/mysqld_default_groups.h b/include/mysqld_default_groups.h
new file mode 100644
index 00000000000..a2e94ddd854
--- /dev/null
+++ b/include/mysqld_default_groups.h
@@ -0,0 +1,8 @@
+const char *load_default_groups[]= {
+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
+"mysql_cluster",
+#endif
+"mysqld", "server", MYSQL_BASE_VERSION,
+"mariadb", MARIADB_BASE_VERSION,
+"client-server",
+0, 0};
diff --git a/include/thread_pool_priv.h b/include/thread_pool_priv.h
index 78526894e21..84c7faa2e2b 100644
--- a/include/thread_pool_priv.h
+++ b/include/thread_pool_priv.h
@@ -61,6 +61,7 @@ uint thd_get_net_read_write(THD *thd);
void thd_set_mysys_var(THD *thd, st_my_thread_var *mysys_var);
ulong thd_get_net_wait_timeout(THD *thd);
my_socket thd_get_fd(THD *thd);
+int thd_store_globals(THD* thd);
THD *first_global_thread();
THD *next_global_thread(THD *thd);
diff --git a/include/welcome_copyright_notice.h b/include/welcome_copyright_notice.h
index 01139677b7d..9878ab1c07d 100644
--- a/include/welcome_copyright_notice.h
+++ b/include/welcome_copyright_notice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, 2012, Oracle and/or its affiliates.
+/* Copyright (c) 2011, 2013, Oracle and/or its affiliates.
Copyright (c) 2011, 2012, Monty Program Ab
This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@
#ifndef _welcome_copyright_notice_h_
#define _welcome_copyright_notice_h_
-#define COPYRIGHT_NOTICE_CURRENT_YEAR "2012"
+#define COPYRIGHT_NOTICE_CURRENT_YEAR "2013"
/*
This define specifies copyright notice which is displayed by every MySQL
diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
index d23a255e1b7..0bad5934659 100644
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -141,13 +141,14 @@ mysql_load_plugin
mysql_load_plugin_v
mysql_plugin_options
# Async API
+mysql_get_timeout_value
+mysql_get_timeout_value_ms
+mysql_get_socket
mysql_autocommit_cont
mysql_autocommit_start
mysql_change_user_cont
mysql_change_user_start
mysql_close_cont
-mysql_close_slow_part_cont
-mysql_close_slow_part_start
mysql_close_start
mysql_commit_cont
mysql_commit_start
@@ -257,10 +258,12 @@ IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
get_charset
get_charset_by_csname
net_realloc
- client_errors)
+ client_errors
+ THR_KEY_mysys
+ )
# Add special script to fix symbols renames by Fedora
- SET(CLIENT_SOURCES_EXTRA ${CLIENT_SOURCES} rpm_support.cc)
+ SET(CLIENT_SOURCES_EXTRA rpm_support.cc)
SET(VERSION_SCRIPT_TEMPLATE
${CMAKE_CURRENT_SOURCE_DIR}/libmysql_rpm_version.in)
ELSEIF(DEB)
@@ -349,7 +352,7 @@ IF(UNIX)
ENDIF()
IF(NOT DISABLE_SHARED)
- MERGE_LIBRARIES(libmysql SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS} COMPONENT SharedLibraries)
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_EXTRA} COMPONENT SharedLibraries)
IF(UNIX)
# libtool compatability
IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR APPLE)
diff --git a/libmysql/get_password.c b/libmysql/get_password.c
index 16f6b25822d..e65bd6de2f6 100644
--- a/libmysql/get_password.c
+++ b/libmysql/get_password.c
@@ -62,13 +62,34 @@
/* were just going to fake it here and get input from the keyboard */
void get_tty_password_buff(const char *opt_message, char *to, size_t length)
{
+ HANDLE consoleinput;
+ DWORD oldstate;
char *pos=to,*end=to+length-1;
int i=0;
+
+ consoleinput= GetStdHandle(STD_INPUT_HANDLE);
+ if (!consoleinput)
+ {
+ /* This is a GUI application or service without console input, bail out. */
+ *to= 0;
+ return;
+ }
_cputs(opt_message ? opt_message : "Enter password: ");
+
+ /*
+ Switch to raw mode (no line input, no echo input).
+ Allow Ctrl-C handler with ENABLE_PROCESSED_INPUT.
+ */
+ GetConsoleMode(consoleinput, &oldstate);
+ SetConsoleMode(consoleinput, ENABLE_PROCESSED_INPUT);
for (;;)
{
- int tmp;
- tmp=_getch();
+ char tmp;
+ DWORD chars_read;
+ if (!ReadConsole(consoleinput, &tmp, 1, &chars_read, NULL))
+ break;
+ if (chars_read == 0)
+ break;
if (tmp == '\b' || tmp == 127)
{
if (pos != to)
@@ -78,13 +99,15 @@ void get_tty_password_buff(const char *opt_message, char *to, size_t length)
continue;
}
}
- if (tmp == -1 || tmp == '\n' || tmp == '\r' || tmp == 3)
+ if (tmp == '\n' || tmp == '\r')
break;
if (iscntrl(tmp) || pos == end)
continue;
_cputs("*");
- *(pos++) = (char)tmp;
+ *(pos++) = tmp;
}
+ /* Reset console mode after password input. */
+ SetConsoleMode(consoleinput, oldstate);
*pos=0;
_cputs("\n");
}
diff --git a/libmysql/libmysql_rpm_version.in b/libmysql/libmysql_rpm_version.in
index b153b02e381..ff0707cdb75 100644
--- a/libmysql/libmysql_rpm_version.in
+++ b/libmysql/libmysql_rpm_version.in
@@ -21,6 +21,8 @@ libmysqlclient_16 {
my_print_help;
# pure-ftpd requires this
my_make_scrambled_password;
+# fedora18 export
+ THR_KEY_mysys;
# hydra requires this
scramble;
# DBD::mysql requires this
diff --git a/mysql-test/CMakeLists.txt b/mysql-test/CMakeLists.txt
index d065e8935c2..c0ee12fbd23 100644
--- a/mysql-test/CMakeLists.txt
+++ b/mysql-test/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
#
# 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
@@ -154,8 +154,10 @@ ENDMACRO()
FILE(GLOB infiles "collections/*.in")
FOREACH(collin ${infiles})
STRING(REPLACE ".in" "" collection ${collin})
+ STRING(REPLACE ".in" ".done" colldone ${collin})
# Only generate file once
- IF(NOT EXISTS ${collection})
+ IF(NOT EXISTS ${colldone})
PROCESS_COLLECTION_INCLUDE(${collin} ${collection})
+ FILE(APPEND ${colldone} "${collin}\n")
ENDIF()
ENDFOREACH()
diff --git a/mysql-test/collections/default.daily b/mysql-test/collections/default.daily
index e8b15acb34d..665da0d152c 100644
--- a/mysql-test/collections/default.daily
+++ b/mysql-test/collections/default.daily
@@ -1,5 +1,5 @@
-perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=normal --vardir=var-normal --report-features --skip-test-list=collections/disabled-daily.list --unit-tests
+perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=normal --vardir=var-normal --report-features --skip-test-list=collections/disabled-daily.list
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --skip-test-list=collections/disabled-daily.list
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=row --vardir=var-row --mysqld=--binlog-format=row --skip-test-list=collections/disabled-daily.list
perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --mysqld=--binlog-format=row --ps-protocol --skip-test-list=collections/disabled-daily.list
diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental
index 1f4d29968a5..56b8feb6739 100644
--- a/mysql-test/collections/default.experimental
+++ b/mysql-test/collections/default.experimental
@@ -18,9 +18,4 @@ rpl.rpl_row_sp011 @solaris # Bug#11753919 2011-07-25 sven Several
sys_vars.max_sp_recursion_depth_func @solaris # Bug#11753919 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
sys_vars.wait_timeout_func # Bug#11750645 2010-04-26 alik wait_timeout_func fails
-# BUG #59055 : All ndb tests should be removed from the repository
-# Leaving the sys_vars tests for now. sys_vars.all_vars.test fails on removing ndb tests
-sys_vars.ndb_log_update_as_write_basic
-sys_vars.have_ndbcluster_basic
-sys_vars.ndb_log_updated_only_basic
sys_vars.rpl_init_slave_func # Bug#12535301 2011-05-09 andrei sys_vars.rpl_init_slave_func mismatches in daily-5.5
diff --git a/mysql-test/collections/default.push b/mysql-test/collections/default.push
index c8402aecd75..e1781d5082c 100644
--- a/mysql-test/collections/default.push
+++ b/mysql-test/collections/default.push
@@ -1,5 +1,6 @@
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list --unit-tests
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental --skip-ndb
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
-perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental --skip-ndb
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-test-list=collections/disabled-per-push.list
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-test-list=collections/disabled-per-push.list
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-test-list=collections/disabled-per-push.list
+perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental
+
diff --git a/mysql-test/collections/default.release.in b/mysql-test/collections/default.release.in
index 0e3ad30671b..8833086fad9 100644
--- a/mysql-test/collections/default.release.in
+++ b/mysql-test/collections/default.release.in
@@ -4,14 +4,14 @@
# include default.daily
# include default.weekly
-perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=debug --vardir=var-debug --skip-ndbcluster --skip-rpl --report-features --debug-server
-perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=normal --vardir=var-normal --skip-ndbcluster --report-features
-perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=ps --vardir=var-ps --skip-ndbcluster --ps-protocol
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=debug --vardir=var-debug --skip-rpl --report-features --debug-server
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=normal --vardir=var-normal --report-features
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=ps --vardir=var-ps --ps-protocol
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=funcs1+ps --vardir=var-funcs_1_ps --suite=funcs_1 --ps-protocol
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=funcs2 --vardir=var-funcs2 --suite=funcs_2
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=partitions --vardir=var-parts --suite=parts
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=stress --vardir=var-stress --suite=stress
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=jp --vardir=var-jp --suite=jp
-perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-embedded --embedded-server --skip-rpl --skip-ndbcluster
+perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-embedded --embedded-server --skip-rpl
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=nist --vardir=var-nist --suite=nist
perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=nist+ps --vardir=var-nist_ps --suite=nist --ps-protocol
diff --git a/mysql-test/include/get_binlog_dump_thread_id.inc b/mysql-test/include/get_binlog_dump_thread_id.inc
deleted file mode 100644
index bfc8506b39e..00000000000
--- a/mysql-test/include/get_binlog_dump_thread_id.inc
+++ /dev/null
@@ -1,22 +0,0 @@
---exec $MYSQL test -e "show processlist" > $MYSQLTEST_VARDIR/tmp/bl_dump_thread_id
---disable_warnings
-drop table if exists t999;
---enable_warnings
-# Create a table to hold the process list
-create temporary table t999(
- id int,
- user char(255),
- host char(255),
- db char(255),
- Command char(255),
- time int,
- State char(255),
- info char(255)
-);
-# Load processlist into table, headers will create seom warnings
---disable_warnings
---replace_result $MYSQLTEST_VARDIR "."
-eval LOAD DATA INFILE "$MYSQLTEST_VARDIR/tmp/bl_dump_thread_id" into table t999;
---enable_warnings
-let $id = `select Id from t999 where Command="Binlog Dump"`;
-drop table t999;
diff --git a/mysql-test/lib/My/SafeProcess/CMakeLists.txt b/mysql-test/lib/My/SafeProcess/CMakeLists.txt
index 810096805c8..95e23756c30 100644
--- a/mysql-test/lib/My/SafeProcess/CMakeLists.txt
+++ b/mysql-test/lib/My/SafeProcess/CMakeLists.txt
@@ -29,4 +29,4 @@ INSTALL(TARGETS my_safe_process DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/Safe
IF(WIN32)
INSTALL(TARGETS my_safe_kill DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess" COMPONENT Test)
ENDIF()
-INSTALL(FILES safe_process.pl Base.pm DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess" COMPONENT Test)
+INSTALL(FILES Base.pm DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess" COMPONENT Test)
diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc
index ffe11417e7d..f41a77ff6ac 100644
--- a/mysql-test/lib/My/SafeProcess/safe_process.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process.cc
@@ -153,12 +153,19 @@ int main(int argc, char* const argv[] )
pid_t own_pid= getpid();
pid_t parent_pid= getppid();
bool nocore = false;
+ struct sigaction sa,sa_abort;
+ sa.sa_handler= handle_signal;
+ sa.sa_flags= SA_NOCLDSTOP;
+ sigemptyset(&sa.sa_mask);
+
+ sa_abort.sa_handler= handle_abort;
+ sigemptyset(&sa_abort.sa_mask);
/* Install signal handlers */
- signal(SIGTERM, handle_signal);
- signal(SIGINT, handle_signal);
- signal(SIGCHLD, handle_signal);
- signal(SIGABRT, handle_abort);
+ sigaction(SIGTERM, &sa,NULL);
+ sigaction(SIGINT, &sa,NULL);
+ sigaction(SIGCHLD, &sa,NULL);
+ sigaction(SIGABRT, &sa_abort,NULL);
sprintf(safe_process_name, "safe_process[%ld]", (long) own_pid);
diff --git a/mysql-test/lib/My/SafeProcess/safe_process.pl b/mysql-test/lib/My/SafeProcess/safe_process.pl
deleted file mode 100644
index de844e010a1..00000000000
--- a/mysql-test/lib/My/SafeProcess/safe_process.pl
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/usr/bin/perl
-# -*- cperl -*-
-
-# Copyright (c) 2007, 2011, Oracle and/or its affiliates
-#
-# 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; version 2 of the License.
-#
-# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-use strict;
-use warnings;
-
-use lib 'lib';
-use My::SafeProcess::Base;
-use POSIX qw(WNOHANG);
-
-###########################################################################
-# Util functions
-###########################################################################
-
-#
-#Print message to stderr
-#
-my $verbose= 0;
-sub message {
- if ($verbose > 0){
- use Time::localtime;
- my $tm= localtime();
- my $timestamp= sprintf("%02d%02d%02d %2d:%02d:%02d",
- $tm->year % 100, $tm->mon+1, $tm->mday,
- $tm->hour, $tm->min, $tm->sec);
- print STDERR $timestamp, " monitor[$$]: ", @_, "\n";
- }
-}
-
-
-###########################################################################
-# Main program
-###########################################################################
-
-my $terminated= 0;
-
-# Protect against being killed in the middle
-# of child creation, just set the terminated flag
-# to make sure the child will be killed off
-# when program is ready to do that
-$SIG{TERM}= sub { message("!Got signal @_"); $terminated= 1; };
-$SIG{INT}= sub { message("!Got signal @_"); $terminated= 1; };
-
-my $parent_pid= getppid();
-
-my $found_double_dash= 0;
-while (my $arg= shift(@ARGV)){
-
- if ($arg =~ /^--$/){
- $found_double_dash= 1;
- last;
- }
- elsif ($arg =~ /^--verbose$/){
- $verbose= 1;
- }
- else {
- die "Unknown option: $arg";
- }
-}
-
-my $path= shift(@ARGV); # Executable
-
-die "usage:\n" .
- " safe_process.pl [opts] -- <path> [<args> [...<args_n>]]"
- unless defined $path || $found_double_dash;
-
-
-message("started");
-#message("path: '$path'");
-message("parent: $parent_pid");
-
-# Start process to monitor
-my $child_pid=
- create_process(
- path => $path,
- args => \@ARGV,
- setpgrp => 1,
- );
-message("Started child $child_pid");
-
-eval {
- sub handle_signal {
- $terminated= 1;
- message("Got signal @_");
-
- # Ignore all signals
- foreach my $name (keys %SIG){
- $SIG{$name}= 'IGNORE';
- }
-
- die "signaled\n";
- };
- local $SIG{TERM}= \&handle_signal;
- local $SIG{INT}= \&handle_signal;
- local $SIG{CHLD}= sub {
- message("Got signal @_");
- kill('KILL', -$child_pid);
- my $ret= waitpid($child_pid, 0);
- if ($? & 127){
- exit(65); # Killed by signal
- }
- exit($? >> 8);
- };
-
- # Monitoring loop
- while(!$terminated) {
-
- # Check if parent is still alive
- if (kill(0, $parent_pid) < 1){
- message("Parent is not alive anymore");
- last;
- }
-
- # Wait for child to terminate but wakeup every
- # second to also check that parent is still alive
- my $ret_pid;
- $ret_pid= waitpid($child_pid, &WNOHANG);
- if ($ret_pid == $child_pid) {
- # Process has exited, collect return status
- my $ret_code= $? >> 8;
- message("Child exit: $ret_code");
- # Exit with exit status of the child
- exit ($ret_code);
- }
- sleep(1);
- }
-};
-if ( $@ ) {
- # The monitoring loop should have been
- # broken by handle_signal
- warn "Unexpected: $@" unless ( $@ =~ /signaled/ );
-}
-
-# Use negative pid in order to kill the whole
-# process group
-#
-my $ret= kill('KILL', -$child_pid);
-message("Killed child: $child_pid, ret: $ret");
-if ($ret > 0) {
- message("Killed child: $child_pid");
- # Wait blocking for the child to return
- my $ret_pid= waitpid($child_pid, 0);
- if ($ret_pid != $child_pid){
- message("unexpected pid $ret_pid returned from waitpid($child_pid)");
- }
-}
-
-message("DONE!");
-exit (1);
-
-
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index a8db67f1e67..32ec24da492 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -769,18 +769,11 @@ sub collect_one_test_case {
if ( $tinfo->{'ndb_test'} )
{
# This is a NDB test
- if ( $::opt_skip_ndbcluster == 2 )
+ if ( $::ndbcluster_enabled == 0)
{
- # Ndb is not supported, skip it
+ # ndbcluster is disabled
$tinfo->{'skip'}= 1;
- $tinfo->{'comment'}= "No ndbcluster support or ndb tests not enabled";
- return $tinfo;
- }
- elsif ( $::opt_skip_ndbcluster )
- {
- # All ndb test's should be skipped
- $tinfo->{'skip'}= 1;
- $tinfo->{'comment'}= "No ndbcluster";
+ $tinfo->{'comment'}= "ndbcluster disabled";
return $tinfo;
}
}
diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm
index e68ac783369..9ab82c454ed 100644
--- a/mysql-test/lib/mtr_report.pm
+++ b/mysql-test/lib/mtr_report.pm
@@ -28,7 +28,7 @@ our @EXPORT= qw(report_option mtr_print_line mtr_print_thick_line
mtr_warning mtr_error mtr_debug mtr_verbose
mtr_verbose_restart mtr_report_test_passed
mtr_report_test_skipped mtr_print
- mtr_report_test);
+ mtr_report_test isotime);
use mtr_match;
use My::Platform;
@@ -106,6 +106,8 @@ sub mtr_report_test_passed ($) {
$tinfo->{'result'}= 'MTR_RES_PASSED';
mtr_report_test($tinfo);
+
+ resfile_global("endtime ", isotime (time));
}
@@ -550,4 +552,12 @@ sub mtr_verbose_restart (@) {
}
+# Used by --result-file for for formatting times
+
+sub isotime($) {
+ my ($sec,$min,$hr,$day,$mon,$yr)= gmtime($_[0]);
+ return sprintf "%d-%02d-%02dT%02d:%02d:%02dZ",
+ $yr+1900, $mon+1, $day, $hr, $min, $sec;
+}
+
1;
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index e2331e2e454..1001769e4e2 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -333,8 +333,9 @@ sub check_timeout ($) { return testcase_timeout($_[0]) / 10; }
our $opt_warnings= 1;
-our $opt_include_ndbcluster= 0;
-our $opt_skip_ndbcluster= 1;
+our $ndbcluster_enabled= 0;
+my $opt_include_ndbcluster= 0;
+my $opt_skip_ndbcluster= 0;
my $exe_ndbd;
my $exe_ndbmtd;
@@ -361,14 +362,6 @@ my $opt_stop_keep_alive= $ENV{MTR_STOP_KEEP_ALIVE};
select(STDOUT);
$| = 1; # Automatically flush STDOUT
-# Used by --result-file for for formatting times
-
-sub isotime($) {
- my ($sec,$min,$hr,$day,$mon,$yr)= gmtime($_[0]);
- return sprintf "%d-%02d-%02dT%02d:%02d:%02dZ",
- $yr+1900, $mon+1, $day, $hr, $min, $sec;
-}
-
main();
@@ -393,26 +386,6 @@ sub main {
if (!$opt_suites) {
$opt_suites= $DEFAULT_SUITES;
-
- # Check for any extra suites to enable based on the path name
- my %extra_suites=
- (
- "mysql-5.1-new-ndb" => "ndb_team",
- "mysql-5.1-new-ndb-merge" => "ndb_team",
- "mysql-5.1-telco-6.2" => "ndb_team",
- "mysql-5.1-telco-6.2-merge" => "ndb_team",
- "mysql-5.1-telco-6.3" => "ndb_team",
- "mysql-6.0-ndb" => "ndb_team",
- );
-
- foreach my $dir ( reverse splitdir($basedir) ) {
- my $extra_suite= $extra_suites{$dir};
- if (defined $extra_suite) {
- mtr_report("Found extra suite: $extra_suite");
- $opt_suites= "$extra_suite,$opt_suites";
- last;
- }
- }
}
mtr_report("Using suites: $opt_suites") unless @opt_cases;
@@ -762,6 +735,10 @@ sub run_test_server ($$$) {
else {
mtr_report("\nRetrying test $tname, ".
"attempt($retries/$opt_retry)...\n");
+ #saving the log file as filename.failed in case of retry
+ my $worker_logdir= $result->{savedir};
+ my $log_file_name=dirname($worker_logdir)."/".$result->{shortname}.".log";
+ rename $log_file_name,$log_file_name.".failed";
delete($result->{result});
$result->{retries}= $retries+1;
$result->write_test($sock, 'TESTCASE');
@@ -1138,7 +1115,7 @@ sub command_line_setup {
# Control what test suites or cases to run
'force+' => \$opt_force,
'with-ndbcluster-only' => \&collect_option,
- 'include-ndbcluster' => \$opt_include_ndbcluster,
+ 'ndb|include-ndbcluster' => \$opt_include_ndbcluster,
'skip-ndbcluster|skip-ndb' => \$opt_skip_ndbcluster,
'suite|suites=s' => \$opt_suites,
'skip-rpl' => \&collect_option,
@@ -1580,7 +1557,6 @@ sub command_line_setup {
# --------------------------------------------------------------------------
if ( $opt_embedded_server )
{
- $opt_skip_ndbcluster= 1; # Turn off use of NDB cluster
$opt_skip_ssl= 1; # Turn off use of SSL
# Turn off use of bin log
@@ -2036,7 +2012,7 @@ sub executable_setup () {
$exe_mysql_embedded= mtr_exe_maybe_exists("$basedir/libmysqld/examples/mysql_embedded");
- if ( ! $opt_skip_ndbcluster )
+ if ( $ndbcluster_enabled )
{
# Look for single threaded NDB
$exe_ndbd=
@@ -2298,7 +2274,7 @@ sub environment_setup {
# --------------------------------------------------------------------------
# Add the path where libndbclient can be found
# --------------------------------------------------------------------------
- if ( !$opt_skip_ndbcluster )
+ if ( $ndbcluster_enabled )
{
push(@ld_library_paths, "$basedir/storage/ndb/src/.libs");
}
@@ -2391,7 +2367,7 @@ sub environment_setup {
# ----------------------------------------------------
# Setup env for NDB
# ----------------------------------------------------
- if ( ! $opt_skip_ndbcluster )
+ if ( $ndbcluster_enabled )
{
$ENV{'NDB_MGM'}=
my_find_bin($bindir,
@@ -2822,7 +2798,7 @@ sub fix_vs_config_dir () {
$opt_vs_config="";
- for (<$bindir/sql/*/mysqld.exe>) {
+ for (<$bindir/sql/*/mysqld.exe>) { #/
if (-M $_ < $modified)
{
$modified = -M _;
@@ -2864,37 +2840,87 @@ sub vs_config_dirs ($$) {
sub check_ndbcluster_support {
- # Check if this is MySQL Cluster, ie. mysql version string ends
- # with -ndb-Y.Y.Y[-status]
- if ( defined $mysql_version_extra &&
- $mysql_version_extra =~ /^-ndb-/ )
+ my $ndbcluster_supported = 0;
+ if ($mysqld_variables{'ndb-connectstring'})
{
- mtr_report(" - MySQL Cluster");
- # Enable ndb engine and add more test suites
- $opt_include_ndbcluster = 1;
- $DEFAULT_SUITES.=",ndb";
+ $ndbcluster_supported = 1;
}
- if ($opt_include_ndbcluster)
+ if ($opt_skip_ndbcluster && $opt_include_ndbcluster)
{
- $opt_skip_ndbcluster= 0;
+ # User is ambivalent. Theoretically the arg which was
+ # given last on command line should win, but that order is
+ # unknown at this time.
+ mtr_error("Ambigous command, both --include-ndbcluster " .
+ " and --skip-ndbcluster was specified");
}
- if ($opt_skip_ndbcluster)
+ # Check if this is MySQL Cluster, ie. mysql version string ends
+ # with -ndb-Y.Y.Y[-status]
+ if ( defined $mysql_version_extra &&
+ $mysql_version_extra =~ /-ndb-([0-9]*)\.([0-9]*)\.([0-9]*)/ )
{
- mtr_report(" - skipping ndbcluster");
- return;
- }
+ # MySQL Cluster tree
+ mtr_report(" - MySQL Cluster detected");
- if ( ! $mysqld_variables{'ndb-connectstring'} )
- {
- #mtr_report(" - skipping ndbcluster, mysqld not compiled with ndbcluster");
- $opt_skip_ndbcluster= 2;
- return;
+ if ($opt_skip_ndbcluster)
+ {
+ mtr_report(" - skipping ndbcluster(--skip-ndbcluster)");
+ return;
+ }
+
+ if (!$ndbcluster_supported)
+ {
+ # MySQL Cluster tree, but mysqld was not compiled with
+ # ndbcluster -> fail unless --skip-ndbcluster was used
+ mtr_error("This is MySQL Cluster but mysqld does not " .
+ "support ndbcluster. Use --skip-ndbcluster to " .
+ "force mtr to run without it.");
+ }
+
+ # mysqld was compiled with ndbcluster -> auto enable
}
+ else
+ {
+ # Not a MySQL Cluster tree
+ if (!$ndbcluster_supported)
+ {
+ if ($opt_include_ndbcluster)
+ {
+ mtr_error("Could not detect ndbcluster support ".
+ "requested with --include-ndbcluster");
+ }
+
+ # Silently skip, mysqld was compiled without ndbcluster
+ # which is the default case
+ return;
+ }
- mtr_report(" - using ndbcluster when necessary, mysqld supports it");
+ if ($opt_skip_ndbcluster)
+ {
+ # Compiled with ndbcluster but ndbcluster skipped
+ mtr_report(" - skipping ndbcluster(--skip-ndbcluster)");
+ return;
+ }
+
+
+ # Not a MySQL Cluster tree, enable ndbcluster
+ # if --include-ndbcluster was used
+ if ($opt_include_ndbcluster)
+ {
+ # enable ndbcluster
+ }
+ else
+ {
+ mtr_report(" - skipping ndbcluster(disabled by default)");
+ return;
+ }
+ }
+ mtr_report(" - enabling ndbcluster");
+ $ndbcluster_enabled= 1;
+ # Add MySQL Cluster test suites
+ $DEFAULT_SUITES.=",ndb,ndb_binlog,rpl_ndb,ndb_rpl,ndb_memcache";
return;
}
@@ -4745,6 +4771,7 @@ sub extract_warning_lines ($$) {
qr|Error: io_setup\(\) failed|,
qr|Warning: io_setup\(\) failed|,
qr|Warning: io_setup\(\) attempt|,
+ qr|setrlimit could not change the size of core files to 'infinity';|,
);
my $matched_lines= [];
diff --git a/mysql-test/r/bug13633383.result b/mysql-test/r/bug13633383.result
index 89b522724f9..3b533f89df2 100644
--- a/mysql-test/r/bug13633383.result
+++ b/mysql-test/r/bug13633383.result
@@ -4,18 +4,18 @@
CREATE TABLE t1 (
`a` int(11) DEFAULT NULL,
`col432` bit(8) DEFAULT NULL,
-`col433` multipoint DEFAULT NULL,
-`col434` polygon DEFAULT NULL,
+`col433` geometry DEFAULT NULL,
+`col434` geometry DEFAULT NULL,
`col435` decimal(50,17) unsigned DEFAULT NULL,
`col436` geometry NOT NULL,
`col437` tinyblob NOT NULL,
-`col438` multipolygon DEFAULT NULL,
+`col438` geometry DEFAULT NULL,
`col439` mediumblob NOT NULL,
`col440` tinyblob NOT NULL,
`col441` double unsigned DEFAULT NULL
);
CREATE TABLE t2 (
-`a` multipoint DEFAULT NULL,
+`a` geometry DEFAULT NULL,
`col460` date DEFAULT NULL,
`col461` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`col462` date NOT NULL,
@@ -31,7 +31,7 @@ CREATE TABLE t3 (
`col579` bit(38) NOT NULL,
`col580` varchar(93) NOT NULL,
`col581` datetime DEFAULT NULL,
-`col583` multipolygon DEFAULT NULL,
+`col583` geometry DEFAULT NULL,
`col584` bit(47) NOT NULL
);
set session sort_buffer_size= 32768;
diff --git a/mysql-test/r/ddl_i18n_koi8r.result b/mysql-test/r/ddl_i18n_koi8r.result
index 0d858424715..fbed2ac1565 100644
--- a/mysql-test/r/ddl_i18n_koi8r.result
+++ b/mysql-test/r/ddl_i18n_koi8r.result
@@ -734,7 +734,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p1`(
+CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(
INOUT ÐÁÒÁÍ1 CHAR(10),
OUT ÐÁÒÁÍ2 CHAR(10))
BEGIN
@@ -751,7 +751,7 @@ COLLATION(_utf8 'текÑÑ‚') AS c6,
@@character_set_client AS c8;
SET ÐÁÒÁÍ1 = 'a';
SET ÐÁÒÁÍ2 = 'b';
-END */;;
+END ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
@@ -768,7 +768,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p2`(
+CREATE DEFINER=`root`@`localhost` PROCEDURE `p2`(
INOUT ÐÁÒÁÍ1 CHAR(10) CHARACTER SET utf8,
OUT ÐÁÒÁÍ2 CHAR(10) CHARACTER SET utf8)
BEGIN
@@ -785,7 +785,7 @@ COLLATION(_utf8 'текÑÑ‚') AS c6,
@@character_set_client AS c8;
SET ÐÁÒÁÍ1 = 'a';
SET ÐÁÒÁÍ2 = 'b';
-END */;;
+END ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
@@ -810,7 +810,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p3`(
+CREATE DEFINER=`root`@`localhost` PROCEDURE `p3`(
INOUT ÐÁÒÁÍ1 CHAR(10),
OUT ÐÁÒÁÍ2 CHAR(10))
BEGIN
@@ -827,7 +827,7 @@ COLLATION(_utf8 'текÑÑ‚') AS c6,
@@character_set_client AS c8;
SET ÐÁÒÁÍ1 = 'a';
SET ÐÁÒÁÍ2 = 'b';
-END */;;
+END ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
@@ -844,7 +844,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p4`(
+CREATE DEFINER=`root`@`localhost` PROCEDURE `p4`(
INOUT ÐÁÒÁÍ1 CHAR(10) CHARACTER SET utf8,
OUT ÐÁÒÁÍ2 CHAR(10) CHARACTER SET utf8)
BEGIN
@@ -861,7 +861,7 @@ COLLATION(_utf8 'текÑÑ‚') AS c6,
@@character_set_client AS c8;
SET ÐÁÒÁÍ1 = 'a';
SET ÐÁÒÁÍ2 = 'b';
-END */;;
+END ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
diff --git a/mysql-test/r/ddl_i18n_utf8.result b/mysql-test/r/ddl_i18n_utf8.result
index fb32d229040..98da459dafc 100644
--- a/mysql-test/r/ddl_i18n_utf8.result
+++ b/mysql-test/r/ddl_i18n_utf8.result
@@ -734,7 +734,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p1`(
+CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(
INOUT парам1 CHAR(10),
OUT парам2 CHAR(10))
BEGIN
@@ -751,7 +751,7 @@ COLLATION(_koi8r 'ÔÅËÓÔ') AS c6,
@@character_set_client AS c8;
SET парам1 = 'a';
SET парам2 = 'b';
-END */;;
+END ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
@@ -768,7 +768,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p2`(
+CREATE DEFINER=`root`@`localhost` PROCEDURE `p2`(
INOUT парам1 CHAR(10) CHARACTER SET utf8,
OUT парам2 CHAR(10) CHARACTER SET utf8)
BEGIN
@@ -785,7 +785,7 @@ COLLATION(_koi8r 'ÔÅËÓÔ') AS c6,
@@character_set_client AS c8;
SET парам1 = 'a';
SET парам2 = 'b';
-END */;;
+END ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
@@ -810,7 +810,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p3`(
+CREATE DEFINER=`root`@`localhost` PROCEDURE `p3`(
INOUT парам1 CHAR(10),
OUT парам2 CHAR(10))
BEGIN
@@ -827,7 +827,7 @@ COLLATION(_koi8r 'ÔÅËÓÔ') AS c6,
@@character_set_client AS c8;
SET парам1 = 'a';
SET парам2 = 'b';
-END */;;
+END ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
@@ -844,7 +844,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p4`(
+CREATE DEFINER=`root`@`localhost` PROCEDURE `p4`(
INOUT парам1 CHAR(10) CHARACTER SET utf8,
OUT парам2 CHAR(10) CHARACTER SET utf8)
BEGIN
@@ -861,7 +861,7 @@ COLLATION(_koi8r 'ÔÅËÓÔ') AS c6,
@@character_set_client AS c8;
SET парам1 = 'a';
SET парам2 = 'b';
-END */;;
+END ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result
index c6b8bf73a6f..363a4700ee6 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/derived.result
@@ -441,3 +441,16 @@ ERROR 21000: Subquery returns more than 1 row
DROP TABLE t1, t2;
DROP VIEW v1, v2;
set optimizer_switch=@save_derived_optimizer_switch;
+create table t1 (n bigint(20) unsigned, d1 datetime, d2 datetime, key (d1));
+insert t1 values (2085,'2012-01-01 00:00:00','2013-01-01 00:00:00');
+insert t1 values (2084,'2012-02-01 00:00:00','2013-01-01 00:00:00');
+insert t1 values (2088,'2012-03-01 00:00:00','2013-01-01 00:00:00');
+select * from (
+select n, d1, d2, @result := 0 as result
+from t1
+where d1 < '2012-12-12 12:12:12' and n in (2085, 2084) order by d2 asc
+) as calculated_result;
+n d1 d2 result
+2085 2012-01-01 00:00:00 2013-01-01 00:00:00 0
+2084 2012-02-01 00:00:00 2013-01-01 00:00:00 0
+drop table t1;
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index 95ff464918c..8630087ba72 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -2164,6 +2164,57 @@ a
set optimizer_switch=@save3912_optimizer_switch;
drop table t1, t2, t3;
#
+# MDEV-4209: equi-join on BLOB column from materialized view
+# or derived table
+#
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_with_keys=on';
+CREATE TABLE t1 (c1 text, c2 int);
+INSERT INTO t1 VALUES ('a',1), ('c',3), ('g',7), ('d',4), ('c',3);
+CREATE TABLE t2 (c1 text, c2 int);
+INSERT INTO t2 VALUES ('b',2), ('c',3);
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN EXTENDED
+SELECT v1.c1, v1.c2 FROM v1, t2 WHERE v1.c1=t2.c1 AND v1.c2=t2.c2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.c2 2 100.00 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00
+Warnings:
+Note 1003 select `v1`.`c1` AS `c1`,`v1`.`c2` AS `c2` from `test`.`v1` join `test`.`t2` where ((`v1`.`c1` = `test`.`t2`.`c1`) and (`v1`.`c2` = `test`.`t2`.`c2`))
+SELECT v1.c1, v1.c2 FROM v1, t2 WHERE v1.c1=t2.c1 AND v1.c2=t2.c2;
+c1 c2
+c 3
+c 3
+EXPLAIN EXTENDED
+SELECT t2.c1, t2.c2 FROM (SELECT c1 g, MAX(c2) m FROM t1 GROUP BY c1) t, t2
+WHERE t.g=t2.c1 AND t.m=t2.c2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.c2 2 100.00 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `test`.`t2`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2` from (select `test`.`t1`.`c1` AS `g`,max(`test`.`t1`.`c2`) AS `m` from `test`.`t1` group by `test`.`t1`.`c1`) `t` join `test`.`t2` where ((`t`.`g` = `test`.`t2`.`c1`) and (`t`.`m` = `test`.`t2`.`c2`))
+SELECT t2.c1, t2.c2 FROM (SELECT c1 g, MAX(c2) m FROM t1 GROUP BY c1) t, t2
+WHERE t.g=t2.c1 AND t.m=t2.c2;
+c1 c2
+c 3
+EXPLAIN EXTENDED
+SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00
+Warnings:
+Note 1003 select `v1`.`c1` AS `c1`,`v1`.`c2` AS `c2`,`test`.`t2`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2` from `test`.`v1` join `test`.`t2` where (`v1`.`c1` = `test`.`t2`.`c1`)
+SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1;
+c1 c2 c1 c2
+c 3 c 3
+c 3 c 3
+DROP VIEW v1;
+DROP TABLE t1,t2;
+set optimizer_switch=@save_optimizer_switch;
+#
# end of 5.3 tests
#
set optimizer_switch=@exit_optimizer_switch;
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index 65323257300..f1884df2452 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -1851,7 +1851,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 range a a 4 NULL 4 100.00 Using where; Using index; Using join buffer (flat, BNL join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
Warnings:
-Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = 2) and (`test`.`t2`.`a` = 1) and (`test`.`t1`.`a` < 10))
+Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`a` = 1) and (`test`.`t2`.`b` = 2) and (`test`.`t1`.`a` < 10))
SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10;
MAX(a)
NULL
diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result
index 26787366358..c394aec8851 100644
--- a/mysql-test/r/gis-rtree.result
+++ b/mysql-test/r/gis-rtree.result
@@ -758,7 +758,7 @@ SPATIAL KEY(g)
INSERT INTO t1 (g) VALUES (GeomFromText('LineString(1 2, 2 3)')),(GeomFromText('LineString(1 2, 2 4)'));
drop table t1;
CREATE TABLE t1 (
-line LINESTRING NOT NULL,
+line GEOMETRY NOT NULL,
kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po',
name VARCHAR(32),
SPATIAL KEY (line)
@@ -1553,7 +1553,7 @@ End of 5.0 tests.
# Bug #57323/11764487: myisam corruption with insert ignore
# and invalid spatial data
#
-CREATE TABLE t1(a LINESTRING NOT NULL, b GEOMETRY NOT NULL,
+CREATE TABLE t1(a POINT NOT NULL, b GEOMETRY NOT NULL,
SPATIAL KEY(a), SPATIAL KEY(b)) ENGINE=MyISAM;
INSERT INTO t1 VALUES(GEOMFROMTEXT("point (0 0)"), GEOMFROMTEXT("point (1 1)"));
INSERT IGNORE INTO t1 SET a=GEOMFROMTEXT("point (-6 0)"), b=GEOMFROMTEXT("error");
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 30385323502..906ed3f9338 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -1047,7 +1047,7 @@ SET @a=0x00000000030000000100000000000000000000000000144000000000000014400000000
SET @a=POLYFROMWKB(@a);
SET @a=0x00000000030000000000000000000000000000000000144000000000000014400000000000001840000000000000184000000000000014400000000000001440;
SET @a=POLYFROMWKB(@a);
-create table t1(a polygon NOT NULL)engine=myisam;
+create table t1(a geometry NOT NULL)engine=myisam;
insert into t1 values (geomfromtext("point(0 1)"));
insert into t1 values (geomfromtext("point(1 0)"));
select * from (select polygon(t1.a) as p from t1 order by t1.a) d;
@@ -1491,4 +1491,26 @@ SELECT 1 FROM g1 WHERE a >= ANY
(SELECT 1 FROM g1 WHERE a = geomfromtext('') OR a) ;
1
DROP TABLE g1;
+#
+# MDEV-3819 missing constraints for spatial column types
+#
+create table t1 (pt point);
+insert into t1 values(Geomfromtext('POLYGON((1 1, 2 2, 2 1, 1 1))'));
+ERROR 22007: Incorrect POINT value: 'POLYGON' for column 'pt' at row 1
+drop table t1;
+#
+# TODO-424 geometry query crashes server
+#
+select astext(0x0100000000030000000100000000000010);
+astext(0x0100000000030000000100000000000010)
+NULL
+select st_area(0x0100000000030000000100000000000010);
+st_area(0x0100000000030000000100000000000010)
+NULL
+select astext(st_exteriorring(0x0100000000030000000100000000000010));
+astext(st_exteriorring(0x0100000000030000000100000000000010))
+NULL
+select astext(st_centroid(0x0100000000030000000100000000000010));
+astext(st_centroid(0x0100000000030000000100000000000010))
+NULL
End of 5.5 tests
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index 9fb21c3d828..9f9dcd59d56 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -1946,6 +1946,250 @@ Warning 1292 Truncated incorrect INTEGER value: 'K'
Warning 1292 Truncated incorrect INTEGER value: 'jxW<'
DROP TABLE t1;
SET SQL_BIG_TABLES=0;
+#
+# MDEV-641 LP:1002108 - Wrong result (or crash) from a query with duplicated field in the group list and a limit clause
+# Bug#11761078: 53534: INCORRECT 'SELECT SQL_BIG_RESULT...'
+# WITH GROUP BY ON DUPLICATED FIELDS
+#
+CREATE TABLE t1(
+col1 int,
+UNIQUE INDEX idx (col1));
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),
+(11),(12),(13),(14),(15),(16),(17),(18),(19),(20);
+EXPLAIN SELECT col1 AS field1, col1 AS field2
+FROM t1 GROUP BY field1, field2;;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL idx 5 NULL 20 Using index; Using temporary; Using filesort
+FLUSH STATUS;
+SELECT col1 AS field1, col1 AS field2
+FROM t1 GROUP BY field1, field2;;
+field1 field2
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+13 13
+14 14
+15 15
+16 16
+17 17
+18 18
+19 19
+20 20
+SHOW SESSION STATUS LIKE 'Sort_scan%';
+Variable_name Value
+Sort_scan 1
+EXPLAIN SELECT SQL_BIG_RESULT col1 AS field1, col1 AS field2
+FROM t1 GROUP BY field1, field2;;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL idx 5 NULL 20 Using index; Using filesort
+FLUSH STATUS;
+SELECT SQL_BIG_RESULT col1 AS field1, col1 AS field2
+FROM t1 GROUP BY field1, field2;;
+field1 field2
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+13 13
+14 14
+15 15
+16 16
+17 17
+18 18
+19 19
+20 20
+SHOW SESSION STATUS LIKE 'Sort_scan%';
+Variable_name Value
+Sort_scan 1
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT SQL_BIG_RESULT col1 AS field1, col1 AS field2
+FROM v1
+GROUP BY field1, field2;
+field1 field2
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+13 13
+14 14
+15 15
+16 16
+17 17
+18 18
+19 19
+20 20
+SELECT SQL_BIG_RESULT tbl1.col1 AS field1, tbl2.col1 AS field2
+FROM t1 as tbl1, t1 as tbl2
+GROUP BY field1, field2
+LIMIT 3;
+field1 field2
+1 1
+1 2
+1 3
+explain
+select col1 f1, col1 f2 from t1 order by f2, f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL idx 5 NULL 20 Using index; Using filesort
+select col1 f1, col1 f2 from t1 order by f2, f1;
+f1 f2
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+13 13
+14 14
+15 15
+16 16
+17 17
+18 18
+19 19
+20 20
+explain
+select col1 f1, col1 f2 from t1 group by f2 order by f2, f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range NULL idx 5 NULL 7 Using index for group-by; Using temporary; Using filesort
+select col1 f1, col1 f2 from t1 group by f2 order by f2, f1;
+f1 f2
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+13 13
+14 14
+15 15
+16 16
+17 17
+18 18
+19 19
+20 20
+explain
+select col1 f1, col1 f2 from t1 group by f1, f2 order by f2, f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL idx 5 NULL 20 Using index; Using temporary; Using filesort
+select col1 f1, col1 f2 from t1 group by f1, f2 order by f2, f1;
+f1 f2
+1 1
+2 2
+3 3
+4 4
+5 5
+6 6
+7 7
+8 8
+9 9
+10 10
+11 11
+12 12
+13 13
+14 14
+15 15
+16 16
+17 17
+18 18
+19 19
+20 20
+CREATE TABLE t2(
+col1 int,
+col2 int,
+UNIQUE INDEX idx (col1, col2));
+INSERT INTO t2(col1, col2) VALUES
+(1,20),(2,19),(3,18),(4,17),(5,16),(6,15),(7,14),(8,13),(9,12),(10,11),
+(11,10),(12,9),(13,8),(14,7),(15,6),(16,5),(17,4),(18,3),(19,2),(20,1);
+explain
+select col1 f1, col2 f2, col1 f3 from t2 group by f1, f2, f3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL idx 10 NULL 20 Using index; Using temporary; Using filesort
+select col1 f1, col2 f2, col1 f3 from t2 group by f1, f2, f3;
+f1 f2 f3
+1 20 1
+2 19 2
+3 18 3
+4 17 4
+5 16 5
+6 15 6
+7 14 7
+8 13 8
+9 12 9
+10 11 10
+11 10 11
+12 9 12
+13 8 13
+14 7 14
+15 6 15
+16 5 16
+17 4 17
+18 3 18
+19 2 19
+20 1 20
+explain
+select col1 f1, col2 f2, col1 f3 from t2 order by f1, f2, f3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL idx 10 NULL 20 Using index; Using filesort
+select col1 f1, col2 f2, col1 f3 from t2 order by f1, f2, f3;
+f1 f2 f3
+1 20 1
+2 19 2
+3 18 3
+4 17 4
+5 16 5
+6 15 6
+7 14 7
+8 13 8
+9 12 9
+10 11 10
+11 10 11
+12 9 12
+13 8 13
+14 7 14
+15 6 15
+16 5 16
+17 4 17
+18 3 18
+19 2 19
+20 1 20
+DROP VIEW v1;
+DROP TABLE t1, t2;
# End of 5.1 tests
#
# LP bug#694450 Wrong result with non-standard GROUP BY + ORDER BY
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index d1faec7f758..cc7c9c4d364 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -1714,7 +1714,7 @@ explain extended select distinct a1,a2,b,c from t1 where (a2 >= 'b') and (b = 'a
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index NULL idx_t1_1 163 NULL 128 50.78 Using where; Using index
Warnings:
-Note 1003 select distinct `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`c` = 'i121') and (`test`.`t1`.`b` = 'a') and (`test`.`t1`.`a2` >= 'b'))
+Note 1003 select distinct `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c` from `test`.`t1` where ((`test`.`t1`.`b` = 'a') and (`test`.`t1`.`c` = 'i121') and (`test`.`t1`.`a2` >= 'b'))
explain select distinct a1,a2,b from t1 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range idx_t1_0,idx_t1_1,idx_t1_2 idx_t1_1 147 NULL 14 Using where; Using index for group-by
@@ -1731,7 +1731,7 @@ explain extended select distinct a1,a2,b,c from t2 where (a2 >= 'b') and (b = 'a
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 index NULL idx_t2_1 163 NULL 164 50.61 Using where; Using index
Warnings:
-Note 1003 select distinct `test`.`t2`.`a1` AS `a1`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where ((`test`.`t2`.`c` = 'i121') and (`test`.`t2`.`b` = 'a') and (`test`.`t2`.`a2` >= 'b'))
+Note 1003 select distinct `test`.`t2`.`a1` AS `a1`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t2` where ((`test`.`t2`.`b` = 'a') and (`test`.`t2`.`c` = 'i121') and (`test`.`t2`.`a2` >= 'b'))
explain select distinct a1,a2,b from t2 where (a1 > 'a') and (a2 > 'a') and (b = 'c');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range idx_t2_0,idx_t2_1,idx_t2_2 idx_t2_1 146 NULL # Using where; Using index for group-by
@@ -3187,6 +3187,106 @@ a b
drop table t1;
End of 5.1 tests
#
+# MDEV-765 lp:825075 - Wrong result with GROUP BY + multipart key + MIN/MAX loose scan
+#
+CREATE TABLE t1 (a varchar(1), b varchar(1), KEY (b,a));
+INSERT INTO t1 VALUES
+('0',NULL),('9',NULL),('8','c'),('4','d'),('7','d'),(NULL,'f'),
+('7','f'),('8','g'),(NULL,'j');
+explain
+SELECT max(a) , b FROM t1 WHERE a IS NULL OR b = 'z' GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index b b 8 NULL 9 Using where; Using index
+SELECT max(a) , b FROM t1 WHERE a IS NULL OR b = 'z' GROUP BY b;
+max(a) b
+NULL f
+NULL j
+explain
+SELECT b, min(a) FROM t1 WHERE a = '7' OR b = 'z' GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index b b 8 NULL 9 Using where; Using index
+SELECT b, min(a) FROM t1 WHERE a = '7' OR b = 'z' GROUP BY b;
+b min(a)
+d 7
+f 7
+explain
+SELECT b, min(a) FROM t1 WHERE (a = b OR b = 'd' OR b is NULL) GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index b b 8 NULL 9 Using where; Using index
+SELECT b, min(a) FROM t1 WHERE (a = b OR b = 'd' OR b is NULL) GROUP BY b;
+b min(a)
+NULL 0
+d 4
+explain
+SELECT b, min(a) FROM t1 WHERE a > ('0' = b) AND b = 'z' GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref b b 4 const 1 Using where; Using index
+SELECT b, min(a) FROM t1 WHERE a > ('0' = b) AND b = 'z' GROUP BY b;
+b min(a)
+explain
+SELECT b, min(a) FROM t1 WHERE a > '0' AND (b < (a = '7')) GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL b 8 NULL 9 Using where; Using index
+SELECT b, min(a) FROM t1 WHERE a > '0' AND (b < (a = '7')) GROUP BY b;
+b min(a)
+d 7
+f 7
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'c'
+Warning 1292 Truncated incorrect DOUBLE value: 'd'
+Warning 1292 Truncated incorrect DOUBLE value: 'd'
+Warning 1292 Truncated incorrect DOUBLE value: 'f'
+Warning 1292 Truncated incorrect DOUBLE value: 'g'
+explain
+SELECT b, min(a) FROM t1 WHERE (a > '0' AND (a > '1' OR b = 'd')) GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index b b 8 NULL 9 Using where; Using index
+SELECT b, min(a) FROM t1 WHERE (a > '0' AND (a > '1' OR b = 'd')) GROUP BY b;
+b min(a)
+NULL 9
+c 8
+d 4
+f 7
+g 8
+drop table t1;
+#
+# MDEV-4140 Wrong result with GROUP BY + multipart key + MIN/MAX loose scan and a subquery
+#
+CREATE TABLE t1 (a int, b int, KEY (b, a)) ;
+INSERT INTO t1 VALUES (0,99),(9,99),(4,0),(7,0),(99,0),(7,0),(8,0),(99,0),(1,0);
+CREATE TABLE t2 (c int) ;
+INSERT INTO t2 VALUES (0),(1);
+EXPLAIN
+SELECT MIN(a), b FROM t1 WHERE a > 0 GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range NULL b 10 NULL 10 Using where; Using index for group-by
+SELECT MIN(a), b FROM t1 WHERE a > 0 GROUP BY b;
+MIN(a) b
+1 0
+9 99
+EXPLAIN
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT c FROM t2 WHERE c = 0 ) GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 range NULL b 10 NULL 10 Using where; Using index for group-by
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT c FROM t2 WHERE c = 0 ) GROUP BY b;
+MIN(a) b
+1 0
+9 99
+EXPLAIN
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT min(c) FROM t2, t1 t1a, t1 t1b WHERE c = 0 ) GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL b 10 NULL 9 Using where; Using index
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY t1a index NULL b 10 NULL 9 Using index; Using join buffer (flat, BNL join)
+2 SUBQUERY t1b index NULL b 10 NULL 9 Using index; Using join buffer (incremental, BNL join)
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT min(c) FROM t2, t1 t1a, t1 t1b WHERE c = 0 ) GROUP BY b;
+MIN(a) b
+1 0
+9 99
+drop table t1, t2;
+End of 5.3 tests
+#
# WL#3220 (Loose index scan for COUNT DISTINCT)
#
CREATE TABLE t1 (a INT, b INT, c INT, KEY (a,b));
diff --git a/mysql-test/r/group_min_max_innodb.result b/mysql-test/r/group_min_max_innodb.result
index 0e7841e979d..320c4b2b750 100644
--- a/mysql-test/r/group_min_max_innodb.result
+++ b/mysql-test/r/group_min_max_innodb.result
@@ -70,7 +70,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index; Using temporary
explain select distinct f1, f2 from t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL PRIMARY 5 NULL 3 Using index for group-by; Using temporary
+1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index
drop table t1;
create table t1(pk int primary key) engine=innodb;
create view v1 as select pk from t1 where pk < 20;
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index 5961a84cddc..a0a4fc42e2d 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -473,7 +473,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE table2 const PRIMARY PRIMARY 4 const 1 100.00 Using filesort
1 SIMPLE table1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
-Note 1003 select `test`.`table1`.`f1` AS `f1`,7 AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = 9)) group by `test`.`table1`.`f1`,7 having ((7 = 8) and (`test`.`table1`.`f1` >= 6))
+Note 1003 select `test`.`table1`.`f1` AS `f1`,7 AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where (`test`.`table1`.`f3` = 9) group by `test`.`table1`.`f1`,7 having ((7 = 8) and (`test`.`table1`.`f1` >= 6))
EXPLAIN EXTENDED
SELECT table1.f1, table2.f2
FROM t1 AS table1
@@ -485,7 +485,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE table2 const PRIMARY PRIMARY 4 const 1 100.00 Using filesort
1 SIMPLE table1 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
-Note 1003 select `test`.`table1`.`f1` AS `f1`,7 AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where ((`test`.`table1`.`f3` = 9)) group by `test`.`table1`.`f1`,7 having (7 = 8)
+Note 1003 select `test`.`table1`.`f1` AS `f1`,7 AS `f2` from `test`.`t1` `table1` join `test`.`t1` `table2` where (`test`.`table1`.`f3` = 9) group by `test`.`table1`.`f1`,7 having (7 = 8)
DROP TABLE t1;
#
# Bug#52336 Segfault / crash in 5.1 copy_fields (param=0x9872980) at sql_select.cc:15355
diff --git a/mysql-test/r/innodb_ext_key.result b/mysql-test/r/innodb_ext_key.result
index 4e441245a39..0da4feaf26f 100644
--- a/mysql-test/r/innodb_ext_key.result
+++ b/mysql-test/r/innodb_ext_key.result
@@ -731,6 +731,7 @@ CREATE TABLE t2 (b int) ENGINE=MyISAM;
INSERT INTO t1 (a) VALUES (4), (6);
INSERT INTO t2 (b) VALUES (0), (8);
set @save_optimizer_switch=@@optimizer_switch;
+set @save_join_cache_level=@@join_cache_level;
SET join_cache_level=3;
SET optimizer_switch='join_cache_hashed=on';
SET optimizer_switch='join_cache_bka=on';
@@ -742,6 +743,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 hash_ALL NULL #hash#$hj 5 test.t1.a 2 Using where; Using join buffer (flat, BNLH join)
SELECT * FROM t1, t2 WHERE b=a;
a b
+set join_cache_level=@save_join_cache_level;
set optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2;
#
@@ -772,5 +774,97 @@ INSERT INTO t1 (c2, c3, c4) VALUES (58291525, 2580, 'foobar')
ON DUPLICATE KEY UPDATE c4 = VALUES(c4);
set optimizer_switch=@save_optimizer_switch;
DROP TABLE t1;
+#
+# Bug mdev-4220: using ref instead of eq_ref
+# with extended_keys=on
+# (performance regression introduced in the patch for mdev-3851)
+#
+set @save_optimizer_switch=@@optimizer_switch;
+create table t1 (a int not null) engine=innodb;
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (
+pk int primary key, a int not null, b int, unique(a)
+)engine=innodb;
+insert into t2
+select
+A.a + 10 * B.a, A.a + 10 * B.a, A.a + 10 * B.a
+from t1 A, t1 B;
+set optimizer_switch='extended_keys=off';
+explain
+select * from t1, t2 where t2.a=t1.a and t2.b < 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 10
+1 SIMPLE t2 eq_ref a a 4 test.t1.a 1 Using where
+flush status;
+select * from t1, t2 where t2.a=t1.a and t2.b < 2;
+a pk a b
+0 0 0 0
+1 1 1 1
+show status like 'handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 10
+Handler_read_last 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 11
+set optimizer_switch='extended_keys=on';
+explain
+select * from t1, t2 where t2.a=t1.a and t2.b < 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 10
+1 SIMPLE t2 eq_ref a a 4 test.t1.a 1 Using where
+flush status;
+select * from t1, t2 where t2.a=t1.a and t2.b < 2;
+a pk a b
+0 0 0 0
+1 1 1 1
+show status like 'handler_read%';
+Variable_name Value
+Handler_read_first 0
+Handler_read_key 10
+Handler_read_last 0
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 0
+Handler_read_rnd_deleted 0
+Handler_read_rnd_next 11
+drop table t1,t2;
+create table t1(a int) engine=myisam;
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2(a int) engine=myisam;
+insert into t2 select A.a + 10*B.a + 100*C.a from t1 A, t1 B, t1 C;
+create table t3 (
+pk1 int not null, pk2 int not null, col1 int not null, col2 int not null)
+engine=innodb;
+insert into t3 select a,a,a,a from t2;
+alter table t3 add primary key (pk1, pk2);
+alter table t3 add key (col1, col2);
+set optimizer_switch='extended_keys=off';
+explain
+select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where
+1 SIMPLE t3 ref col1 col1 8 test.t1.a,test.t1.a # Using index
+explain
+select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where
+1 SIMPLE t3 ref PRIMARY,col1 PRIMARY 4 test.t1.a # Using where
+set optimizer_switch='extended_keys=on';
+explain
+select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where
+1 SIMPLE t3 ref col1 col1 8 test.t1.a,test.t1.a # Using index
+explain
+select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL # Using where
+1 SIMPLE t3 ref PRIMARY,col1 col1 12 test.t1.a,test.t1.a,test.t1.a # Using index
+drop table t1,t2,t3;
+set optimizer_switch=@save_optimizer_switch;
set optimizer_switch=@save_ext_key_optimizer_switch;
SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result
index bb455f2b39a..618ce7e540b 100644
--- a/mysql-test/r/join_cache.result
+++ b/mysql-test/r/join_cache.result
@@ -5595,7 +5595,7 @@ DROP TABLE t1,t2,t3;
#
CREATE TABLE t1 (
col269 decimal(31,10) unsigned DEFAULT NULL,
-col280 multipoint DEFAULT NULL,
+col280 geometry DEFAULT NULL,
col281 tinyint(1) DEFAULT NULL,
col282 time NOT NULL,
col284 datetime DEFAULT NULL,
diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result
index dfb1a8c72d3..255714a7236 100644
--- a/mysql-test/r/join_nested.result
+++ b/mysql-test/r/join_nested.result
@@ -235,7 +235,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t8`.`b` = `test`.`t7`.`b`))) where 1
+Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t7`.`b`) and (`test`.`t6`.`b` < 10))) where 1
SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
FROM (t6, t7)
LEFT JOIN
@@ -556,7 +556,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
FROM t0,t1
@@ -652,7 +652,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
SELECT t9.a,t9.b
FROM t9;
a b
@@ -858,7 +858,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 2 100.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(((`test`.`t2`.`a` > 0) and (`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`b`) and (`test`.`t3`.`b` is not null))) where 1
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`a` > 0) and (`test`.`t3`.`b` is not null))) where 1
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
@@ -920,7 +920,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t2`.`a` > 0) and (`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`a` > 0))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
INSERT INTO t4 VALUES (-3,12,0), (-4,13,0), (-1,11,0), (-3,11,0), (-5,15,0);
INSERT INTO t5 VALUES (-3,11,0), (-2,12,0), (-3,13,0), (-4,12,0);
CREATE INDEX idx_b ON t4(b);
@@ -972,7 +972,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t2`.`a` > 0) and (`test`.`t4`.`a` > 0) and (`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and ((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`))))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t5`.`a` > 0) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`a` > 0) and (`test`.`t4`.`a` > 0) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`a` > 0)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
INSERT INTO t8 VALUES (-3,12,0), (-1,14,0), (-5,15,0), (-1,11,0), (-4,13,0);
CREATE INDEX idx_b ON t8(b);
EXPLAIN EXTENDED
@@ -1022,7 +1022,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t2`.`a` > 0) and (`test`.`t4`.`a` > 0) and (`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t8`.`a` >= 0) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t5`.`a` > 0) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`a` > 0) and (`test`.`t4`.`a` > 0) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t8`.`a` >= 0) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`a` > 0)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
INSERT INTO t1 VALUES (-1,133,0), (-2,12,0), (-3,11,0), (-5,15,0);
CREATE INDEX idx_b ON t1(b);
CREATE INDEX idx_a ON t0(a);
@@ -1073,7 +1073,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2) and (`test`.`t1`.`a` > 0))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2) and (`test`.`t1`.`a` > 0))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
FROM t0,t1
@@ -1215,7 +1215,7 @@ EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using index
1 SIMPLE t3 index c c 5 NULL 6 Using where; Using index
-1 SIMPLE t2 ref b b 5 test.t3.c 2 Using where; Using index
+1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index
SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
a b c
NULL 0 0
@@ -1286,7 +1286,7 @@ EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using index
1 SIMPLE t3 index c c 5 NULL 0 Using where; Using index
-1 SIMPLE t2 ref b b 5 test.t3.c 2 Using where; Using index
+1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index
SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
a b c
NULL NULL NULL
@@ -1843,7 +1843,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 ALL NULL NULL NULL NULL 1 100.00 Using where; Not exists
1 SIMPLE t4 ALL NULL NULL NULL NULL 0 0.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`b` AS `b` from `test`.`t1` left join (`test`.`t2` left join `test`.`t3` on(((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t3`.`b` = `test`.`t1`.`a`))) left join `test`.`t4` on((`test`.`t4`.`b` = `test`.`t3`.`a`))) on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where isnull(`test`.`t3`.`a`)
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`b` AS `b` from `test`.`t1` left join (`test`.`t2` left join `test`.`t3` on((`test`.`t3`.`b` = `test`.`t1`.`a`)) left join `test`.`t4` on((`test`.`t4`.`b` = `test`.`t3`.`a`))) on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where isnull(`test`.`t3`.`a`)
DROP TABLE t1,t2,t3,t4;
SET optimizer_switch=@save_optimizer_switch;
End of 5.0 tests
diff --git a/mysql-test/r/join_nested_jcl6.result b/mysql-test/r/join_nested_jcl6.result
index 69eb4532c73..c744df9e2fe 100644
--- a/mysql-test/r/join_nested_jcl6.result
+++ b/mysql-test/r/join_nested_jcl6.result
@@ -246,7 +246,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join)
1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t7.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
Warnings:
-Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t8`.`b` = `test`.`t7`.`b`) and (`test`.`t7`.`b` is not null))) where 1
+Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t7`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t7`.`b` is not null))) where 1
SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
FROM (t6, t7)
LEFT JOIN
@@ -567,7 +567,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)))
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
FROM t0,t1
@@ -663,7 +663,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
SELECT t9.a,t9.b
FROM t9;
a b
@@ -869,7 +869,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (incremental, BNL join)
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(((`test`.`t2`.`a` > 0) and (`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`b`) and (`test`.`t3`.`b` is not null))) where 1
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`b` = `test`.`t3`.`b`) and (`test`.`t2`.`a` > 0) and (`test`.`t3`.`b` is not null))) where 1
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
@@ -931,7 +931,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t2`.`a` > 0) and (`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`a` > 0) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t3`.`b` = `test`.`t4`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t9`.`b` = `test`.`t8`.`b`) or isnull(`test`.`t8`.`c`)))
INSERT INTO t4 VALUES (-3,12,0), (-4,13,0), (-1,11,0), (-3,11,0), (-5,15,0);
INSERT INTO t5 VALUES (-3,11,0), (-2,12,0), (-3,13,0), (-4,12,0);
CREATE INDEX idx_b ON t4(b);
@@ -983,7 +983,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t8 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t2`.`a` > 0) and (`test`.`t4`.`a` > 0) and (`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t5`.`a` > 0) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`a` > 0) and (`test`.`t4`.`a` > 0) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`a` > 0) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
INSERT INTO t8 VALUES (-3,12,0), (-1,14,0), (-5,15,0), (-1,11,0), (-4,13,0);
CREATE INDEX idx_b ON t8(b);
EXPLAIN EXTENDED
@@ -1033,7 +1033,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t2`.`a` > 0) and (`test`.`t4`.`a` > 0) and (`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t8`.`a` >= 0) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t5`.`a` > 0) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`a` > 0) and (`test`.`t4`.`a` > 0) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t8`.`a` >= 0) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`a` > 0) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
INSERT INTO t1 VALUES (-1,133,0), (-2,12,0), (-3,11,0), (-5,15,0);
CREATE INDEX idx_b ON t1(b);
CREATE INDEX idx_a ON t0(a);
@@ -1082,9 +1082,9 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t7 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
-1 SIMPLE t8 ref idx_b idx_b 5 test.t7.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
Warnings:
-Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t6`.`b` < 10) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t7`.`b` is not null)))) on(((`test`.`t6`.`b` >= 2) and (`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and (((`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t5`.`b` = `test`.`t0`.`b`)) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2) and (`test`.`t1`.`a` > 0))) join `test`.`t9` where ((`test`.`t9`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t0`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
+Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`b` is not null))) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(((`test`.`t8`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` < 10) and (`test`.`t5`.`b` is not null)))) on(((`test`.`t7`.`b` = `test`.`t5`.`b`) and (`test`.`t6`.`b` >= 2) and (`test`.`t5`.`b` is not null)))) on((((`test`.`t3`.`b` = 2) or isnull(`test`.`t3`.`c`)) and ((`test`.`t6`.`b` = 2) or isnull(`test`.`t6`.`c`)) and ((`test`.`t5`.`b` = `test`.`t0`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t6`.`c`) or isnull(`test`.`t8`.`c`)) and (`test`.`t1`.`a` <> 2) and (`test`.`t1`.`a` > 0))) join `test`.`t9` where ((`test`.`t0`.`a` = 1) and (`test`.`t1`.`b` = `test`.`t0`.`b`) and (`test`.`t9`.`a` = 1) and ((`test`.`t2`.`a` >= 4) or isnull(`test`.`t2`.`c`)) and ((`test`.`t3`.`a` < 5) or isnull(`test`.`t3`.`c`)) and ((`test`.`t4`.`b` = `test`.`t3`.`b`) or isnull(`test`.`t3`.`c`) or isnull(`test`.`t4`.`c`)) and ((`test`.`t5`.`a` >= 2) or isnull(`test`.`t5`.`c`)) and ((`test`.`t6`.`a` >= 4) or isnull(`test`.`t6`.`c`)) and ((`test`.`t7`.`a` <= 2) or isnull(`test`.`t7`.`c`)) and ((`test`.`t8`.`a` < 1) or isnull(`test`.`t8`.`c`)) and ((`test`.`t8`.`b` = `test`.`t9`.`b`) or isnull(`test`.`t8`.`c`)))
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b
FROM t0,t1
@@ -1226,7 +1226,7 @@ EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using index
1 SIMPLE t3 index c c 5 NULL 6 Using where; Using index
-1 SIMPLE t2 ref b b 5 test.t3.c 2 Using where; Using index
+1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index
SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
a b c
NULL 0 0
@@ -1297,7 +1297,7 @@ EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 5 NULL 21 Using index
1 SIMPLE t3 index c c 5 NULL 0 Using where; Using index
-1 SIMPLE t2 ref b b 5 test.t3.c 2 Using where; Using index
+1 SIMPLE t2 ref b b 5 test.t3.c 2 Using index
SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c;
a b c
NULL NULL NULL
@@ -1854,7 +1854,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t3 hash_ALL NULL #hash#$hj 5 test.t1.a 1 100.00 Using where; Not exists; Using join buffer (incremental, BNLH join)
1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t3.a 0 0.00 Using where; Using join buffer (incremental, BNLH join)
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`b` AS `b` from `test`.`t1` left join (`test`.`t2` left join `test`.`t3` on(((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t3`.`b` = `test`.`t1`.`a`))) left join `test`.`t4` on(((`test`.`t4`.`b` = `test`.`t3`.`a`) and (`test`.`t3`.`a` is not null)))) on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where isnull(`test`.`t3`.`a`)
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`b` AS `b` from `test`.`t1` left join (`test`.`t2` left join `test`.`t3` on((`test`.`t3`.`b` = `test`.`t1`.`a`)) left join `test`.`t4` on(((`test`.`t4`.`b` = `test`.`t3`.`a`) and (`test`.`t3`.`a` is not null)))) on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where isnull(`test`.`t3`.`a`)
DROP TABLE t1,t2,t3,t4;
SET optimizer_switch=@save_optimizer_switch;
End of 5.0 tests
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index fd2a948847c..c28887d4ff2 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -2008,7 +2008,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 100.00
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index
Warnings:
-Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where (1) order by 5
+Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where 1 order by 5
SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a
WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
ORDER BY t1.pk;
diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result
index d891f5c49b2..4efb6126cba 100644
--- a/mysql-test/r/join_outer_jcl6.result
+++ b/mysql-test/r/join_outer_jcl6.result
@@ -2019,7 +2019,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 100.00
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index
Warnings:
-Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where (1) order by 5
+Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where 1 order by 5
SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a
WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5
ORDER BY t1.pk;
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
index e991326cdce..7386af13e2c 100644
--- a/mysql-test/r/multi_update.result
+++ b/mysql-test/r/multi_update.result
@@ -689,6 +689,58 @@ DROP VIEW v1;
DROP FUNCTION f1;
DROP TABLE t1;
#
+# MDEV-4123: Incorrect results after multi-table update or
+# assertion `!table || (!table->read_set ||
+# bitmap_is_set(table->read_set, field_index))' failure
+#
+DROP TABLE IF EXISTS t1;
+Warnings:
+Note 1051 Unknown table 't1'
+CREATE TABLE t1 (
+id int(10) unsigned NOT NULL,
+level tinyint(3) unsigned NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES (2519583,1);
+DROP TABLE IF EXISTS t2;
+Warnings:
+Note 1051 Unknown table 't2'
+CREATE TABLE t2 (
+club_id int(11) NOT NULL DEFAULT '0',
+profile_id int(11) NOT NULL DEFAULT '0',
+member_level_id int(11) NOT NULL DEFAULT '0',
+PRIMARY KEY (profile_id,club_id)
+);
+INSERT INTO t2 VALUES (2,2519583,12);
+DROP TABLE IF EXISTS t3;
+Warnings:
+Note 1051 Unknown table 't3'
+CREATE TABLE t3 (
+member_level_id int(11) unsigned NOT NULL DEFAULT '0',
+map_level int(11) unsigned NOT NULL DEFAULT '0',
+map_status int(11) unsigned NOT NULL DEFAULT '0',
+PRIMARY KEY (member_level_id)
+);
+INSERT INTO t3 VALUES (12,12,1);
+CREATE
+VIEW v1 AS
+select club_id,profile_id,
+map_level AS member_level_id,map_status AS member_status
+from (t2 tc join t3 map
+on(((tc.member_level_id = map.member_level_id) and
+(club_id = 2))));
+select level, count(*) as cnt from t1 group by level;
+level cnt
+1 1
+UPDATE t1 c LEFT JOIN v1 t ON (c.id = t.profile_id AND t.club_id = 2)
+SET c.level = IF (t.member_status IS NULL, 1, IF (t.member_status = 1, 2,3));
+select level, count(*) as cnt from t1 group by level;
+level cnt
+2 1
+drop view v1;
+drop table t1,t2,t3;
+end of tests
+#
# BUG#57373: Multi update+InnoDB reports ER_KEY_NOT_FOUND if a
# table is updated twice
#
@@ -742,3 +794,4 @@ SELECT * FROM t2;
col_int_key pk_1 pk_2 col_int
1 7 11 4
DROP TABLE t1,t2;
+end of 5.5 tests
diff --git a/mysql-test/r/myisam-metadata.result b/mysql-test/r/myisam-metadata.result
new file mode 100644
index 00000000000..5192253d5d1
--- /dev/null
+++ b/mysql-test/r/myisam-metadata.result
@@ -0,0 +1,12 @@
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+id INT PRIMARY KEY,
+a VARCHAR(100),
+INDEX(a)
+) ENGINE=MyISAM;
+ALTER TABLE t1 DISABLE KEYS;
+ALTER TABLE t1 ENABLE KEYS;
+SHOW TABLE STATUS LIKE 't1';
+Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
+t1 MyISAM 10 Dynamic 100000 27 # # # 0 NULL # # # latin1_swedish_ci NULL
+DROP TABLE t1;
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 64c61d4ee36..c969b237293 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -2291,19 +2291,19 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 TRANSACTIONAL=1
drop table t1;
CREATE TABLE t1 (line LINESTRING NOT NULL) engine=myisam;
-INSERT INTO t1 VALUES (GeomFromText("POINT(0 0)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(0 0)"));
checksum table t1;
Table Checksum
-test.t1 326284887
+test.t1 310616673
CREATE TABLE t2 (line LINESTRING NOT NULL) engine=myisam;
-INSERT INTO t2 VALUES (GeomFromText("POINT(0 0)"));
+INSERT INTO t2 VALUES (GeomFromText("LINESTRING(0 0)"));
checksum table t2;
Table Checksum
-test.t2 326284887
+test.t2 310616673
CREATE TABLE t3 select * from t1;
checksum table t3;
Table Checksum
-test.t3 326284887
+test.t3 310616673
drop table t1,t2,t3;
create table t1 (a1 int,a2 int,a3 int,a4 int,a5 int,a6 int,a7 int,a8 int,a9 int,a10 int,a11 int,a12 int,a13 int,a14 int,a15 int,a16 int,a17 int,a18 int,a19 int,a20 int,a21 int,a22 int,a23 int,a24 int,a25 int,a26 int,a27 int,a28 int,a29 int,a30 int,a31 int,a32 int,
key(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,a25,a26,a27,a28,a29,a30,a31,a32)) engine=myisam;
@@ -2337,25 +2337,6 @@ h+0 d + 0 e g + 0
1 1 3 0
1 1 4 0
DROP TABLE t1;
-#
-# Test of BUG#35570 CHECKSUM TABLE unreliable if LINESTRING field
-# (same content / differen checksum)
-#
-CREATE TABLE t1 (line LINESTRING NOT NULL) engine=myisam;
-INSERT INTO t1 VALUES (GeomFromText("POINT(0 0)"));
-checksum table t1;
-Table Checksum
-test.t1 326284887
-CREATE TABLE t2 (line LINESTRING NOT NULL) engine=myisam;
-INSERT INTO t2 VALUES (GeomFromText("POINT(0 0)"));
-checksum table t2;
-Table Checksum
-test.t2 326284887
-CREATE TABLE t3 select * from t1;
-checksum table t3;
-Table Checksum
-test.t3 326284887
-drop table t1,t2,t3;
CREATE TABLE t1(a INT, b CHAR(10), KEY(a), KEY(b));
INSERT INTO t1 VALUES(1,'0'),(2,'0'),(3,'0'),(4,'0'),(5,'0'),
(6,'0'),(7,'0');
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index e0670f7d643..4d2ac25a0eb 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -513,5 +513,7 @@ create database `aa``bb````cc`;
DATABASE()
aa`bb``cc
drop database `aa``bb````cc`;
+a
+>>\ndelimiter\n<<
End of tests
diff --git a/mysql-test/r/mysqlbinlog-innodb.result b/mysql-test/r/mysqlbinlog-innodb.result
index 41d15bc32d3..a5865fe4fac 100644
--- a/mysql-test/r/mysqlbinlog-innodb.result
+++ b/mysql-test/r/mysqlbinlog-innodb.result
@@ -19,6 +19,7 @@ a
1
2
FLUSH LOGS;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -50,6 +51,8 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -81,5 +84,6 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
DROP DATABASE test2;
DROP TABLE t1;
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index 33904dfd9bd..823c7dc8629 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -14,6 +14,7 @@ insert into t1 values ("Alas");
flush logs;
--- Local --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -95,8 +96,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- Broken LOAD DATA --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -131,8 +134,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- --database --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -186,8 +191,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- --start-position --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -213,8 +220,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- Remote --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -296,8 +305,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- Broken LOAD DATA --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -332,8 +343,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- --database --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -387,8 +400,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- --start-position --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -414,8 +429,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- reading stdin --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -435,6 +452,8 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -453,6 +472,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
drop table t1,t2;
flush logs;
flush logs;
@@ -495,6 +515,7 @@ call p1();
drop procedure p1;
call p1();
ERROR 42000: PROCEDURE test.p1 does not exist
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -517,6 +538,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
call p1();
1
1
@@ -545,6 +567,7 @@ C3BF
D0AA
drop table t1;
flush logs;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -634,6 +657,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
CREATE TABLE t1 (c1 CHAR(10));
FLUSH LOGS;
INSERT INTO t1 VALUES ('0123456789');
@@ -721,6 +745,7 @@ RESET MASTER;
FLUSH LOGS;
#
# Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified exists
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -772,8 +797,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified does not exist
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -806,8 +833,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# Test if the 'SAVEPOINT', 'ROLLBACK TO' are output if the database specified exists
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -846,8 +875,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# Test if the 'SAVEPOINT', 'ROLLBACK TO' are output if the database specified does not exist
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -873,6 +904,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
End of 5.0 tests
End of 5.1 tests
# Expect deprecation warning.
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 7b650addd3d..e3d5df479b3 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -2791,8 +2791,8 @@ UNLOCK TABLES;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11)
-RETURN a+b */;;
+CREATE DEFINER=`root`@`localhost` FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11)
+RETURN a+b ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
@@ -2808,11 +2808,11 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) CHARSET latin1
+CREATE DEFINER=`root`@`localhost` FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) CHARSET latin1
begin
set f1= concat( 'hello', f1 );
return f1;
-end */;;
+end ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
@@ -2828,8 +2828,8 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER="root"@"localhost"*/ /*!50003 PROCEDURE "a'b"()
-select 1 */;;
+CREATE DEFINER="root"@"localhost" PROCEDURE "a'b"()
+select 1 ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
@@ -2845,8 +2845,8 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT)
-BEGIN SELECT a+b INTO c; end */;;
+CREATE DEFINER=`root`@`localhost` PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT)
+BEGIN SELECT a+b INTO c; end ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
@@ -2862,10 +2862,10 @@ DELIMITER ;
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `bug9056_proc2`(OUT a INT)
+CREATE DEFINER=`root`@`localhost` PROCEDURE `bug9056_proc2`(OUT a INT)
BEGIN
select sum(id) from t1 into a;
-END */;;
+END ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
@@ -3851,8 +3851,8 @@ create procedure mysqldump_test_db.sp1() select 'hello';
/*!50003 SET @saved_sql_mode = @@sql_mode */ ;
/*!50003 SET sql_mode = '' */ ;
DELIMITER ;;
-/*!50003 CREATE*/ /*!50020 DEFINER=`user1`@`%`*/ /*!50003 PROCEDURE `sp1`()
-select 'hello' */;;
+CREATE DEFINER=`user1`@`%` PROCEDURE `sp1`()
+select 'hello' ;;
DELIMITER ;
/*!50003 SET sql_mode = @saved_sql_mode */ ;
/*!50003 SET character_set_client = @saved_cs_client */ ;
diff --git a/mysql-test/r/row.result b/mysql-test/r/row.result
index 80934a4e01f..f94c958a1be 100644
--- a/mysql-test/r/row.result
+++ b/mysql-test/r/row.result
@@ -405,7 +405,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 6 100.00 Using index
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 12 test.t1.a,const,const 1 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = 1) and (`test`.`t2`.`b` = 2) and (`test`.`t2`.`a` = `test`.`t1`.`a`))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`b` = 2) and (`test`.`t2`.`c` = 1))
SELECT * FROM t1,t2 WHERE (t2.a,(t2.b,t2.c))=(t1.a,(2,1));
a b a b c
1 1 1 2 1
@@ -415,7 +415,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 6 100.00 Using index
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 12 test.t1.a,const,const 1 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`c` = 1) and (`test`.`t2`.`b` = 2) and (`test`.`t2`.`a` = `test`.`t1`.`a`))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t2`.`b` = 2) and (`test`.`t2`.`c` = 1))
SELECT * FROM t1,t2 WHERE t2.a=t1.a AND (t2.b,t2.c)=(2,1);
a b a b c
1 1 1 2 1
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 378b20829f3..3d16d37c5f1 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -5302,4 +5302,24 @@ INSERT INTO t2 VALUES (3),(4);
SELECT * FROM t1, t2 WHERE a=3 AND a=b;
a b
drop table t1,t2;
+#
+# Bug mdev-4250: wrong transformation of WHERE condition with OR
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, a int);
+INSERT INTO t1 VALUES (3,0), (2,0), (4,1), (5,0), (1,0);
+SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0;
+pk a
+EXPLAIN EXTENDED
+SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select 2 AS `pk`,0 AS `a` from `test`.`t1` where ((0 <> 0))
+DROP TABLE t1;
+SELECT * FROM mysql.time_zone
+WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1)
+AND Time_zone_id = Time_zone_id
+OR Time_zone_id <> Time_zone_id )
+AND Use_leap_seconds <> 'N';
+Time_zone_id Use_leap_seconds
End of 5.3 tests
diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result
index b5c6f89b87b..467f940c85d 100644
--- a/mysql-test/r/select_jcl6.result
+++ b/mysql-test/r/select_jcl6.result
@@ -5313,6 +5313,26 @@ INSERT INTO t2 VALUES (3),(4);
SELECT * FROM t1, t2 WHERE a=3 AND a=b;
a b
drop table t1,t2;
+#
+# Bug mdev-4250: wrong transformation of WHERE condition with OR
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, a int);
+INSERT INTO t1 VALUES (3,0), (2,0), (4,1), (5,0), (1,0);
+SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0;
+pk a
+EXPLAIN EXTENDED
+SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select 2 AS `pk`,0 AS `a` from `test`.`t1` where ((0 <> 0))
+DROP TABLE t1;
+SELECT * FROM mysql.time_zone
+WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1)
+AND Time_zone_id = Time_zone_id
+OR Time_zone_id <> Time_zone_id )
+AND Use_leap_seconds <> 'N';
+Time_zone_id Use_leap_seconds
End of 5.3 tests
set join_cache_level=default;
show variables like 'join_cache_level';
diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result
index 378b20829f3..3d16d37c5f1 100644
--- a/mysql-test/r/select_pkeycache.result
+++ b/mysql-test/r/select_pkeycache.result
@@ -5302,4 +5302,24 @@ INSERT INTO t2 VALUES (3),(4);
SELECT * FROM t1, t2 WHERE a=3 AND a=b;
a b
drop table t1,t2;
+#
+# Bug mdev-4250: wrong transformation of WHERE condition with OR
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, a int);
+INSERT INTO t1 VALUES (3,0), (2,0), (4,1), (5,0), (1,0);
+SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0;
+pk a
+EXPLAIN EXTENDED
+SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select 2 AS `pk`,0 AS `a` from `test`.`t1` where ((0 <> 0))
+DROP TABLE t1;
+SELECT * FROM mysql.time_zone
+WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1)
+AND Time_zone_id = Time_zone_id
+OR Time_zone_id <> Time_zone_id )
+AND Use_leap_seconds <> 'N';
+Time_zone_id Use_leap_seconds
End of 5.3 tests
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 14347e9b899..1977fbaccee 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1457,7 +1457,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t2`.`a`))
drop table t1, t2, t3;
create table t1 (a int, b int, index a (a,b));
create table t2 (a int, index a (a));
@@ -1500,7 +1500,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2)
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` = `test`.`t3`.`a`))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`b` = `test`.`t3`.`a`) and (`test`.`t1`.`a` = `test`.`t2`.`a`))
insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
@@ -2973,7 +2973,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N'))
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where (`test`.`t2`.`flag` = 'N')
explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result
index 049c4d14b1a..487ffe655c1 100644
--- a/mysql-test/r/subselect3.result
+++ b/mysql-test/r/subselect3.result
@@ -314,7 +314,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 index_subquery idx idx 5 func 4 100.00 Using where; Full scan on NULL key
Warnings:
Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`))))))) AS `Z` from `test`.`t2` where ((`test`.`t2`.`b` = 10) and (`test`.`t2`.`a` = 10))
+Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`))))))) AS `Z` from `test`.`t2` where ((`test`.`t2`.`a` = 10) and (`test`.`t2`.`b` = 10))
drop table t1, t2;
create table t1 (oref char(4), grp int, ie int);
insert into t1 (oref, grp, ie) values
@@ -1416,7 +1416,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00 Using where
1 PRIMARY a eq_ref PRIMARY PRIMARY 4 test.c.idObj 1 100.00 Using index; End temporary
Warnings:
-Note 1003 select `test`.`a`.`idIndividual` AS `idIndividual` from `test`.`t1` `a` semi join (`test`.`t3` `cona` join `test`.`t2` `c`) where ((`test`.`c`.`idContact` = `test`.`cona`.`idContact`) and (`test`.`a`.`idIndividual` = `test`.`c`.`idObj`) and (`test`.`cona`.`postalStripped` = 'T2H3B2'))
+Note 1003 select `test`.`a`.`idIndividual` AS `idIndividual` from `test`.`t1` `a` semi join (`test`.`t3` `cona` join `test`.`t2` `c`) where ((`test`.`cona`.`postalStripped` = 'T2H3B2') and (`test`.`a`.`idIndividual` = `test`.`c`.`idObj`) and (`test`.`c`.`idContact` = `test`.`cona`.`idContact`))
set @@optimizer_switch=@save_optimizer_switch;
drop table t1,t2,t3;
#
diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result
index 815a8985d44..9cd3018718c 100644
--- a/mysql-test/r/subselect3_jcl6.result
+++ b/mysql-test/r/subselect3_jcl6.result
@@ -324,7 +324,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 index_subquery idx idx 5 func 4 100.00 Using where; Full scan on NULL key
Warnings:
Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`))))))) AS `Z` from `test`.`t2` where ((`test`.`t2`.`b` = 10) and (`test`.`t2`.`a` = 10))
+Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on idx checking NULL where ((`test`.`t1`.`oref` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`ie1`) or isnull(`test`.`t1`.`ie1`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`ie2`) or isnull(`test`.`t1`.`ie2`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`ie1`)) and trigcond(<is_not_null_test>(`test`.`t1`.`ie2`))))))) AS `Z` from `test`.`t2` where ((`test`.`t2`.`a` = 10) and (`test`.`t2`.`b` = 10))
drop table t1, t2;
create table t1 (oref char(4), grp int, ie int);
insert into t1 (oref, grp, ie) values
@@ -1426,7 +1426,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY c eq_ref PRIMARY PRIMARY 4 test.cona.idContact 1 100.00 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
1 PRIMARY a eq_ref PRIMARY PRIMARY 4 test.c.idObj 1 100.00 Using index; End temporary
Warnings:
-Note 1003 select `test`.`a`.`idIndividual` AS `idIndividual` from `test`.`t1` `a` semi join (`test`.`t3` `cona` join `test`.`t2` `c`) where ((`test`.`c`.`idContact` = `test`.`cona`.`idContact`) and (`test`.`a`.`idIndividual` = `test`.`c`.`idObj`) and (`test`.`cona`.`postalStripped` = 'T2H3B2'))
+Note 1003 select `test`.`a`.`idIndividual` AS `idIndividual` from `test`.`t1` `a` semi join (`test`.`t3` `cona` join `test`.`t2` `c`) where ((`test`.`cona`.`postalStripped` = 'T2H3B2') and (`test`.`a`.`idIndividual` = `test`.`c`.`idObj`) and (`test`.`c`.`idContact` = `test`.`cona`.`idContact`))
set @@optimizer_switch=@save_optimizer_switch;
drop table t1,t2,t3;
#
diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result
index 9bb26e8a6e0..53334dbc32b 100644
--- a/mysql-test/r/subselect_mat.result
+++ b/mysql-test/r/subselect_mat.result
@@ -1896,7 +1896,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where ((`test`.`t1`.`a` = `<subquery2>`.`MAX(c)`) and (`test`.`t1`.`b` = 7) and (<cache>(isnull(`<subquery2>`.`MAX(c)`)) or (`<subquery2>`.`MAX(c)` = 7)))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where ((`test`.`t1`.`b` = 7) and (`test`.`t1`.`a` = `<subquery2>`.`MAX(c)`) and (<cache>(isnull(`<subquery2>`.`MAX(c)`)) or (`<subquery2>`.`MAX(c)` = 7)))
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
a b
diff --git a/mysql-test/r/subselect_mat_cost_bugs.result b/mysql-test/r/subselect_mat_cost_bugs.result
index 8c95c8637aa..24640154c59 100644
--- a/mysql-test/r/subselect_mat_cost_bugs.result
+++ b/mysql-test/r/subselect_mat_cost_bugs.result
@@ -100,7 +100,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 index c3 c3 9 NULL 2 100.00 Using where; Using index; Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.t1.pk' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` where <expr_cache><`test`.`t1`.`c1`,`test`.`t1`.`pk`>(<in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t1a`.`c1` from `test`.`t1b` join `test`.`t2` left join `test`.`t1a` on((2 and (`test`.`t1a`.`c2` = `test`.`t1b`.`pk`))) where ((`test`.`t1`.`pk` <> 0) and (<cache>(`test`.`t1`.`c1`) = `test`.`t1a`.`c1`) and (`test`.`t2`.`c3` = `test`.`t1b`.`c4`)))))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` where <expr_cache><`test`.`t1`.`c1`,`test`.`t1`.`pk`>(<in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t1a`.`c1` from `test`.`t1b` join `test`.`t2` left join `test`.`t1a` on(((`test`.`t1a`.`c2` = `test`.`t1b`.`pk`) and 2)) where ((`test`.`t1`.`pk` <> 0) and (<cache>(`test`.`t1`.`c1`) = `test`.`t1a`.`c1`) and (`test`.`t2`.`c3` = `test`.`t1b`.`c4`)))))
SELECT pk
FROM t1
WHERE c1 IN
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
index c307a68f64d..feaeff50f7d 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -1464,7 +1464,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t2`.`a`))
drop table t1, t2, t3;
create table t1 (a int, b int, index a (a,b));
create table t2 (a int, index a (a));
@@ -1507,7 +1507,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2)
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` = `test`.`t3`.`a`))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`b` = `test`.`t3`.`a`) and (`test`.`t1`.`a` = `test`.`t2`.`a`))
insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
@@ -2979,7 +2979,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
1 PRIMARY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; FirstMatch(t1)
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`two` = `test`.`t1`.`two`) and (`test`.`t2`.`one` = `test`.`t1`.`one`) and (`test`.`t2`.`flag` = 'N'))
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N') and (`test`.`t2`.`one` = `test`.`t1`.`one`) and (`test`.`t2`.`two` = `test`.`t1`.`two`))
explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
index b6b5572815a..2fd58c075d2 100644
--- a/mysql-test/r/subselect_no_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -1463,7 +1463,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`b`))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t3` join `test`.`t2` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t2`.`a`))
drop table t1, t2, t3;
create table t1 (a int, b int, index a (a,b));
create table t2 (a int, index a (a));
@@ -1506,7 +1506,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index
1 PRIMARY t1 ref a a 10 test.t2.a,test.t3.a 116 100.00 Using index; FirstMatch(t2)
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` = `test`.`t3`.`a`))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join `test`.`t3`) where ((`test`.`t1`.`b` = `test`.`t3`.`a`) and (`test`.`t1`.`a` = `test`.`t2`.`a`))
insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
@@ -2979,7 +2979,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 9 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`flag` = 'N'))
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` semi join (`test`.`t2`) where (`test`.`t2`.`flag` = 'N')
explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 8 100.00
diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result
index d9fa9853da5..a4e4922474e 100644
--- a/mysql-test/r/subselect_sj.result
+++ b/mysql-test/r/subselect_sj.result
@@ -74,7 +74,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using where
1 PRIMARY t12 eq_ref PRIMARY PRIMARY 4 test.t10.a 1 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t12` join `test`.`t1` where ((`test`.`t10`.`pk` = `test`.`t1`.`a`) and (`test`.`t12`.`pk` = `test`.`t10`.`a`))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t12` join `test`.`t1` where ((`test`.`t12`.`pk` = `test`.`t10`.`a`) and (`test`.`t10`.`pk` = `test`.`t1`.`a`))
subqueries within outer joins go into ON expr.
explAin extended
select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
@@ -84,7 +84,7 @@ id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA
1 PRIMARY B ALL NULL NULL NULL NULL 3 100.00 Using where
2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on((<in_optimizer>(`test`.`B`.`A`,`test`.`B`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`B`.`A` in <temporAry tABle> on distinct_key where ((`test`.`B`.`A` = `<suBquery2>`.`pk`))))) And (`test`.`A`.`A` = `test`.`t1`.`A`))) where 1
+Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,`test`.`B`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`B`.`A` in <temporAry tABle> on distinct_key where ((`test`.`B`.`A` = `<suBquery2>`.`pk`))))))) where 1
t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
explAin extended
select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
@@ -93,7 +93,7 @@ id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where
2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on((<in_optimizer>(`test`.`t2`.`A`,`test`.`t2`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`t2`.`A` in <temporAry tABle> on distinct_key where ((`test`.`t2`.`A` = `<suBquery2>`.`pk`))))) And (`test`.`t2`.`A` = `test`.`t1`.`A`))) where 1
+Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t1`.`A`,`test`.`t1`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`t1`.`A` in <temporAry tABle> on distinct_key where ((`test`.`t1`.`A` = `<suBquery2>`.`pk`))))))) where 1
we shouldn't flatten if we're going to get a join of > MAX_TABLES.
explain select * from
t1 s00, t1 s01, t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -501,7 +501,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t0.pk 1 100.00 Using where
1 PRIMARY t2 ref vkey vkey 4 test.t1.vnokey 2 100.00 Using index; FirstMatch(t1)
Warnings:
-Note 1003 select `test`.`t0`.`vkey` AS `vkey` from `test`.`t0` `t1` semi join (`test`.`t0` `t2`) join `test`.`t0` where ((`test`.`t2`.`vkey` = `test`.`t1`.`vnokey`) and (`test`.`t1`.`pk` = `test`.`t0`.`pk`))
+Note 1003 select `test`.`t0`.`vkey` AS `vkey` from `test`.`t0` `t1` semi join (`test`.`t0` `t2`) join `test`.`t0` where ((`test`.`t1`.`pk` = `test`.`t0`.`pk`) and (`test`.`t2`.`vkey` = `test`.`t1`.`vnokey`))
SELECT vkey FROM t0 WHERE pk IN
(SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
vkey
@@ -814,7 +814,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`c` = `test`.`t1`.`c`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`c` = `test`.`t1`.`c`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0);
pk
1
@@ -824,7 +824,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`d` = `test`.`t1`.`d`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`d` = `test`.`t1`.`d`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0);
pk
2
@@ -833,7 +833,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`e` = `test`.`t1`.`e`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`e` = `test`.`t1`.`e`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0);
pk
1
@@ -843,7 +843,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`f` = `test`.`t1`.`f`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`f` = `test`.`t1`.`f`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0);
pk
1
@@ -853,7 +853,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`g` = `test`.`t1`.`g`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`g` = `test`.`t1`.`g`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0);
pk
1
@@ -863,7 +863,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`h` = `test`.`t1`.`h`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`h` = `test`.`t1`.`h`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0);
pk
1
@@ -873,7 +873,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`i` = `test`.`t1`.`i`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`i` = `test`.`t1`.`i`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0);
pk
1
@@ -883,7 +883,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`j` = `test`.`t1`.`j`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`j` = `test`.`t1`.`j`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0);
pk
1
@@ -893,7 +893,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`k` = `test`.`t1`.`k`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`k` = `test`.`t1`.`k`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0);
pk
1
@@ -1994,7 +1994,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` semi join (`test`.`t4`) join `test`.`t2` join `test`.`t3` where ((`test`.`t1`.`f2` = `test`.`t2`.`f2`) and (`test`.`t3`.`f1` = `test`.`t1`.`f1`) and (`test`.`t4`.`f2` = `test`.`t2`.`f3`))
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` semi join (`test`.`t4`) join `test`.`t2` join `test`.`t3` where ((`test`.`t4`.`f2` = `test`.`t2`.`f3`) and (`test`.`t3`.`f1` = `test`.`t1`.`f1`) and (`test`.`t1`.`f2` = `test`.`t2`.`f2`))
SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
f1 f2 f3 f3
2 0 0 0
diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result
index 97e36cd705c..c4b9933ae07 100644
--- a/mysql-test/r/subselect_sj2.result
+++ b/mysql-test/r/subselect_sj2.result
@@ -456,7 +456,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ref a a 5 test.t0.a 1 100.00 Using where; FirstMatch(t2)
Warnings:
Note 1276 Field or reference 'test.t0.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) join `test`.`t0` where ((`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`a` = `test`.`t0`.`a`))
+Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) join `test`.`t0` where ((`test`.`t2`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`b` = `test`.`t2`.`b`))
update t1 set a=3, b=11 where a=4;
update t2 set b=11 where a=3;
select * from t0 where t0.a in
diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result
index e4030b8138b..d9b9815133c 100644
--- a/mysql-test/r/subselect_sj2_jcl6.result
+++ b/mysql-test/r/subselect_sj2_jcl6.result
@@ -468,7 +468,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ref a a 5 test.t0.a 1 100.00 Using where; FirstMatch(t2); Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
Warnings:
Note 1276 Field or reference 'test.t0.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) join `test`.`t0` where ((`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`a` = `test`.`t0`.`a`))
+Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) join `test`.`t0` where ((`test`.`t2`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`b` = `test`.`t2`.`b`))
update t1 set a=3, b=11 where a=4;
update t2 set b=11 where a=3;
# Not anymore:
diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result
index f69befc8608..c91ee67a717 100644
--- a/mysql-test/r/subselect_sj2_mat.result
+++ b/mysql-test/r/subselect_sj2_mat.result
@@ -458,7 +458,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ref a a 5 test.t0.a 1 100.00 Using where; FirstMatch(t2)
Warnings:
Note 1276 Field or reference 'test.t0.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) join `test`.`t0` where ((`test`.`t1`.`b` = `test`.`t2`.`b`) and (`test`.`t2`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`a` = `test`.`t0`.`a`))
+Note 1003 select `test`.`t0`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) join `test`.`t0` where ((`test`.`t2`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`a` = `test`.`t0`.`a`) and (`test`.`t1`.`b` = `test`.`t2`.`b`))
update t1 set a=3, b=11 where a=4;
update t2 set b=11 where a=3;
select * from t0 where t0.a in
@@ -1124,3 +1124,267 @@ AND ( 6 ) IN
ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay
DROP TABLE t1, t2;
set max_join_size= @tmp_906385;
+#
+# mdev-3995: Wrong result for semijoin with materialization
+#
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (
+cat_id int(10) unsigned NOT NULL,
+PRIMARY KEY (cat_id)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+(709411),(709412),(709413),(709414),(709416),(709417),(709418),(709419),(709421),(709422),
+(709424),(709425),(709427),(709428),(709429),(709431),(709432),(709433),(709434),(709435),
+(709438),(709439),(709441),(709442),(709443),(709444),(709445),(709446),(709447),(709450),
+(709451),(709454),(709455),(709456),(709457),(709459),(709460),(709461),(709462),(709463),
+(709464),(709465),(709467),(709469),(709470),(709471),(709472),(709473),(709474),(709475),
+(709476),(709477),(709478),(709479),(709480),(709481),(709483),(709484),(709485),(709487),
+(709490),(709491),(709492),(709493),(709494),(709495),(709496),(709497),(709498),(709499),
+(709500),(709501),(709502),(709503),(709504),(709505),(709506),(709507),(709509),(709510),
+(709511),(709512),(709513),(709514),(709515),(709516),(709517),(709518),(709519),(709520),
+(709521),(709522),(709523),(709524),(709525),(709526),(709527),(709528),(709529),(709530),
+(709531),(709532),(709533),(709534),(709535),(709536),(709537),(709538),(709539),(709540),
+(709541),(709542),(709543),(709544),(709545),(709546),(709548),(709549),(709551),(709552),
+(709553),(709555),(709556),(709557),(709558),(709559),(709560),(709561),(709562),(709563),
+(709564),(709565),(709566),(709567),(709568),(709569),(709570),(709571),(709572),(709573),
+(709574),(709575),(709576),(709577),(709578),(709579),(709580),(709581),(709582),(709583),
+(709584),(709585),(709586),(709587),(709588),(709590),(709591),(709592),(709593),(709594),
+(709595),(709596),(709597),(709598),(709600),(709601),(709602),(709603),(709604),(709605),
+(709606),(709608),(709609),(709610),(709611),(709612),(709613),(709614),(709615),(709616),
+(709617),(709618),(709619),(709620),(709621),(709622),(709623),(709624),(709625),(709626),
+(709627),(709628),(709629),(709630),(709631),(709632),(709633),(709634),(709635),(709637),
+(709638),(709639),(709640),(709641),(709642),(709643),(709644),(709645),(709646),(709649),
+(709650),(709651),(709652),(709653),(709654),(709655),(709656),(709657),(709658),(709659);
+CREATE TABLE t2 (
+cat_id int(10) NOT NULL,
+KEY cat_id (cat_id)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES
+(708742),(708755),(708759),(708761),(708766),(708769),(708796),(708798),(708824),(708825),
+(708838),(708844),(708861),(708882),(708887),(708889),(708890),(709586),(709626);
+CREATE TABLE t3 (
+sack_id int(10) unsigned NOT NULL,
+kit_id tinyint(3) unsigned NOT NULL DEFAULT '0',
+cat_id int(10) unsigned NOT NULL,
+PRIMARY KEY (sack_id,kit_id,cat_id)
+) ENGINE=MyISAM;
+INSERT INTO t3 VALUES
+(33479,6,708523),(33479,6,708632),(33479,6,709085),(33479,6,709586),(33479,6,709626);
+CREATE TABLE t4 (
+cat_id int(10) unsigned NOT NULL,
+KEY cat_id (cat_id)
+) ENGINE=MyISAM;
+INSERT INTO t4 (cat_id) SELECT cat_id from t2;
+set optimizer_switch='materialization=off';
+EXPLAIN
+SELECT count(*) FROM t1, t3
+WHERE t1.cat_id = t3.cat_id AND
+t3.cat_id IN (SELECT cat_id FROM t2) AND
+t3.sack_id = 33479 AND t3.kit_id = 6;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 4 Using index
+1 PRIMARY t2 ref cat_id cat_id 4 test.t3.cat_id 2 Using where; Using index; FirstMatch(t3)
+1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t2.cat_id 1 Using where; Using index
+SELECT count(*) FROM t1, t3
+WHERE t1.cat_id = t3.cat_id AND
+t3.cat_id IN (SELECT cat_id FROM t2) AND
+t3.sack_id = 33479 AND t3.kit_id = 6;
+count(*)
+2
+set optimizer_switch='materialization=on';
+EXPLAIN
+SELECT count(*) FROM t1, t3
+WHERE t1.cat_id = t3.cat_id AND
+t3.cat_id IN (SELECT cat_id FROM t4) AND
+t3.sack_id = 33479 AND t3.kit_id = 6;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 4 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
+1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.cat_id 1 Using index
+2 MATERIALIZED t4 index cat_id cat_id 4 NULL 19 Using index
+SELECT count(*) FROM t1, t3
+WHERE t1.cat_id = t3.cat_id AND
+t3.cat_id IN (SELECT cat_id FROM t4) AND
+t3.sack_id = 33479 AND t3.kit_id = 6;
+count(*)
+2
+EXPLAIN
+SELECT count(*) FROM t1, t3
+WHERE t1.cat_id = t3.cat_id AND
+t3.cat_id IN (SELECT cat_id FROM t2) AND
+t3.sack_id = 33479 AND t3.kit_id = 6;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ref PRIMARY PRIMARY 5 const,const 4 Using index
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 Using where
+1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.cat_id 1 Using index
+2 MATERIALIZED t2 index cat_id cat_id 4 NULL 19 Using index
+SELECT count(*) FROM t1, t3
+WHERE t1.cat_id = t3.cat_id AND
+t3.cat_id IN (SELECT cat_id FROM t2) AND
+t3.sack_id = 33479 AND t3.kit_id = 6;
+count(*)
+2
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch=@save_optimizer_switch;
+#
+# mdev-3913: LEFT JOIN with materialized multi-table IN subquery in WHERE
+#
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (a1 char(1), b1 char(1), index idx(b1,a1));
+INSERT INTO t1 VALUES ('f','c'),('d','m'),('g','y');
+INSERT INTO t1 VALUES ('f','c'),('d','m'),('g','y');
+CREATE TABLE t2 (a2 char(1), b2 char(1));
+INSERT INTO t2 VALUES ('y','y'),('y','y'),('w','w');
+CREATE TABLE t3 (a3 int);
+INSERT INTO t3 VALUES (8),(6);
+CREATE TABLE t4 (a4 char(1), b4 char(1));
+INSERT INTO t4 VALUES ('y','y'),('y','y'),('w','w');
+set optimizer_switch='materialization=off';
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 Start temporary
+1 PRIMARY t4 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t1 ref idx idx 2 test.t4.a4 1 100.00 Using index; End temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t4`) left join `test`.`t2` on((`test`.`t2`.`a2` = `test`.`t4`.`a4`)) where ((`test`.`t4`.`b4` = `test`.`t4`.`a4`) and (`test`.`t1`.`b1` = `test`.`t4`.`a4`))
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+a1 b1 a2 b2
+g y y y
+g y y y
+g y y y
+g y y y
+set optimizer_switch='materialization=on';
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 100.00
+1 PRIMARY t1 ref idx idx 2 test.t4.a4 1 100.00 Using index
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED t4 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`,`test`.`t2`.`a2` AS `a2`,`test`.`t2`.`b2` AS `b2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t4`) left join `test`.`t2` on(((`test`.`t1`.`b1` = `test`.`t4`.`a4`) and (`test`.`t2`.`a2` = `test`.`t4`.`a4`))) where ((`test`.`t4`.`b4` = `test`.`t4`.`a4`) and (`test`.`t1`.`b1` = `test`.`t4`.`a4`))
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+a1 b1 a2 b2
+g y y y
+g y y y
+g y y y
+g y y y
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch=@save_optimizer_switch;
+#
+# mdev-4172: LEFT JOIN with materialized multi-table IN subquery in WHERE
+# and OR in ON condition
+#
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (a1 int, c1 varchar(1));
+INSERT t1 VALUES (7,'v'), (3,'y');
+CREATE TABLE t2 (c2 varchar(1));
+INSERT INTO t2 VALUES ('y'), ('y');
+CREATE TABLE t3 (c3 varchar(1));
+INSERT INTO t3 VALUES
+('j'), ('v'), ('c'), ('m'), ('d'),
+('d'), ('y'), ('t'), ('d'), ('s');
+CREATE TABLE t4 (a4 int, c4 varchar(1));
+INSERT INTO t4 SELECT * FROM t1;
+set optimizer_switch='materialization=off';
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 10 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t4`) left join `test`.`t2` on(((`test`.`t2`.`c2` = `test`.`t1`.`c1`) or (`test`.`t1`.`c1` > 'z'))) where ((`test`.`t4`.`c4` = `test`.`t1`.`c1`) and (`test`.`t3`.`c3` = `test`.`t1`.`c1`))
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+a1 c1 c2
+3 y y
+3 y y
+7 v NULL
+set optimizer_switch='materialization=on';
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+2 MATERIALIZED t4 ALL NULL NULL NULL NULL 2 100.00
+2 MATERIALIZED t3 ALL NULL NULL NULL NULL 10 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t4`) left join `test`.`t2` on(((`test`.`t2`.`c2` = `test`.`t1`.`c1`) or (`test`.`t1`.`c1` > 'z'))) where (`test`.`t3`.`c3` = `test`.`t4`.`c4`)
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+a1 c1 c2
+3 y y
+3 y y
+7 v NULL
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch=@save_optimizer_switch;
+#
+# mdev-4177: materialization of a subquery whose WHERE condition is OR
+# formula with two disjucts such that the second one is always false
+#
+set @save_optimizer_switch=@@optimizer_switch;
+set @save_join_cache_level=@@join_cache_level;
+CREATE TABLE t1 (i1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1), (7), (4), (8), (4);
+CREATE TABLE t2 (i2 int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (7), (5);
+CREATE TABLE t3 (i3 int) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (7), (2), (9);
+set join_cache_level=3;
+set optimizer_switch='materialization=off,semijoin=off';
+EXPLAIN EXTENDED
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5 100.00 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+2 DEPENDENT SUBQUERY t3 hash_ALL NULL #hash#$hj 5 func 3 100.00 Using where; Using join buffer (flat, BNLH join)
+Warnings:
+Note 1003 select `test`.`t1`.`i1` AS `i1` from `test`.`t1` where <expr_cache><`test`.`t1`.`i1`>(<in_optimizer>(`test`.`t1`.`i1`,<exists>(select `test`.`t3`.`i3` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`i3` = `test`.`t2`.`i2`) and (<cache>(`test`.`t1`.`i1`) = `test`.`t3`.`i3`)))))
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+i1
+7
+set optimizer_switch='materialization=on,semijoin=on';
+EXPLAIN EXTENDED
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 100.00
+1 PRIMARY t1 hash_ALL NULL #hash#$hj 5 test.t2.i2 5 100.00 Using where; Using join buffer (flat, BNLH join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 MATERIALIZED t3 hash_ALL NULL #hash#$hj 5 test.t2.i2 3 100.00 Using where; Using join buffer (flat, BNLH join)
+Warnings:
+Note 1003 select `test`.`t1`.`i1` AS `i1` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where ((`test`.`t3`.`i3` = `test`.`t2`.`i2`) and (`test`.`t1`.`i1` = `test`.`t2`.`i2`))
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+i1
+7
+EXPLAIN EXTENDED
+SELECT * FROM t1
+WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 0 AND i3 = i2 OR 1=2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3 100.00
+1 PRIMARY t1 hash_ALL NULL #hash#$hj 5 test.t2.i2 5 100.00 Using where; Using join buffer (flat, BNLH join)
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 MATERIALIZED t3 hash_ALL NULL #hash#$hj 5 test.t2.i2 3 100.00 Using where; Using join buffer (flat, BNLH join)
+Warnings:
+Note 1003 select `test`.`t1`.`i1` AS `i1` from `test`.`t1` semi join (`test`.`t2` join `test`.`t3`) where ((`test`.`t3`.`i3` = `test`.`t2`.`i2`) and (`test`.`t1`.`i1` = `test`.`t2`.`i2`) and (`test`.`t3`.`i3` > 0))
+SELECT * FROM t1
+WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 0 AND i3 = i2 OR 1=2);
+i1
+7
+SELECT * FROM t1
+WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 7 AND i3 = i2 OR 1=2);
+i1
+DROP TABLE t1,t2,t3;
+set join_cache_level= @save_join_cache_level;
+set optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result
index 1ca8b44a0b8..4e67c1cc01c 100644
--- a/mysql-test/r/subselect_sj_jcl6.result
+++ b/mysql-test/r/subselect_sj_jcl6.result
@@ -87,7 +87,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t10 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
1 PRIMARY t12 eq_ref PRIMARY PRIMARY 4 test.t10.a 1 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t12` join `test`.`t1` where ((`test`.`t10`.`pk` = `test`.`t1`.`a`) and (`test`.`t12`.`pk` = `test`.`t10`.`a`))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t10` join `test`.`t12` join `test`.`t1` where ((`test`.`t12`.`pk` = `test`.`t10`.`a`) and (`test`.`t10`.`pk` = `test`.`t1`.`a`))
subqueries within outer joins go into ON expr.
explAin extended
select * from t1 left join (t2 A, t2 B) on ( A.A= t1.A And B.A in (select pk from t10));
@@ -97,7 +97,7 @@ id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA
1 PRIMARY B ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer (incrementAl, BNL join)
2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on((<in_optimizer>(`test`.`B`.`A`,`test`.`B`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`B`.`A` in <temporAry tABle> on distinct_key where ((`test`.`B`.`A` = `<suBquery2>`.`pk`))))) And (`test`.`A`.`A` = `test`.`t1`.`A`))) where 1
+Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on(((`test`.`A`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`B`.`A`,`test`.`B`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`B`.`A` in <temporAry tABle> on distinct_key where ((`test`.`B`.`A` = `<suBquery2>`.`pk`))))))) where 1
t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
explAin extended
select * from t1 left join t2 on (t2.A= t1.A And t2.A in (select pk from t10));
@@ -106,7 +106,7 @@ id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join Buffer (flAt, BNL join)
2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on((<in_optimizer>(`test`.`t2`.`A`,`test`.`t2`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`t2`.`A` in <temporAry tABle> on distinct_key where ((`test`.`t2`.`A` = `<suBquery2>`.`pk`))))) And (`test`.`t2`.`A` = `test`.`t1`.`A`))) where 1
+Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on(((`test`.`t2`.`A` = `test`.`t1`.`A`) And <in_optimizer>(`test`.`t1`.`A`,`test`.`t1`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`t1`.`A` in <temporAry tABle> on distinct_key where ((`test`.`t1`.`A` = `<suBquery2>`.`pk`))))))) where 1
we shouldn't flatten if we're going to get a join of > MAX_TABLES.
explain select * from
t1 s00, t1 s01, t1 s02, t1 s03, t1 s04,t1 s05,t1 s06,t1 s07,t1 s08,t1 s09,
@@ -514,7 +514,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t0.pk 1 100.00 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
1 PRIMARY t2 ref vkey vkey 4 test.t1.vnokey 2 100.00 Using index; FirstMatch(t1)
Warnings:
-Note 1003 select `test`.`t0`.`vkey` AS `vkey` from `test`.`t0` `t1` semi join (`test`.`t0` `t2`) join `test`.`t0` where ((`test`.`t2`.`vkey` = `test`.`t1`.`vnokey`) and (`test`.`t1`.`pk` = `test`.`t0`.`pk`))
+Note 1003 select `test`.`t0`.`vkey` AS `vkey` from `test`.`t0` `t1` semi join (`test`.`t0` `t2`) join `test`.`t0` where ((`test`.`t1`.`pk` = `test`.`t0`.`pk`) and (`test`.`t2`.`vkey` = `test`.`t1`.`vnokey`))
SELECT vkey FROM t0 WHERE pk IN
(SELECT t1.pk FROM t0 t1 JOIN t0 t2 ON t2.vkey = t1.vnokey);
vkey
@@ -827,7 +827,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`c` = `test`.`t1`.`c`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`c` = `test`.`t1`.`c`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, c) IN (SELECT b, c FROM t2 WHERE pk > 0);
pk
1
@@ -837,7 +837,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`d` = `test`.`t1`.`d`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`d` = `test`.`t1`.`d`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, d) IN (SELECT b, d FROM t2 WHERE pk > 0);
pk
2
@@ -846,7 +846,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`e` = `test`.`t1`.`e`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`e` = `test`.`t1`.`e`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, e) IN (SELECT b, e FROM t2 WHERE pk > 0);
pk
1
@@ -856,7 +856,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`f` = `test`.`t1`.`f`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`f` = `test`.`t1`.`f`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, f) IN (SELECT b, f FROM t2 WHERE pk > 0);
pk
1
@@ -866,7 +866,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`g` = `test`.`t1`.`g`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`g` = `test`.`t1`.`g`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, g) IN (SELECT b, g FROM t2 WHERE pk > 0);
pk
1
@@ -876,7 +876,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`h` = `test`.`t1`.`h`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`h` = `test`.`t1`.`h`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, h) IN (SELECT b, h FROM t2 WHERE pk > 0);
pk
1
@@ -886,7 +886,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`i` = `test`.`t1`.`i`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`i` = `test`.`t1`.`i`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, i) IN (SELECT b, i FROM t2 WHERE pk > 0);
pk
1
@@ -896,7 +896,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`j` = `test`.`t1`.`j`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`j` = `test`.`t1`.`j`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, j) IN (SELECT b, j FROM t2 WHERE pk > 0);
pk
1
@@ -906,7 +906,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
1 PRIMARY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Using where; Rowid-ordered scan; FirstMatch(t1); Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`k` = `test`.`t1`.`k`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`pk` > 0))
+Note 1003 select `test`.`t1`.`pk` AS `pk` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`k` = `test`.`t1`.`k`) and (`test`.`t2`.`pk` > 0))
SELECT pk FROM t1 WHERE (b, k) IN (SELECT b, k FROM t2 WHERE pk > 0);
pk
1
@@ -2008,7 +2008,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (incremental, BNL join)
2 MATERIALIZED t4 index f2 f2 5 NULL 2 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` semi join (`test`.`t4`) join `test`.`t2` join `test`.`t3` where ((`test`.`t1`.`f2` = `test`.`t2`.`f2`) and (`test`.`t3`.`f1` = `test`.`t1`.`f1`))
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` semi join (`test`.`t4`) join `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`f1` = `test`.`t1`.`f1`) and (`test`.`t1`.`f2` = `test`.`t2`.`f2`))
SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
f1 f2 f3 f3
2 0 0 0
diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result
index f8598a3864d..549282c9dbe 100644
--- a/mysql-test/r/subselect_sj_mat.result
+++ b/mysql-test/r/subselect_sj_mat.result
@@ -86,7 +86,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`) join `test`.`t1` where ((`<subquery2>`.`min(b2)` = `test`.`t1`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1`.`a1`))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`) join `test`.`t1` where ((`<subquery2>`.`b1` = `test`.`t1`.`a1`) and (`<subquery2>`.`min(b2)` = `test`.`t1`.`a2`))
select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -120,7 +120,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2i index it2i1,it2i2,it2i3 it2i3 # NULL 5 40.00 Using where; Using index; LooseScan
1 PRIMARY t1i ref _it1_idx _it1_idx # _ref_ 1 100.00
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) where ((`test`.`t1i`.`a2` = `test`.`t2i`.`b2`) and (`test`.`t1i`.`a1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` > '0'))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) where ((`test`.`t1i`.`a1` = `test`.`t2i`.`b1`) and (`test`.`t1i`.`a2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b1` > '0'))
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
a1 a2
1 - 01 2 - 01
@@ -132,7 +132,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> eq_ref distinct_key # # # 1 100.00 #
2 MATERIALIZED t2i range it2i1,it2i3 # # # 3 100.00 #
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where ((`<subquery2>`.`max(b2)` = `test`.`t1i`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1i`.`a1`))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where ((`<subquery2>`.`b1` = `test`.`t1i`.`a1`) and (`<subquery2>`.`max(b2)` = `test`.`t1i`.`a2`))
select * from t1i where (a1, a2) in (select b1, max(b2) from t2i where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -144,7 +144,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> eq_ref distinct_key # # # 1 100.00 #
2 MATERIALIZED t2i range it2i1,it2i3 # # # 3 100.00 #
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where ((`<subquery2>`.`min(b2)` = `test`.`t1i`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1i`.`a1`))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where ((`<subquery2>`.`b1` = `test`.`t1i`.`a1`) and (`<subquery2>`.`min(b2)` = `test`.`t1i`.`a2`))
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -156,7 +156,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00
2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`<subquery2>`.`max(b2)` = `test`.`t1`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1`.`a1`))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`<subquery2>`.`b1` = `test`.`t1`.`a1`) and (`<subquery2>`.`max(b2)` = `test`.`t1`.`a2`))
select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
a1 a2
1 - 01 2 - 01
@@ -188,7 +188,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00
2 MATERIALIZED t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`<subquery2>`.`min(b2)` = `test`.`t1`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1`.`a1`))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`<subquery2>`.`b1` = `test`.`t1`.`a1`) and (`<subquery2>`.`min(b2)` = `test`.`t1`.`a2`))
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -236,7 +236,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1.a1,test.t1.a2 1 100.00
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`<subquery2>`.`b2` = `test`.`t1`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1`.`a1`))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`<subquery2>`.`b1` = `test`.`t1`.`a1`) and (`<subquery2>`.`b2` = `test`.`t1`.`a2`))
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -248,7 +248,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 16 test.t1i.a1,test.t1i.a2 1 100.00
2 MATERIALIZED t2i index NULL it2i3 18 NULL 5 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((`<subquery2>`.`b2` = `test`.`t1i`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1i`.`a1`))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((`<subquery2>`.`b1` = `test`.`t1i`.`a1`) and (`<subquery2>`.`b2` = `test`.`t1i`.`a2`))
select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -305,7 +305,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 MATERIALIZED t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2`.`b1` > '0') and (`test`.`t3`.`c2` > '0'))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (`test`.`t2`.`b1` > '0') and (`test`.`t3`.`c2` > '0'))
select * from t1
where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
(a1, a2) in (select c1, c2 from t3
@@ -324,7 +324,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3i ref it3i1,it3i2,it3i3 # # # 1 100.00 #
1 PRIMARY t2i ref it2i1,it2i2,it2i3 # # # 2 100.00 #
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where ((`test`.`t1i`.`a2` = `test`.`t2i`.`b2`) and (`test`.`t3i`.`c2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b2` = `test`.`t2i`.`b2`) and (`test`.`t1i`.`a1` = `test`.`t2i`.`b1`) and (`test`.`t3i`.`c1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` > '0') and (`test`.`t2i`.`b2` > '0'))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where ((`test`.`t1i`.`a1` = `test`.`t2i`.`b1`) and (`test`.`t3i`.`c1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` = `test`.`t2i`.`b1`) and (`test`.`t1i`.`a2` = `test`.`t2i`.`b2`) and (`test`.`t3i`.`c2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b1` > '0') and (`test`.`t2i`.`b2` > '0'))
select * from t1i
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
(a1, a2) in (select c1, c2 from t3i
@@ -349,7 +349,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
4 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
3 MATERIALIZED t3 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3`.`c2` > '0'))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3`.`c2` > '0'))
select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 where c2 LIKE '%02') or
@@ -375,7 +375,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t3a ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2i`.`b2` = `test`.`t3c`.`c2`) and (`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b1` = `test`.`t3c`.`c1`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3c`.`c2` > '0'))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2i`.`b1` = `test`.`t3c`.`c1`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b2` = `test`.`t3c`.`c2`) and (`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3c`.`c2` > '0'))
select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 t3a where c1 = a1) or
@@ -413,7 +413,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
7 UNION t2i ref it2i1,it2i2,it2i3 # # # 2 100.00 #
NULL UNION RESULT <union1,7> ALL NULL # # # NULL NULL #
Warnings:
-Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3`.`c2` > '0'))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where ((`test`.`t1i`.`a2` = `test`.`t2i`.`b2`) and (`test`.`t3i`.`c2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b2` = `test`.`t2i`.`b2`) and (`test`.`t1i`.`a1` = `test`.`t2i`.`b1`) and (`test`.`t3i`.`c1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` > '0') and (`test`.`t2i`.`b2` > '0')))
+Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3`.`c2` > '0'))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where ((`test`.`t1i`.`a1` = `test`.`t2i`.`b1`) and (`test`.`t3i`.`c1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` = `test`.`t2i`.`b1`) and (`test`.`t1i`.`a2` = `test`.`t2i`.`b2`) and (`test`.`t3i`.`c2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b1` > '0') and (`test`.`t2i`.`b2` > '0')))
(select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 where c2 LIKE '%02') or
@@ -443,7 +443,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and (`test`.`t3`.`c2` > '0'))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and (`test`.`t3`.`c2` > '0'))
select * from t1
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
(a1, a2) in (select c1, c2 from t3
@@ -467,7 +467,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT UNION t2 ALL NULL NULL NULL NULL 5 100.00 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t1` semi join (`test`.`t2i` join `test`.`t3`) join `test`.`t3` where ((`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (`test`.`t3`.`c1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and (`test`.`t3`.`c2` > '0'))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t1` semi join (`test`.`t2i` join `test`.`t3`) join `test`.`t3` where ((`test`.`t3`.`c1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t1`.`a1`,`test`.`t1`.`a2` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t1`.`a1`) = `test`.`t1`.`a1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t1`.`a2`)) union select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and (`test`.`t3`.`c2` > '0'))
select * from t1, t3
where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where b1 < '9') and
(c1, c2) in (select c1, c2 from t3
@@ -513,7 +513,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
Note 1276 Field or reference 'test.t1.a2' of SELECT #6 was resolved in SELECT #1
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2i`.`b2` = `test`.`t1`.`a2`) and (`test`.`t3c`.`c2` = `test`.`t1`.`a2`) and (`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b1` = `test`.`t1`.`a1`) and (`test`.`t3c`.`c1` = `test`.`t1`.`a1`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2i`.`b1` = `test`.`t1`.`a1`) and (`test`.`t3c`.`c1` = `test`.`t1`.`a1`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b2` = `test`.`t1`.`a2`) and (`test`.`t3c`.`c2` = `test`.`t1`.`a2`) and (`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))))
explain extended
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
id select_type table type possible_keys key key_len ref rows filtered Extra
@@ -633,7 +633,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where ((`test`.`t2_16`.`b2` = `test`.`t1_16`.`a2`) and (`test`.`t2_16`.`b1` = `test`.`t1_16`.`a1`) and (`test`.`t1_16`.`a1` > '0'))
+Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where ((`test`.`t2_16`.`b1` = `test`.`t1_16`.`a1`) and (`test`.`t2_16`.`b2` = `test`.`t1_16`.`a2`) and (`test`.`t1_16`.`a1` > '0'))
select left(a1,7), left(a2,7)
from t1_16
where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
@@ -700,7 +700,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2_16` join `test`.`t2` join `test`.`t1_16`) where ((`test`.`t2_16`.`b2` = `test`.`t1_16`.`a2`) and (`test`.`t2_16`.`b1` = `test`.`t1_16`.`a1`) and (`test`.`t2`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2`.`b2` = substr(`test`.`t1_16`.`a2`,1,6)) and (`test`.`t3`.`c2` > '0') and (concat(`test`.`t1`.`a1`,'x') = left(`test`.`t1_16`.`a1`,8)))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t3` join `test`.`t2_16` join `test`.`t2` join `test`.`t1_16`) where ((`test`.`t2`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2_16`.`b1` = `test`.`t1_16`.`a1`) and (`test`.`t2_16`.`b2` = `test`.`t1_16`.`a2`) and (`test`.`t2`.`b2` = substr(`test`.`t1_16`.`a2`,1,6)) and (`test`.`t3`.`c2` > '0') and (concat(`test`.`t1`.`a1`,'x') = left(`test`.`t1_16`.`a1`,8)))
drop table t1_16, t2_16, t3_16;
set @blob_len = 512;
set @suffix_len = @blob_len - @prefix_len;
@@ -748,7 +748,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
1 PRIMARY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where ((`test`.`t2_512`.`b2` = `test`.`t1_512`.`a2`) and (`test`.`t2_512`.`b1` = `test`.`t1_512`.`a1`) and (`test`.`t1_512`.`a1` > '0'))
+Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where ((`test`.`t2_512`.`b1` = `test`.`t1_512`.`a1`) and (`test`.`t2_512`.`b2` = `test`.`t1_512`.`a2`) and (`test`.`t1_512`.`a1` > '0'))
select left(a1,7), left(a2,7)
from t1_512
where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
@@ -844,7 +844,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where ((`test`.`t2_1024`.`b2` = `test`.`t1_1024`.`a2`) and (`test`.`t2_1024`.`b1` = `test`.`t1_1024`.`a1`) and (`test`.`t1_1024`.`a1` > '0'))
+Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where ((`test`.`t2_1024`.`b1` = `test`.`t1_1024`.`a1`) and (`test`.`t2_1024`.`b2` = `test`.`t1_1024`.`a2`) and (`test`.`t1_1024`.`a1` > '0'))
select left(a1,7), left(a2,7)
from t1_1024
where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
@@ -939,7 +939,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where ((`test`.`t2_1025`.`b2` = `test`.`t1_1025`.`a2`) and (`test`.`t2_1025`.`b1` = `test`.`t1_1025`.`a1`) and (`test`.`t1_1025`.`a1` > '0'))
+Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where ((`test`.`t2_1025`.`b1` = `test`.`t1_1025`.`a1`) and (`test`.`t2_1025`.`b2` = `test`.`t1_1025`.`a2`) and (`test`.`t1_1025`.`a1` > '0'))
select left(a1,7), left(a2,7)
from t1_1025
where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
@@ -1027,7 +1027,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1bb ALL NULL NULL NULL NULL 3 100.00
1 PRIMARY t2bb ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select conv(`test`.`t1bb`.`a1`,10,2) AS `bin(a1)`,`test`.`t1bb`.`a2` AS `a2` from `test`.`t1bb` semi join (`test`.`t2bb`) where ((`test`.`t2bb`.`b2` = `test`.`t1bb`.`a2`) and (`test`.`t2bb`.`b1` = `test`.`t1bb`.`a1`))
+Note 1003 select conv(`test`.`t1bb`.`a1`,10,2) AS `bin(a1)`,`test`.`t1bb`.`a2` AS `a2` from `test`.`t1bb` semi join (`test`.`t2bb`) where ((`test`.`t2bb`.`b1` = `test`.`t1bb`.`a1`) and (`test`.`t2bb`.`b2` = `test`.`t1bb`.`a2`))
select bin(a1), a2
from t1bb
where (a1, a2) in (select b1, b2 from t2bb);
@@ -1934,7 +1934,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
2 MATERIALIZED t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where ((`test`.`t1`.`a` = `<subquery2>`.`MAX(c)`) and (`test`.`t1`.`b` = 7) and (<cache>(isnull(`<subquery2>`.`MAX(c)`)) or (`<subquery2>`.`MAX(c)` = 7)))
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from <materialize> (select max(`test`.`t2`.`c`) from `test`.`t2`) join `test`.`t1` where ((`test`.`t1`.`b` = 7) and (`test`.`t1`.`a` = `<subquery2>`.`MAX(c)`) and (<cache>(isnull(`<subquery2>`.`MAX(c)`)) or (`<subquery2>`.`MAX(c)` = 7)))
SELECT * FROM t1
WHERE a IN (SELECT MAX(c) FROM t2) AND b=7 AND (a IS NULL OR a=b);
a b
diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result
index 813f912c5af..d373d14c089 100644
--- a/mysql-test/r/type_enum.result
+++ b/mysql-test/r/type_enum.result
@@ -1854,3 +1854,18 @@ a
DROP TABLE t1;
End of 5.1 tests
+#
+# MDEV-4241: Assertion failure: scale >= 0 && precision > 0 &&
+# scale <= precision in decimal_bin_size
+#
+CREATE TABLE t1 (
+f1 enum('1','2','3','4','5')
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+SELECT AVG(f1) FROM t1;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def AVG(f1) 246 7 6 Y 32896 4 63
+AVG(f1)
+1.5000
+drop table t1;
+End of 5.3 tests
diff --git a/mysql-test/r/user_var-binlog.result b/mysql-test/r/user_var-binlog.result
index 68d2364986d..ae4bd68a435 100644
--- a/mysql-test/r/user_var-binlog.result
+++ b/mysql-test/r/user_var-binlog.result
@@ -18,6 +18,7 @@ master-bin.000001 # User var # # @`var2`=_binary 0x61 COLLATE binary
master-bin.000001 # Query # # use `test`; insert into t1 values (@var1),(@var2)
master-bin.000001 # Query # # COMMIT
flush logs;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -56,4 +57,5 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
drop table t1;
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 9c4fd02fcdd..2a3cdc49802 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -461,43 +461,9 @@ GROUP BY @b:=(SELECT COUNT(*) > t2.a);
@a:=MIN(t1.a)
1
DROP TABLE t1;
-End of 5.1 tests
-DROP TABLE IF EXISTS t1;
-CREATE TABLE t1(f1 INT AUTO_INCREMENT, PRIMARY KEY(f1));
-INSERT INTO t1 SET f1 = NULL ;
-SET @aux = NULL ;
-INSERT INTO t1 SET f1 = @aux ;
-SET @aux1 = 0.123E-1;
-SET @aux1 = NULL;
-INSERT INTO t1 SET f1 = @aux1 ;
-SELECT * FROM t1;
-f1
-1
-2
-3
-DROP TABLE t1;
-CREATE TABLE t1(f1 VARCHAR(257) , f2 INT, PRIMARY KEY(f2));
-CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW SET @aux = 1;
-SET @aux = 1;
-SET @aux = NULL;
-INSERT INTO test.t1 (f1, f2) VALUES (1, 1), (@aux, 2);
-SET @aux = 'text';
-SET @aux = NULL;
-INSERT INTO t1(f1, f2) VALUES (1, 3), (@aux, 4);
-SELECT f1, f2 FROM t1 ORDER BY f2;
-f1 f2
-1 1
-1 2
-1 3
-1 4
-DROP TRIGGER trg1;
-DROP TABLE t1;
-#
-# Bug #12408412: GROUP_CONCAT + ORDER BY + INPUT/OUTPUT
-# SAME USER VARIABLE = CRASH
-#
SET @bug12408412=1;
SELECT GROUP_CONCAT(@bug12408412 ORDER BY 1) INTO @bug12408412;
+End of 5.1 tests
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (0);
SELECT DISTINCT POW(COUNT(*), @a:=(SELECT 1 FROM t1 LEFT JOIN t1 AS t2 ON @a))
@@ -530,4 +496,34 @@ SELECT @a;
@a
1
DROP TABLE t1;
+End of 5.2 tests
+CREATE TABLE t1(f1 INT AUTO_INCREMENT, PRIMARY KEY(f1));
+INSERT INTO t1 SET f1 = NULL ;
+SET @aux = NULL ;
+INSERT INTO t1 SET f1 = @aux ;
+SET @aux1 = 0.123E-1;
+SET @aux1 = NULL;
+INSERT INTO t1 SET f1 = @aux1 ;
+SELECT * FROM t1;
+f1
+1
+2
+3
+DROP TABLE t1;
+CREATE TABLE t1(f1 VARCHAR(257) , f2 INT, PRIMARY KEY(f2));
+CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW SET @aux = 1;
+SET @aux = 1;
+SET @aux = NULL;
+INSERT INTO test.t1 (f1, f2) VALUES (1, 1), (@aux, 2);
+SET @aux = 'text';
+SET @aux = NULL;
+INSERT INTO t1(f1, f2) VALUES (1, 3), (@aux, 4);
+SELECT f1, f2 FROM t1 ORDER BY f2;
+f1 f2
+1 1
+1 2
+1 3
+1 4
+DROP TRIGGER trg1;
+DROP TABLE t1;
End of 5.5 tests
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 8f32ca1f566..576752f65c9 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -1423,7 +1423,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on(((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`a`)))) on((`test`.`t1`.`a` = `test`.`t3`.`a`)) where 1
+Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on((`test`.`t2`.`a` = `test`.`t3`.`a`))) on((`test`.`t1`.`a` = `test`.`t3`.`a`)) where 1
create view v1 (a) as select a from t1;
create view v2 (a) as select a from t2;
create view v4 (a,b) as select v1.a as a, v2.a as b from v1 left join v2 on (v1.a=v2.a);
@@ -1438,7 +1438,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join (`test`.`t2`) on(((`test`.`t1`.`a` = `test`.`t3`.`a`) and (`test`.`t2`.`a` = `test`.`t3`.`a`)))) on((`test`.`t1`.`a` = `test`.`t3`.`a`)) where 1
+Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `b` from `test`.`t3` left join (`test`.`t1` left join (`test`.`t2`) on((`test`.`t2`.`a` = `test`.`t3`.`a`))) on((`test`.`t1`.`a` = `test`.`t3`.`a`)) where 1
prepare stmt1 from "select * from t3 left join v4 on (t3.a = v4.a);";
execute stmt1;
a a b
diff --git a/mysql-test/suite/binlog/r/binlog_base64_flag.result b/mysql-test/suite/binlog/r/binlog_base64_flag.result
index f84995cac3b..26eab9f141d 100644
--- a/mysql-test/suite/binlog/r/binlog_base64_flag.result
+++ b/mysql-test/suite/binlog/r/binlog_base64_flag.result
@@ -29,6 +29,7 @@ a
1
3
==== Test --base64-output=never on a binlog with row events ====
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -51,6 +52,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
==== Test non-matching FD event and Row event ====
BINLOG '
4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog2.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog2.result
index 806cf74479e..b86e715869f 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog2.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog2.result
@@ -15,6 +15,7 @@ set timestamp=@a+1;
insert into t1 values(null, "f");
--- Local --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -85,8 +86,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- offset --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -154,8 +157,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- start-position --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -203,8 +208,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- stop-position --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -245,8 +252,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- start and stop positions ---
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -271,8 +280,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- start-datetime --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -320,8 +331,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- stop-datetime --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -362,9 +375,11 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- Local with 2 binlogs on command line --
flush logs;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -456,8 +471,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- offset --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -546,8 +563,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- start-position --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -616,8 +635,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- stop-position --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -702,8 +723,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- start-datetime --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -772,8 +795,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- stop-datetime --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -814,8 +839,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- Remote --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -886,8 +913,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- offset --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -955,8 +984,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- start-position --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1003,8 +1034,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- stop-position --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1045,8 +1078,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- start and stop positions ---
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1070,8 +1105,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- start-datetime --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1119,8 +1156,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- stop-datetime --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1161,8 +1200,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- Remote with 2 binlogs on command line --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1254,8 +1295,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- offset --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1344,8 +1387,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- start-position --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1413,8 +1458,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- stop-position --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1498,8 +1545,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- start-datetime --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1568,8 +1617,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- stop-datetime --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1610,8 +1661,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- to-last-log --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1692,6 +1745,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- end of test --
drop table t1;
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result
index 84a6d6c3baf..fc22085496d 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result
@@ -328,6 +328,7 @@ INSERT INTO t2 SET b=1;
UPDATE t1, t2 SET t1.a=10, t2.a=20;
DROP TABLE t1,t2;
flush logs;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -4135,3 +4136,4 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result
index 31d7ee0df98..8e75d203ecc 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result
@@ -2245,6 +2245,7 @@ FLUSH LOGS;
#
# Call mysqlbinlog to display the log file contents.
#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -3786,6 +3787,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# Cleanup.
#
@@ -3868,6 +3870,7 @@ FLUSH LOGS;
#
# Call mysqlbinlog to display the log file contents.
#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -4077,6 +4080,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# Cleanup.
#
@@ -4235,6 +4239,7 @@ FLUSH LOGS;
#
# Call mysqlbinlog to display the log file contents.
#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -4746,6 +4751,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# Cleanup.
#
@@ -4796,6 +4802,7 @@ FLUSH LOGS;
#
# Call mysqlbinlog to display the log file contents.
#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -4853,6 +4860,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# Cleanup.
#
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result
index c268d20c87d..b4ea8551ca6 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result
@@ -2245,6 +2245,7 @@ FLUSH LOGS;
#
# Call mysqlbinlog to display the log file contents.
#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -3808,6 +3809,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# Cleanup.
#
@@ -3890,6 +3892,7 @@ FLUSH LOGS;
#
# Call mysqlbinlog to display the log file contents.
#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -4105,6 +4108,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# Cleanup.
#
@@ -4263,6 +4267,7 @@ FLUSH LOGS;
#
# Call mysqlbinlog to display the log file contents.
#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -4784,6 +4789,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# Cleanup.
#
@@ -4834,6 +4840,7 @@ FLUSH LOGS;
#
# Call mysqlbinlog to display the log file contents.
#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -4893,6 +4900,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# Cleanup.
#
diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result
index 5d08a1095a9..77e096dd065 100644
--- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result
+++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result
@@ -124,6 +124,7 @@ FLUSH LOGS;
#
# Call mysqlbinlog to display the log file contents.
#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -463,6 +464,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# Cleanup.
#
diff --git a/mysql-test/suite/binlog/r/binlog_row_annotate.result b/mysql-test/suite/binlog/r/binlog_row_annotate.result
index a305f39fb16..7060343616e 100644
--- a/mysql-test/suite/binlog/r/binlog_row_annotate.result
+++ b/mysql-test/suite/binlog/r/binlog_row_annotate.result
@@ -60,6 +60,7 @@ master-bin.000001 # Rotate 1 # master-bin.000002;pos=4
# - INSERT INTO test2.t2 VALUES (1), (2), (3)
# - DELETE xtest1.xt1, test2.t2 FROM <...> (with one subsequent Table map)
#####################################################################################
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -280,12 +281,14 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
#####################################################################################
# mysqlbinlog --database=test1
# The following Annotate should appear in this output:
# - DELETE test1.t1, test2.t2 FROM <...>
#####################################################################################
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -425,11 +428,13 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
#####################################################################################
# mysqlbinlog --skip-annotate-row-events
# No Annotates should appear in this output
#####################################################################################
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -636,6 +641,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
#####################################################################################
# mysqlbinlog --read-from-remote-server
@@ -646,6 +652,7 @@ ROLLBACK /* added by mysqlbinlog */;
# - INSERT INTO test2.t2 VALUES (1), (2), (3)
# - DELETE xtest1.xt1, test2.t2 FROM <...> (with one subsequent Table map)
#####################################################################################
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -866,12 +873,14 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
#####################################################################################
# mysqlbinlog --read-from-remote-server --database=test1
# The following Annotate should appear in this output:
# - DELETE test1.t1, test2.t2 FROM <...>
#####################################################################################
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1011,11 +1020,13 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
#####################################################################################
# mysqlbinlog --read-from-remote-server --skip-annotate-row-events
# No Annotates should appear in this output
#####################################################################################
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1217,3 +1228,4 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
diff --git a/mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result b/mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result
index f0519a9d724..f5d19d08a29 100644
--- a/mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result
+++ b/mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result
@@ -10,6 +10,7 @@ master-bin.000001 # Table_map # # table_id: # (test.t2)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # COMMIT
flush logs;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -32,4 +33,5 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
drop table t2;
diff --git a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result
index 08919db5ed1..74565d976e4 100644
--- a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result
+++ b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result
@@ -28,6 +28,7 @@ flush logs;
# --rewrite-db = test1->new_test1
# --rewrite-db = test3->new_test3
#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -215,6 +216,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
#
# mysqlbinlog output
# --base64-output = decode-rows
@@ -222,6 +224,7 @@ ROLLBACK /* added by mysqlbinlog */;
# --rewrite-db = test3->new_test3
# --read-from-remote-server
#
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -409,6 +412,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
DROP DATABASE test1;
DROP DATABASE test2;
DROP DATABASE test3;
diff --git a/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result b/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result
index 3207b9c2180..3a5c3ac4b02 100644
--- a/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result
+++ b/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result
@@ -10,6 +10,7 @@ master-bin.000001 # User var # # @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_
master-bin.000001 # Query # # use `test`; insert into t2 values (@v)
master-bin.000001 # Query # # COMMIT
flush logs;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -37,4 +38,5 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
drop table t2;
diff --git a/mysql-test/suite/engines/funcs/disabled.def b/mysql-test/suite/engines/funcs/disabled.def
index 2d8ea2d4ff8..c43b0c92bc9 100644
--- a/mysql-test/suite/engines/funcs/disabled.def
+++ b/mysql-test/suite/engines/funcs/disabled.def
@@ -70,7 +70,6 @@ rpl_replicate_ignore_db : Result Difference Due To Change In .inc file
rpl000017 : Result Difference Due To Change In .inc file
rpl_skip_error : Result Difference Due To Change In .inc file
-rpl_row_until : Test Present in rpl suite as well . Test Fails table with t2 table not found.
rpl_loaddata_s : Test Present in rpl suite as well . Test Fails due to bin log truncation.
rpl_log_pos : Test Present in rpl suite as well . Test Fails due to bin log truncation.
rpl_row_NOW : Result Difference Due To Change In .inc file
@@ -96,4 +95,3 @@ rpl_relayspace : Result Difference Due To Change In .inc file
rpl_row_inexist_tbl : Result Difference Due To Change In .inc file
rpl_sp : Result Difference Due To Change In .inc file
rpl_rbr_to_sbr : Result Difference Due To Change In .inc file
-rpl_row_until : Test Timesout
diff --git a/mysql-test/suite/engines/funcs/r/rpl_row_until.result b/mysql-test/suite/engines/funcs/r/rpl_row_until.result
index d8637578ecc..5629f5c8cdd 100644
--- a/mysql-test/suite/engines/funcs/r/rpl_row_until.result
+++ b/mysql-test/suite/engines/funcs/r/rpl_row_until.result
@@ -1,212 +1,60 @@
-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;
+include/master-slave.inc
+[connection 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;
+include/stop_slave.inc
+RESET SLAVE;
+START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=master_pos_drop_t1
+include/wait_for_slave_sql_to_stop.inc
+SELECT * FROM t1;
n
1
2
3
4
-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 slave-relay-bin.000004
-Relay_Log_Pos #
-Relay_Master_Log_File master-bin.000001
-Slave_IO_Running #
-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 0
-Last_Error
-Skip_Counter 0
-Exec_Master_Log_Pos #
-Relay_Log_Space #
-Until_Condition Master
-Until_Log_File master-bin.000001
-Until_Log_Pos 311
-Master_SSL_Allowed No
-Master_SSL_CA_File
-Master_SSL_CA_Path
-Master_SSL_Cert
-Master_SSL_Cipher
-Master_SSL_Key
-Seconds_Behind_Master #
-Master_SSL_Verify_Server_Cert No
-Last_IO_Errno 0
-Last_IO_Error
-Last_SQL_Errno 0
-Last_SQL_Error
-Replicate_Ignore_Server_Ids
-Master_Server_Id 1
-start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
-select * from t1;
-n 1
-n 2
-n 3
-n 4
-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 slave-relay-bin.000004
-Relay_Log_Pos #
-Relay_Master_Log_File master-bin.000001
-Slave_IO_Running #
-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 0
-Last_Error
-Skip_Counter 0
-Exec_Master_Log_Pos #
-Relay_Log_Space #
-Until_Condition Master
-Until_Log_File master-no-such-bin.000001
-Until_Log_Pos 291
-Master_SSL_Allowed No
-Master_SSL_CA_File
-Master_SSL_CA_Path
-Master_SSL_Cert
-Master_SSL_Cipher
-Master_SSL_Key
-Seconds_Behind_Master #
-Master_SSL_Verify_Server_Cert No
-Last_IO_Errno 0
-Last_IO_Error
-Last_SQL_Errno 0
-Last_SQL_Error
-Replicate_Ignore_Server_Ids
-Master_Server_Id 1
-start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728;
-select * from t2;
-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 slave-relay-bin.000004
-Relay_Log_Pos #
-Relay_Master_Log_File master-bin.000001
-Slave_IO_Running #
-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 0
-Last_Error
-Skip_Counter 0
-Exec_Master_Log_Pos #
-Relay_Log_Space #
-Until_Condition Relay
-Until_Log_File slave-relay-bin.000004
-Until_Log_Pos 728
-Master_SSL_Allowed No
-Master_SSL_CA_File
-Master_SSL_CA_Path
-Master_SSL_Cert
-Master_SSL_Cipher
-Master_SSL_Key
-Seconds_Behind_Master #
-Master_SSL_Verify_Server_Cert No
-Last_IO_Errno 0
-Last_IO_Error
-Last_SQL_Errno 0
-Last_SQL_Error
-Replicate_Ignore_Server_Ids
-Master_Server_Id 1
-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 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 slave-relay-bin.000004
-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 0
-Last_Error
-Skip_Counter 0
-Exec_Master_Log_Pos #
-Relay_Log_Space #
-Until_Condition Master
-Until_Log_File master-bin.000001
-Until_Log_Pos 740
-Master_SSL_Allowed No
-Master_SSL_CA_File
-Master_SSL_CA_Path
-Master_SSL_Cert
-Master_SSL_Cipher
-Master_SSL_Key
-Seconds_Behind_Master #
-Master_SSL_Verify_Server_Cert No
-Last_IO_Errno 0
-Last_IO_Error
-Last_SQL_Errno 0
-Last_SQL_Error
-Replicate_Ignore_Server_Ids
-Master_Server_Id 1
-start slave until master_log_file='master-bin', master_log_pos=561;
+include/check_slave_param.inc [Exec_Master_Log_Pos]
+START SLAVE UNTIL MASTER_LOG_FILE='master-no-such-bin.000001', MASTER_LOG_POS=MASTER_LOG_POS;
+include/wait_for_slave_sql_to_stop.inc
+SELECT * FROM t1;
+n
+1
+2
+3
+4
+include/check_slave_param.inc [Exec_Master_Log_Pos]
+START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', RELAY_LOG_POS=relay_pos_insert1_t2
+include/wait_for_slave_sql_to_stop.inc
+SELECT * FROM t2;
+n
+1
+2
+include/check_slave_param.inc [Exec_Master_Log_Pos]
+START SLAVE;
+include/wait_for_slave_to_start.inc
+include/stop_slave.inc
+START SLAVE SQL_THREAD UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=master_pos_create_t2
+include/wait_for_slave_param.inc [Until_Log_Pos]
+include/wait_for_slave_sql_to_stop.inc
+include/check_slave_param.inc [Exec_Master_Log_Pos]
+START SLAVE UNTIL MASTER_LOG_FILE='master-bin', MASTER_LOG_POS=MASTER_LOG_POS;
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;
+START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=MASTER_LOG_POS, RELAY_LOG_POS=RELAY_LOG_POS;
ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL
-start slave until master_log_file='master-bin.000001';
+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';
+START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000009';
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;
+START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', MASTER_LOG_POS=MASTER_LOG_POS;
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;
+START SLAVE;
+START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=MASTER_LOG_POS;
Warnings:
-Level Note
-Code 1254
-Message Slave is already running
+Note 1254 Slave is already running
+include/stop_slave.inc
+RESET SLAVE;
+include/rpl_end.inc
diff --git a/mysql-test/suite/engines/funcs/t/rpl_row_until.test b/mysql-test/suite/engines/funcs/t/rpl_row_until.test
index ccd9ce11637..bf38bd487ea 100644
--- a/mysql-test/suite/engines/funcs/t/rpl_row_until.test
+++ b/mysql-test/suite/engines/funcs/t/rpl_row_until.test
@@ -2,90 +2,126 @@
-- source include/have_binlog_format_row.inc
-- source include/master-slave.inc
-# Test is dependent on binlog positions
+# Note: The test is dependent on binlog positions
-# prepare version for substitutions
-let $VERSION=`select version()`;
+# Create some events on master
+connection master;
+CREATE TABLE t1(n INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+DROP TABLE t1;
+# Save master log position for query DROP TABLE t1
+save_master_pos;
+let $master_pos_drop_t1= query_get_value(SHOW BINLOG EVENTS, Pos, 7);
+let $master_log_file= query_get_value(SHOW BINLOG EVENTS, Log_name, 7);
-# stop slave before he will start replication also sync with master
-# for avoiding undetermenistic behaviour
+CREATE TABLE t2(n INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
+# Save master log position for query CREATE TABLE t2
save_master_pos;
-connection slave;
-sync_with_master;
-stop slave;
+let $master_pos_create_t2= query_get_value(SHOW BINLOG EVENTS, Pos, 8);
+
+INSERT INTO t2 VALUES (1),(2);
+save_master_pos;
+# Save master log position for query INSERT INTO t2 VALUES (1),(2);
+let $master_pos_insert1_t2= query_get_value(SHOW BINLOG EVENTS, End_log_pos, 12);
+sync_slave_with_master;
+
+# Save relay log position for query INSERT INTO t2 VALUES (1),(2);
+let $relay_pos_insert1_t2= query_get_value(show slave status, Relay_Log_Pos, 1);
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
+INSERT INTO t2 VALUES (3),(4);
+DROP TABLE t2;
+# Save master log position for query INSERT INTO t2 VALUES (1),(2);
+let $master_pos_drop_t2= query_get_value(SHOW BINLOG EVENTS, End_log_pos, 17);
+sync_slave_with_master;
+
+--source include/stop_slave.inc
+# Reset slave.
+RESET SLAVE;
+--disable_query_log
+eval CHANGE MASTER TO MASTER_USER='root', MASTER_CONNECT_RETRY=1, MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT;
+--enable_query_log
+
+# 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;
---vertical_results
---replace_result $MASTER_MYPORT MASTER_MYPORT
---replace_column 1 # 7 # 9 # 11 # 22 # 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;
+echo START SLAVE UNTIL MASTER_LOG_FILE='$master_log_file', MASTER_LOG_POS=master_pos_drop_t1;
+--disable_query_log
+eval START SLAVE UNTIL MASTER_LOG_FILE='$master_log_file', MASTER_LOG_POS=$master_pos_drop_t1;
+--enable_query_log
+--source include/wait_for_slave_sql_to_stop.inc
+
+# Here table should be still not deleted
+SELECT * FROM t1;
+--let $slave_param= Exec_Master_Log_Pos
+--let $slave_param_value= $master_pos_drop_t1
+--source include/check_slave_param.inc
+
+# This should fail right after start
+--replace_result 291 MASTER_LOG_POS
+START SLAVE UNTIL MASTER_LOG_FILE='master-no-such-bin.000001', MASTER_LOG_POS=291;
+--source include/wait_for_slave_sql_to_stop.inc
# again this table should be still not deleted
-select * from t1;
-sleep 2;
-wait_for_slave_to_stop;
---vertical_results
---replace_result $MASTER_MYPORT MASTER_MYPORT
---replace_column 1 # 7 # 9 # 11 # 22 # 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;
---vertical_results
---replace_result $MASTER_MYPORT MASTER_MYPORT
---replace_column 1 # 7 # 9 # 11 # 22 # 23 # 33 #
-show slave status;
+SELECT * FROM t1;
+
+--let $slave_param= Exec_Master_Log_Pos
+--let $slave_param_value= $master_pos_drop_t1
+--source include/check_slave_param.inc
+
+# Try replicate all up to and not including the second insert to t2;
+echo START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', RELAY_LOG_POS=relay_pos_insert1_t2;
+--disable_query_log
+eval START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', RELAY_LOG_POS=$relay_pos_insert1_t2;
+--enable_query_log
+--source include/wait_for_slave_sql_to_stop.inc
+SELECT * FROM t2;
+
+--let $slave_param= Exec_Master_Log_Pos
+--let $slave_param_value= $master_pos_insert1_t2
+--source include/check_slave_param.inc
# clean up
-start slave;
+START SLAVE;
+--source include/wait_for_slave_to_start.inc
connection master;
-save_master_pos;
-connection slave;
-sync_with_master;
-stop slave;
+sync_slave_with_master;
+--source include/stop_slave.inc
-# 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;
+# This should stop immediately as we are already there
+echo START SLAVE SQL_THREAD UNTIL MASTER_LOG_FILE='$master_log_file', MASTER_LOG_POS=master_pos_create_t2;
+--disable_query_log
+eval START SLAVE SQL_THREAD UNTIL MASTER_LOG_FILE='$master_log_file', MASTER_LOG_POS=$master_pos_create_t2;
+--enable_query_log
+let $slave_param= Until_Log_Pos;
+let $slave_param_value= $master_pos_create_t2;
+--source include/wait_for_slave_param.inc
+--source include/wait_for_slave_sql_to_stop.inc
# here the sql slave thread should be stopped
---vertical_results
---replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004
---replace_column 1 # 7 # 9 # 22 # 23 # 33 #
-show slave status;
+--let $slave_param= Exec_Master_Log_Pos
+--let $slave_param_value= $master_pos_drop_t2
+--source include/check_slave_param.inc
#testing various error conditions
+--replace_result 561 MASTER_LOG_POS
--error 1277
-start slave until master_log_file='master-bin', master_log_pos=561;
+START SLAVE UNTIL MASTER_LOG_FILE='master-bin', MASTER_LOG_POS=561;
+--replace_result 561 MASTER_LOG_POS 12 RELAY_LOG_POS
--error 1277
-start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12;
+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';
+START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001';
--error 1277
-start slave until relay_log_file='slave-relay-bin.000002';
+START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000009';
+--replace_result 561 MASTER_LOG_POS
--error 1277
-start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=561;
+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;
+START SLAVE;
+--replace_result 740 MASTER_LOG_POS
+START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=740;
+
+--source include/stop_slave.inc
+# Clear slave IO error.
+RESET SLAVE;
+
+--let $rpl_only_running_threads= 1
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/heap/heap.result b/mysql-test/suite/heap/heap.result
index ae562a0dda1..e61b9bcc2bf 100644
--- a/mysql-test/suite/heap/heap.result
+++ b/mysql-test/suite/heap/heap.result
@@ -738,6 +738,26 @@ SELECT c2 FROM t1;
c2
0
DROP TABLE t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL AUTO_INCREMENT,
+color enum('GREEN', 'WHITE') DEFAULT NULL,
+ts int,
+PRIMARY KEY (id),
+KEY color (color) USING HASH
+) ENGINE=MEMORY DEFAULT CHARSET=utf8;
+INSERT INTO t1 VALUES("1","GREEN",1);
+INSERT INTO t1 VALUES("2","GREEN",1);
+INSERT INTO t1 VALUES("3","GREEN",1);
+INSERT INTO t1 VALUES("4","GREEN",1);
+INSERT INTO t1 VALUES("5","GREEN",1);
+INSERT INTO t1 VALUES("6","GREEN",1);
+DELETE FROM t1 WHERE id = 1;
+INSERT INTO t1 VALUES("7","GREEN", 2);
+DELETE FROM t1 WHERE ts = 1 AND color = 'GREEN';
+SELECT * from t1;
+id color ts
+7 GREEN 2
+DROP TABLE t1;
CREATE TABLE t1 (a int, index(a)) engine=heap min_rows=10 max_rows=100;
insert into t1 values(1);
select data_length,index_length from information_schema.tables where table_schema="test" and table_name="t1";
diff --git a/mysql-test/suite/heap/heap.test b/mysql-test/suite/heap/heap.test
index 6f5046af139..ab2a4f0a6d6 100644
--- a/mysql-test/suite/heap/heap.test
+++ b/mysql-test/suite/heap/heap.test
@@ -487,6 +487,32 @@ SELECT c2 FROM t1;
DROP TABLE t1;
#
+# BUG#51763 Can't delete rows from MEMORY table with HASH key
+#
+
+CREATE TABLE t1 (
+ id int(11) NOT NULL AUTO_INCREMENT,
+ color enum('GREEN', 'WHITE') DEFAULT NULL,
+ ts int,
+ PRIMARY KEY (id),
+ KEY color (color) USING HASH
+) ENGINE=MEMORY DEFAULT CHARSET=utf8;
+
+INSERT INTO t1 VALUES("1","GREEN",1);
+INSERT INTO t1 VALUES("2","GREEN",1);
+INSERT INTO t1 VALUES("3","GREEN",1);
+INSERT INTO t1 VALUES("4","GREEN",1);
+INSERT INTO t1 VALUES("5","GREEN",1);
+INSERT INTO t1 VALUES("6","GREEN",1);
+DELETE FROM t1 WHERE id = 1;
+INSERT INTO t1 VALUES("7","GREEN", 2);
+DELETE FROM t1 WHERE ts = 1 AND color = 'GREEN';
+SELECT * from t1;
+DROP TABLE t1;
+
+# End of 5.1 tests
+
+#
# Show that MIN_ROWS and MAX_ROWS have an effect on how data_length
# and index_length are allocated.
# Result is different for 32 / 64 bit machines as pointer lengths are different
diff --git a/mysql-test/suite/innodb/disabled.def b/mysql-test/suite/innodb/disabled.def
index 0e7cd067056..8cae44a3607 100644
--- a/mysql-test/suite/innodb/disabled.def
+++ b/mysql-test/suite/innodb/disabled.def
@@ -10,4 +10,3 @@
#
##############################################################################
-innodb_bug12400341: variable innodb_trx_rseg_n_slots_debug is removed in MariaDB
diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result
index 48390b14a82..5b0fccbe615 100644
--- a/mysql-test/suite/innodb/r/innodb-index.result
+++ b/mysql-test/suite/innodb/r/innodb-index.result
@@ -956,7 +956,7 @@ Table Op Msg_type Msg_text
test.t1 check status OK
explain select * from t1 where b like 'adfd%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL b NULL NULL NULL 15 Using where
+1 SIMPLE t1 range b b 769 NULL 11 Using where
drop table t1;
set global innodb_file_per_table=on;
set global innodb_file_format='Barracuda';
diff --git a/mysql-test/suite/innodb/r/innodb_bug14147491.result b/mysql-test/suite/innodb/r/innodb_bug14147491.result
new file mode 100644
index 00000000000..6279f85f676
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bug14147491.result
@@ -0,0 +1,17 @@
+CALL mtr.add_suppression("InnoDB: Error: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts");
+CALL mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
+# Create and populate the table to be corrupted
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB;
+INSERT INTO t1 (b) VALUES ('corrupt me');
+INSERT INTO t1 (b) VALUES ('corrupt me');
+# Restart server to flush buffers
+# Corrupt the table
+Munged a string.
+Munged a string.
+# Write file to make mysql-test-run.pl expect crash and restart
+SELECT * FROM t1;
+ERROR HY000: Lost connection to MySQL server during query
+# Turn on reconnect
+# Wait for server to fully start
+# Cleanup
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb_bug14676111.result b/mysql-test/suite/innodb/r/innodb_bug14676111.result
new file mode 100644
index 00000000000..ebecd1d00cb
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bug14676111.result
@@ -0,0 +1,53 @@
+drop table if exists t1;
+CREATE TABLE t1 (a int not null primary key) engine=InnoDB;
+set global innodb_limit_optimistic_insert_debug = 2;
+insert into t1 values (1);
+insert into t1 values (5);
+insert into t1 values (4);
+insert into t1 values (3);
+insert into t1 values (2);
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1';
+DATA_LENGTH / 16384
+10.0000
+delete from t1 where a=4;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1';
+DATA_LENGTH / 16384
+8.0000
+delete from t1 where a=5;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1';
+DATA_LENGTH / 16384
+5.0000
+set global innodb_limit_optimistic_insert_debug = 10000;
+delete from t1 where a=2;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1';
+DATA_LENGTH / 16384
+3.0000
+insert into t1 values (2);
+delete from t1 where a=2;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1';
+DATA_LENGTH / 16384
+2.0000
+insert into t1 values (2);
+delete from t1 where a=2;
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1';
+DATA_LENGTH / 16384
+1.0000
+drop table t1;
diff --git a/mysql-test/suite/innodb/r/innodb_bug47777.result b/mysql-test/suite/innodb/r/innodb_bug47777.result
index fbba47edcfc..6625c400d84 100644
--- a/mysql-test/suite/innodb/r/innodb_bug47777.result
+++ b/mysql-test/suite/innodb/r/innodb_bug47777.result
@@ -3,11 +3,11 @@ insert into bug47777 values (geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)'));
select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)');
count(*)
1
-update bug47777 set c2=GeomFromText('POINT(1 1)');
+update bug47777 set c2=GeomFromText('linestring(1 1)');
select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)');
count(*)
0
-select count(*) from bug47777 where c2 = GeomFromText('POINT(1 1)');
+select count(*) from bug47777 where c2 = GeomFromText('linestring(1 1)');
count(*)
1
drop table bug47777;
diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result
index be2b4b28f6a..b2df98bbfa6 100644
--- a/mysql-test/suite/innodb/r/innodb_mysql.result
+++ b/mysql-test/suite/innodb/r/innodb_mysql.result
@@ -343,7 +343,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index; Using temporary
explain select distinct f1, f2 from t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL PRIMARY 5 NULL 3 Using index for group-by; Using temporary
+1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index
drop table t1;
CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20),
INDEX (name));
diff --git a/mysql-test/suite/innodb/t/innodb-zip.test b/mysql-test/suite/innodb/t/innodb-zip.test
index 3db4de3a13b..73601dbe7dc 100644
--- a/mysql-test/suite/innodb/t/innodb-zip.test
+++ b/mysql-test/suite/innodb/t/innodb-zip.test
@@ -1,9 +1,5 @@
-- source include/have_innodb.inc
-if (`select plugin_auth_version <= "1.1.8-29.3" from information_schema.plugins where plugin_name='innodb'`)
-{
- --skip Not fixed in XtraDB 1.1.8-29.3 or earlier
-}
let $per_table=`select @@innodb_file_per_table`;
let $format=`select @@innodb_file_format`;
diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
index db38b48facf..d57a52a2362 100644
--- a/mysql-test/suite/innodb/t/innodb.test
+++ b/mysql-test/suite/innodb/t/innodb.test
@@ -4,11 +4,6 @@
# .\sync\sync0sync.c line 324
# is fixed
-if (`select plugin_auth_version <= "1.1.8-29.3" from information_schema.plugins where plugin_name='innodb'`)
-{
- --skip Not fixed in XtraDB 1.1.8-29.3 or earlier
-}
-
#######################################################################
# #
# Please, DO NOT TOUCH this file as well as the innodb.result file. #
diff --git a/mysql-test/suite/innodb/t/innodb_bug14147491-master.opt b/mysql-test/suite/innodb/t/innodb_bug14147491-master.opt
new file mode 100644
index 00000000000..6b82baca147
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bug14147491-master.opt
@@ -0,0 +1 @@
+--innodb_file_per_table=1 --skip-stack-trace --skip-core-file
diff --git a/mysql-test/suite/innodb/t/innodb_bug14147491.test b/mysql-test/suite/innodb/t/innodb_bug14147491.test
new file mode 100644
index 00000000000..ee3519c53fc
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bug14147491.test
@@ -0,0 +1,75 @@
+#
+# Test opening a corrupted table.
+#
+
+# Don't test under valgrind, memory leaks will occur
+source include/not_valgrind.inc;
+# Avoid CrashReporter popup on Mac
+source include/not_crashrep.inc;
+# Don't test under embedded
+source include/not_embedded.inc;
+# Require InnoDB
+source include/have_innodb.inc;
+
+CALL mtr.add_suppression("InnoDB: Error: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts");
+CALL mtr.add_suppression("InnoDB: Warning: database page corruption or a failed");
+
+--echo # Create and populate the table to be corrupted
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB;
+INSERT INTO t1 (b) VALUES ('corrupt me');
+--disable_query_log
+--let $i = 10
+while ($i)
+{
+ INSERT INTO t1 (b) VALUES (REPEAT('abcdefghijklmnopqrstuvwxyz', 100));
+ dec $i;
+}
+--enable_query_log
+INSERT INTO t1 (b) VALUES ('corrupt me');
+
+--echo # Restart server to flush buffers
+source include/restart_mysqld.inc;
+
+--echo # Corrupt the table
+let $MYSQLD_DATADIR=`select @@datadir`;
+let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd;
+
+perl;
+use strict;
+use warnings;
+use Fcntl qw(:DEFAULT :seek);
+
+my $ibd_file = $ENV{'t1_IBD'};
+
+my $chunk;
+my $len;
+
+sysopen IBD_FILE, $ibd_file, O_RDWR || die "Unable to open $ibd_file";
+
+while ($len = sysread IBD_FILE, $chunk, 1024)
+{
+ if ($chunk =~ s/corrupt me/korrupt me/)
+ {
+ print "Munged a string.\n";
+ sysseek IBD_FILE, -$len, SEEK_CUR;
+ syswrite IBD_FILE, $chunk, $len;
+ }
+}
+
+close IBD_FILE;
+EOF
+
+--echo # Write file to make mysql-test-run.pl expect crash and restart
+--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
+
+--error 2013
+SELECT * FROM t1;
+
+--echo # Turn on reconnect
+--enable_reconnect
+
+--echo # Wait for server to fully start
+--source include/wait_until_connected_again.inc
+
+--echo # Cleanup
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb_bug14676111.test b/mysql-test/suite/innodb/t/innodb_bug14676111.test
new file mode 100644
index 00000000000..fadd111fdc9
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bug14676111.test
@@ -0,0 +1,128 @@
+# Test for bug #14676111: WRONG PAGE_LEVEL WRITTEN FOR UPPER THAN FATHER PAGE AT BTR_LIFT_PAGE_UP()
+
+-- source include/have_innodb.inc
+-- source include/have_debug.inc
+
+if (`select count(*)=0 from information_schema.global_variables where variable_name = 'INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG'`)
+{
+ --skip Test requires InnoDB built with UNIV_DEBUG definition.
+}
+
+--disable_query_log
+set @old_innodb_limit_optimistic_insert_debug = @@innodb_limit_optimistic_insert_debug;
+--enable_query_log
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+CREATE TABLE t1 (a int not null primary key) engine=InnoDB;
+
+let $wait_condition=
+ SELECT VARIABLE_VALUE < 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS
+ WHERE VARIABLE_NAME = 'INNODB_PURGE_TRX_ID_AGE';
+
+#
+# make 4 leveled straight tree
+#
+set global innodb_limit_optimistic_insert_debug = 2;
+insert into t1 values (1);
+insert into t1 values (5);
+#current tree form
+# (1, 5)
+
+insert into t1 values (4);
+#records in a page is limited to 2 artificially. root rise occurs
+#current tree form
+# (1, 5)
+#(1, 4) (5)
+
+insert into t1 values (3);
+#current tree form
+# (1, 5)
+# (1, 4) (5)
+#(1, 3) (4) (5)
+
+insert into t1 values (2);
+#current tree form
+# (1, 5)
+# (1, 4) (5)
+# (1, 3) (4) (5)
+#(1, 2) (3) (4) (5)
+
+analyze table t1;
+select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1';
+
+delete from t1 where a=4;
+--source include/wait_condition.inc
+#deleting 1 record of 2 records don't cause merge artificially.
+#current tree form
+# (1, 5)
+# (1) (5)
+# (1, 3) (5)
+#(1, 2) (3) (5)
+
+analyze table t1;
+select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1';
+
+delete from t1 where a=5;
+--source include/wait_condition.inc
+#deleting 1 record of 2 records don't cause merge artificially.
+#current tree form
+# (1)
+# (1)
+# (1, 3) <- lift up this level next, when deleting node ptr
+#(1, 2) (3) <- merged next
+
+analyze table t1;
+select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1';
+
+#
+# cause merge at level 0
+#
+
+#disable the artificial limitation of records in a page
+set global innodb_limit_optimistic_insert_debug = 10000;
+delete from t1 where a=2;
+--source include/wait_condition.inc
+#merge page occurs. and lift up occurs.
+#current tree form
+# (1)
+# (1)
+# (1, 3)
+
+analyze table t1;
+select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1';
+
+insert into t1 values (2);
+#current tree form
+# (1)
+# (1) <- lift up this level next, because it is not root
+# (1, 2, 3)
+
+delete from t1 where a=2;
+--source include/wait_condition.inc
+#current tree form
+# (1)
+# (1, 3)
+
+analyze table t1;
+select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1';
+
+insert into t1 values (2);
+#current tree form
+# (1)
+# (1, 2, 3) <- lift up this level next, because the father is root
+
+delete from t1 where a=2;
+--source include/wait_condition.inc
+#current tree form
+# (1, 3)
+
+analyze table t1;
+select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1';
+
+drop table t1;
+
+--disable_query_log
+set global innodb_limit_optimistic_insert_debug = @old_innodb_limit_optimistic_insert_debug;
+--enable_query_log
diff --git a/mysql-test/suite/innodb/t/innodb_bug47777.test b/mysql-test/suite/innodb/t/innodb_bug47777.test
index d00509c3814..575d84b97e9 100644
--- a/mysql-test/suite/innodb/t/innodb_bug47777.test
+++ b/mysql-test/suite/innodb/t/innodb_bug47777.test
@@ -14,11 +14,11 @@ insert into bug47777 values (geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)'));
select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)');
# Update table bug47777 should be successful.
-update bug47777 set c2=GeomFromText('POINT(1 1)');
+update bug47777 set c2=GeomFromText('linestring(1 1)');
# Verify the row get updated successfully. The original
-# c2 value should be changed to GeomFromText('POINT(1 1)').
+# c2 value should be changed to GeomFromText('linestring(1 1)').
select count(*) from bug47777 where c2 =geomfromtext('linestring(1 2,3 4,5 6,7 8,9 10)');
-select count(*) from bug47777 where c2 = GeomFromText('POINT(1 1)');
+select count(*) from bug47777 where c2 = GeomFromText('linestring(1 1)');
drop table bug47777;
diff --git a/mysql-test/suite/innodb/t/innodb_bug53591.test b/mysql-test/suite/innodb/t/innodb_bug53591.test
index f0ed4b93c32..9a1c2afbccb 100644
--- a/mysql-test/suite/innodb/t/innodb_bug53591.test
+++ b/mysql-test/suite/innodb/t/innodb_bug53591.test
@@ -1,9 +1,5 @@
--source include/have_innodb.inc
-if (`select plugin_auth_version <= "1.1.8-29.3" from information_schema.plugins where plugin_name='innodb'`)
-{
- --skip Not fixed in XtraDB 1.1.8-29.3 or earlier
-}
let $file_format=`select @@innodb_file_format`;
let $file_per_table=`select @@innodb_file_per_table`;
diff --git a/mysql-test/suite/innodb/t/innodb_prefix_index_liftedlimit.test b/mysql-test/suite/innodb/t/innodb_prefix_index_liftedlimit.test
index 776f5dae517..d7540dff36d 100644
--- a/mysql-test/suite/innodb/t/innodb_prefix_index_liftedlimit.test
+++ b/mysql-test/suite/innodb/t/innodb_prefix_index_liftedlimit.test
@@ -14,10 +14,6 @@
# #
######################################################################
-if (`select plugin_auth_version <= "1.1.8-29.3" from information_schema.plugins where plugin_name='innodb'`)
-{
- --skip Not fixed in XtraDB 1.1.8-29.3 or earlier
-}
# Save innodb variables
let $innodb_file_format_orig=`select @@innodb_file_format`;
diff --git a/mysql-test/suite/maria/maria-gis-rtree-dynamic.result b/mysql-test/suite/maria/maria-gis-rtree-dynamic.result
index f4593f2f10a..ee7135c4851 100644
--- a/mysql-test/suite/maria/maria-gis-rtree-dynamic.result
+++ b/mysql-test/suite/maria/maria-gis-rtree-dynamic.result
@@ -766,35 +766,35 @@ SPATIAL KEY (line)
) row_format=dynamic;
ALTER TABLE t1 DISABLE KEYS;
INSERT INTO t1 (name, kind, line) VALUES
-("Aadaouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
-("Aadassiye", "pp", GeomFromText("POINT(35.816667 36.216667)")),
-("Aadbel", "pp", GeomFromText("POINT(34.533333 36.100000)")),
-("Aadchit", "pp", GeomFromText("POINT(33.347222 35.423611)")),
-("Aadchite", "pp", GeomFromText("POINT(33.347222 35.423611)")),
-("Aadchit el Qoussair", "pp", GeomFromText("POINT(33.283333 35.483333)")),
-("Aaddaye", "pp", GeomFromText("POINT(36.716667 40.833333)")),
-("'Aadeissa", "pp", GeomFromText("POINT(32.823889 35.698889)")),
-("Aaderup", "pp", GeomFromText("POINT(55.216667 11.766667)")),
-("Qalaat Aades", "pp", GeomFromText("POINT(33.503333 35.377500)")),
-("A ad'ino", "pp", GeomFromText("POINT(54.812222 38.209167)")),
-("Aadi Noia", "pp", GeomFromText("POINT(13.800000 39.833333)")),
-("Aad La Macta", "pp", GeomFromText("POINT(35.779444 -0.129167)")),
-("Aadland", "pp", GeomFromText("POINT(60.366667 5.483333)")),
-("Aadliye", "pp", GeomFromText("POINT(33.366667 36.333333)")),
-("Aadloun", "pp", GeomFromText("POINT(33.403889 35.273889)")),
-("Aadma", "pp", GeomFromText("POINT(58.798333 22.663889)")),
-("Aadma Asundus", "pp", GeomFromText("POINT(58.798333 22.663889)")),
-("Aadmoun", "pp", GeomFromText("POINT(34.150000 35.650000)")),
-("Aadneram", "pp", GeomFromText("POINT(59.016667 6.933333)")),
-("Aadneskaar", "pp", GeomFromText("POINT(58.083333 6.983333)")),
-("Aadorf", "pp", GeomFromText("POINT(47.483333 8.900000)")),
-("Aadorp", "pp", GeomFromText("POINT(52.366667 6.633333)")),
-("Aadouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
-("Aadoui", "pp", GeomFromText("POINT(34.450000 35.983333)")),
-("Aadouiye", "pp", GeomFromText("POINT(34.583333 36.183333)")),
-("Aadouss", "pp", GeomFromText("POINT(33.512500 35.601389)")),
-("Aadra", "pp", GeomFromText("POINT(33.616667 36.500000)")),
-("Aadzi", "pp", GeomFromText("POINT(38.100000 64.850000)"));
+("Aadaouane", "pp", GeomFromText("LINESTRING(32.816667 35.983333)")),
+("Aadassiye", "pp", GeomFromText("LINESTRING(35.816667 36.216667)")),
+("Aadbel", "pp", GeomFromText("LINESTRING(34.533333 36.100000)")),
+("Aadchit", "pp", GeomFromText("LINESTRING(33.347222 35.423611)")),
+("Aadchite", "pp", GeomFromText("LINESTRING(33.347222 35.423611)")),
+("Aadchit el Qoussair", "pp", GeomFromText("LINESTRING(33.283333 35.483333)")),
+("Aaddaye", "pp", GeomFromText("LINESTRING(36.716667 40.833333)")),
+("'Aadeissa", "pp", GeomFromText("LINESTRING(32.823889 35.698889)")),
+("Aaderup", "pp", GeomFromText("LINESTRING(55.216667 11.766667)")),
+("Qalaat Aades", "pp", GeomFromText("LINESTRING(33.503333 35.377500)")),
+("A ad'ino", "pp", GeomFromText("LINESTRING(54.812222 38.209167)")),
+("Aadi Noia", "pp", GeomFromText("LINESTRING(13.800000 39.833333)")),
+("Aad La Macta", "pp", GeomFromText("LINESTRING(35.779444 -0.129167)")),
+("Aadland", "pp", GeomFromText("LINESTRING(60.366667 5.483333)")),
+("Aadliye", "pp", GeomFromText("LINESTRING(33.366667 36.333333)")),
+("Aadloun", "pp", GeomFromText("LINESTRING(33.403889 35.273889)")),
+("Aadma", "pp", GeomFromText("LINESTRING(58.798333 22.663889)")),
+("Aadma Asundus", "pp", GeomFromText("LINESTRING(58.798333 22.663889)")),
+("Aadmoun", "pp", GeomFromText("LINESTRING(34.150000 35.650000)")),
+("Aadneram", "pp", GeomFromText("LINESTRING(59.016667 6.933333)")),
+("Aadneskaar", "pp", GeomFromText("LINESTRING(58.083333 6.983333)")),
+("Aadorf", "pp", GeomFromText("LINESTRING(47.483333 8.900000)")),
+("Aadorp", "pp", GeomFromText("LINESTRING(52.366667 6.633333)")),
+("Aadouane", "pp", GeomFromText("LINESTRING(32.816667 35.983333)")),
+("Aadoui", "pp", GeomFromText("LINESTRING(34.450000 35.983333)")),
+("Aadouiye", "pp", GeomFromText("LINESTRING(34.583333 36.183333)")),
+("Aadouss", "pp", GeomFromText("LINESTRING(33.512500 35.601389)")),
+("Aadra", "pp", GeomFromText("LINESTRING(33.616667 36.500000)")),
+("Aadzi", "pp", GeomFromText("LINESTRING(38.100000 64.850000)"));
ALTER TABLE t1 ENABLE KEYS;
INSERT INTO t1 (name, kind, line) VALUES ("austria", "pp", GeomFromText('LINESTRING(14.9906 48.9887,14.9946 48.9904,14.9947 48.9916)'));
drop table t1;
diff --git a/mysql-test/suite/maria/maria-gis-rtree-dynamic.test b/mysql-test/suite/maria/maria-gis-rtree-dynamic.test
index 166c88cab36..668d393d0b8 100644
--- a/mysql-test/suite/maria/maria-gis-rtree-dynamic.test
+++ b/mysql-test/suite/maria/maria-gis-rtree-dynamic.test
@@ -135,35 +135,35 @@ CREATE TABLE t1 (
ALTER TABLE t1 DISABLE KEYS;
INSERT INTO t1 (name, kind, line) VALUES
- ("Aadaouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
- ("Aadassiye", "pp", GeomFromText("POINT(35.816667 36.216667)")),
- ("Aadbel", "pp", GeomFromText("POINT(34.533333 36.100000)")),
- ("Aadchit", "pp", GeomFromText("POINT(33.347222 35.423611)")),
- ("Aadchite", "pp", GeomFromText("POINT(33.347222 35.423611)")),
- ("Aadchit el Qoussair", "pp", GeomFromText("POINT(33.283333 35.483333)")),
- ("Aaddaye", "pp", GeomFromText("POINT(36.716667 40.833333)")),
- ("'Aadeissa", "pp", GeomFromText("POINT(32.823889 35.698889)")),
- ("Aaderup", "pp", GeomFromText("POINT(55.216667 11.766667)")),
- ("Qalaat Aades", "pp", GeomFromText("POINT(33.503333 35.377500)")),
- ("A ad'ino", "pp", GeomFromText("POINT(54.812222 38.209167)")),
- ("Aadi Noia", "pp", GeomFromText("POINT(13.800000 39.833333)")),
- ("Aad La Macta", "pp", GeomFromText("POINT(35.779444 -0.129167)")),
- ("Aadland", "pp", GeomFromText("POINT(60.366667 5.483333)")),
- ("Aadliye", "pp", GeomFromText("POINT(33.366667 36.333333)")),
- ("Aadloun", "pp", GeomFromText("POINT(33.403889 35.273889)")),
- ("Aadma", "pp", GeomFromText("POINT(58.798333 22.663889)")),
- ("Aadma Asundus", "pp", GeomFromText("POINT(58.798333 22.663889)")),
- ("Aadmoun", "pp", GeomFromText("POINT(34.150000 35.650000)")),
- ("Aadneram", "pp", GeomFromText("POINT(59.016667 6.933333)")),
- ("Aadneskaar", "pp", GeomFromText("POINT(58.083333 6.983333)")),
- ("Aadorf", "pp", GeomFromText("POINT(47.483333 8.900000)")),
- ("Aadorp", "pp", GeomFromText("POINT(52.366667 6.633333)")),
- ("Aadouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
- ("Aadoui", "pp", GeomFromText("POINT(34.450000 35.983333)")),
- ("Aadouiye", "pp", GeomFromText("POINT(34.583333 36.183333)")),
- ("Aadouss", "pp", GeomFromText("POINT(33.512500 35.601389)")),
- ("Aadra", "pp", GeomFromText("POINT(33.616667 36.500000)")),
- ("Aadzi", "pp", GeomFromText("POINT(38.100000 64.850000)"));
+ ("Aadaouane", "pp", GeomFromText("LINESTRING(32.816667 35.983333)")),
+ ("Aadassiye", "pp", GeomFromText("LINESTRING(35.816667 36.216667)")),
+ ("Aadbel", "pp", GeomFromText("LINESTRING(34.533333 36.100000)")),
+ ("Aadchit", "pp", GeomFromText("LINESTRING(33.347222 35.423611)")),
+ ("Aadchite", "pp", GeomFromText("LINESTRING(33.347222 35.423611)")),
+ ("Aadchit el Qoussair", "pp", GeomFromText("LINESTRING(33.283333 35.483333)")),
+ ("Aaddaye", "pp", GeomFromText("LINESTRING(36.716667 40.833333)")),
+ ("'Aadeissa", "pp", GeomFromText("LINESTRING(32.823889 35.698889)")),
+ ("Aaderup", "pp", GeomFromText("LINESTRING(55.216667 11.766667)")),
+ ("Qalaat Aades", "pp", GeomFromText("LINESTRING(33.503333 35.377500)")),
+ ("A ad'ino", "pp", GeomFromText("LINESTRING(54.812222 38.209167)")),
+ ("Aadi Noia", "pp", GeomFromText("LINESTRING(13.800000 39.833333)")),
+ ("Aad La Macta", "pp", GeomFromText("LINESTRING(35.779444 -0.129167)")),
+ ("Aadland", "pp", GeomFromText("LINESTRING(60.366667 5.483333)")),
+ ("Aadliye", "pp", GeomFromText("LINESTRING(33.366667 36.333333)")),
+ ("Aadloun", "pp", GeomFromText("LINESTRING(33.403889 35.273889)")),
+ ("Aadma", "pp", GeomFromText("LINESTRING(58.798333 22.663889)")),
+ ("Aadma Asundus", "pp", GeomFromText("LINESTRING(58.798333 22.663889)")),
+ ("Aadmoun", "pp", GeomFromText("LINESTRING(34.150000 35.650000)")),
+ ("Aadneram", "pp", GeomFromText("LINESTRING(59.016667 6.933333)")),
+ ("Aadneskaar", "pp", GeomFromText("LINESTRING(58.083333 6.983333)")),
+ ("Aadorf", "pp", GeomFromText("LINESTRING(47.483333 8.900000)")),
+ ("Aadorp", "pp", GeomFromText("LINESTRING(52.366667 6.633333)")),
+ ("Aadouane", "pp", GeomFromText("LINESTRING(32.816667 35.983333)")),
+ ("Aadoui", "pp", GeomFromText("LINESTRING(34.450000 35.983333)")),
+ ("Aadouiye", "pp", GeomFromText("LINESTRING(34.583333 36.183333)")),
+ ("Aadouss", "pp", GeomFromText("LINESTRING(33.512500 35.601389)")),
+ ("Aadra", "pp", GeomFromText("LINESTRING(33.616667 36.500000)")),
+ ("Aadzi", "pp", GeomFromText("LINESTRING(38.100000 64.850000)"));
ALTER TABLE t1 ENABLE KEYS;
INSERT INTO t1 (name, kind, line) VALUES ("austria", "pp", GeomFromText('LINESTRING(14.9906 48.9887,14.9946 48.9904,14.9947 48.9916)'));
diff --git a/mysql-test/suite/maria/maria-gis-rtree-trans.result b/mysql-test/suite/maria/maria-gis-rtree-trans.result
index c4e773c7e0a..dba56204172 100644
--- a/mysql-test/suite/maria/maria-gis-rtree-trans.result
+++ b/mysql-test/suite/maria/maria-gis-rtree-trans.result
@@ -766,35 +766,35 @@ SPATIAL KEY (line)
) transactional=1 row_format=page;
ALTER TABLE t1 DISABLE KEYS;
INSERT INTO t1 (name, kind, line) VALUES
-("Aadaouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
-("Aadassiye", "pp", GeomFromText("POINT(35.816667 36.216667)")),
-("Aadbel", "pp", GeomFromText("POINT(34.533333 36.100000)")),
-("Aadchit", "pp", GeomFromText("POINT(33.347222 35.423611)")),
-("Aadchite", "pp", GeomFromText("POINT(33.347222 35.423611)")),
-("Aadchit el Qoussair", "pp", GeomFromText("POINT(33.283333 35.483333)")),
-("Aaddaye", "pp", GeomFromText("POINT(36.716667 40.833333)")),
-("'Aadeissa", "pp", GeomFromText("POINT(32.823889 35.698889)")),
-("Aaderup", "pp", GeomFromText("POINT(55.216667 11.766667)")),
-("Qalaat Aades", "pp", GeomFromText("POINT(33.503333 35.377500)")),
-("A ad'ino", "pp", GeomFromText("POINT(54.812222 38.209167)")),
-("Aadi Noia", "pp", GeomFromText("POINT(13.800000 39.833333)")),
-("Aad La Macta", "pp", GeomFromText("POINT(35.779444 -0.129167)")),
-("Aadland", "pp", GeomFromText("POINT(60.366667 5.483333)")),
-("Aadliye", "pp", GeomFromText("POINT(33.366667 36.333333)")),
-("Aadloun", "pp", GeomFromText("POINT(33.403889 35.273889)")),
-("Aadma", "pp", GeomFromText("POINT(58.798333 22.663889)")),
-("Aadma Asundus", "pp", GeomFromText("POINT(58.798333 22.663889)")),
-("Aadmoun", "pp", GeomFromText("POINT(34.150000 35.650000)")),
-("Aadneram", "pp", GeomFromText("POINT(59.016667 6.933333)")),
-("Aadneskaar", "pp", GeomFromText("POINT(58.083333 6.983333)")),
-("Aadorf", "pp", GeomFromText("POINT(47.483333 8.900000)")),
-("Aadorp", "pp", GeomFromText("POINT(52.366667 6.633333)")),
-("Aadouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
-("Aadoui", "pp", GeomFromText("POINT(34.450000 35.983333)")),
-("Aadouiye", "pp", GeomFromText("POINT(34.583333 36.183333)")),
-("Aadouss", "pp", GeomFromText("POINT(33.512500 35.601389)")),
-("Aadra", "pp", GeomFromText("POINT(33.616667 36.500000)")),
-("Aadzi", "pp", GeomFromText("POINT(38.100000 64.850000)"));
+("Aadaouane", "pp", GeomFromText("LINESTRING(32.816667 35.983333)")),
+("Aadassiye", "pp", GeomFromText("LINESTRING(35.816667 36.216667)")),
+("Aadbel", "pp", GeomFromText("LINESTRING(34.533333 36.100000)")),
+("Aadchit", "pp", GeomFromText("LINESTRING(33.347222 35.423611)")),
+("Aadchite", "pp", GeomFromText("LINESTRING(33.347222 35.423611)")),
+("Aadchit el Qoussair", "pp", GeomFromText("LINESTRING(33.283333 35.483333)")),
+("Aaddaye", "pp", GeomFromText("LINESTRING(36.716667 40.833333)")),
+("'Aadeissa", "pp", GeomFromText("LINESTRING(32.823889 35.698889)")),
+("Aaderup", "pp", GeomFromText("LINESTRING(55.216667 11.766667)")),
+("Qalaat Aades", "pp", GeomFromText("LINESTRING(33.503333 35.377500)")),
+("A ad'ino", "pp", GeomFromText("LINESTRING(54.812222 38.209167)")),
+("Aadi Noia", "pp", GeomFromText("LINESTRING(13.800000 39.833333)")),
+("Aad La Macta", "pp", GeomFromText("LINESTRING(35.779444 -0.129167)")),
+("Aadland", "pp", GeomFromText("LINESTRING(60.366667 5.483333)")),
+("Aadliye", "pp", GeomFromText("LINESTRING(33.366667 36.333333)")),
+("Aadloun", "pp", GeomFromText("LINESTRING(33.403889 35.273889)")),
+("Aadma", "pp", GeomFromText("LINESTRING(58.798333 22.663889)")),
+("Aadma Asundus", "pp", GeomFromText("LINESTRING(58.798333 22.663889)")),
+("Aadmoun", "pp", GeomFromText("LINESTRING(34.150000 35.650000)")),
+("Aadneram", "pp", GeomFromText("LINESTRING(59.016667 6.933333)")),
+("Aadneskaar", "pp", GeomFromText("LINESTRING(58.083333 6.983333)")),
+("Aadorf", "pp", GeomFromText("LINESTRING(47.483333 8.900000)")),
+("Aadorp", "pp", GeomFromText("LINESTRING(52.366667 6.633333)")),
+("Aadouane", "pp", GeomFromText("LINESTRING(32.816667 35.983333)")),
+("Aadoui", "pp", GeomFromText("LINESTRING(34.450000 35.983333)")),
+("Aadouiye", "pp", GeomFromText("LINESTRING(34.583333 36.183333)")),
+("Aadouss", "pp", GeomFromText("LINESTRING(33.512500 35.601389)")),
+("Aadra", "pp", GeomFromText("LINESTRING(33.616667 36.500000)")),
+("Aadzi", "pp", GeomFromText("LINESTRING(38.100000 64.850000)"));
ALTER TABLE t1 ENABLE KEYS;
INSERT INTO t1 (name, kind, line) VALUES ("austria", "pp", GeomFromText('LINESTRING(14.9906 48.9887,14.9946 48.9904,14.9947 48.9916)'));
drop table t1;
diff --git a/mysql-test/suite/maria/maria-gis-rtree-trans.test b/mysql-test/suite/maria/maria-gis-rtree-trans.test
index ec1573c3e29..73f129d8df9 100644
--- a/mysql-test/suite/maria/maria-gis-rtree-trans.test
+++ b/mysql-test/suite/maria/maria-gis-rtree-trans.test
@@ -138,35 +138,35 @@ CREATE TABLE t1 (
ALTER TABLE t1 DISABLE KEYS;
INSERT INTO t1 (name, kind, line) VALUES
- ("Aadaouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
- ("Aadassiye", "pp", GeomFromText("POINT(35.816667 36.216667)")),
- ("Aadbel", "pp", GeomFromText("POINT(34.533333 36.100000)")),
- ("Aadchit", "pp", GeomFromText("POINT(33.347222 35.423611)")),
- ("Aadchite", "pp", GeomFromText("POINT(33.347222 35.423611)")),
- ("Aadchit el Qoussair", "pp", GeomFromText("POINT(33.283333 35.483333)")),
- ("Aaddaye", "pp", GeomFromText("POINT(36.716667 40.833333)")),
- ("'Aadeissa", "pp", GeomFromText("POINT(32.823889 35.698889)")),
- ("Aaderup", "pp", GeomFromText("POINT(55.216667 11.766667)")),
- ("Qalaat Aades", "pp", GeomFromText("POINT(33.503333 35.377500)")),
- ("A ad'ino", "pp", GeomFromText("POINT(54.812222 38.209167)")),
- ("Aadi Noia", "pp", GeomFromText("POINT(13.800000 39.833333)")),
- ("Aad La Macta", "pp", GeomFromText("POINT(35.779444 -0.129167)")),
- ("Aadland", "pp", GeomFromText("POINT(60.366667 5.483333)")),
- ("Aadliye", "pp", GeomFromText("POINT(33.366667 36.333333)")),
- ("Aadloun", "pp", GeomFromText("POINT(33.403889 35.273889)")),
- ("Aadma", "pp", GeomFromText("POINT(58.798333 22.663889)")),
- ("Aadma Asundus", "pp", GeomFromText("POINT(58.798333 22.663889)")),
- ("Aadmoun", "pp", GeomFromText("POINT(34.150000 35.650000)")),
- ("Aadneram", "pp", GeomFromText("POINT(59.016667 6.933333)")),
- ("Aadneskaar", "pp", GeomFromText("POINT(58.083333 6.983333)")),
- ("Aadorf", "pp", GeomFromText("POINT(47.483333 8.900000)")),
- ("Aadorp", "pp", GeomFromText("POINT(52.366667 6.633333)")),
- ("Aadouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
- ("Aadoui", "pp", GeomFromText("POINT(34.450000 35.983333)")),
- ("Aadouiye", "pp", GeomFromText("POINT(34.583333 36.183333)")),
- ("Aadouss", "pp", GeomFromText("POINT(33.512500 35.601389)")),
- ("Aadra", "pp", GeomFromText("POINT(33.616667 36.500000)")),
- ("Aadzi", "pp", GeomFromText("POINT(38.100000 64.850000)"));
+ ("Aadaouane", "pp", GeomFromText("LINESTRING(32.816667 35.983333)")),
+ ("Aadassiye", "pp", GeomFromText("LINESTRING(35.816667 36.216667)")),
+ ("Aadbel", "pp", GeomFromText("LINESTRING(34.533333 36.100000)")),
+ ("Aadchit", "pp", GeomFromText("LINESTRING(33.347222 35.423611)")),
+ ("Aadchite", "pp", GeomFromText("LINESTRING(33.347222 35.423611)")),
+ ("Aadchit el Qoussair", "pp", GeomFromText("LINESTRING(33.283333 35.483333)")),
+ ("Aaddaye", "pp", GeomFromText("LINESTRING(36.716667 40.833333)")),
+ ("'Aadeissa", "pp", GeomFromText("LINESTRING(32.823889 35.698889)")),
+ ("Aaderup", "pp", GeomFromText("LINESTRING(55.216667 11.766667)")),
+ ("Qalaat Aades", "pp", GeomFromText("LINESTRING(33.503333 35.377500)")),
+ ("A ad'ino", "pp", GeomFromText("LINESTRING(54.812222 38.209167)")),
+ ("Aadi Noia", "pp", GeomFromText("LINESTRING(13.800000 39.833333)")),
+ ("Aad La Macta", "pp", GeomFromText("LINESTRING(35.779444 -0.129167)")),
+ ("Aadland", "pp", GeomFromText("LINESTRING(60.366667 5.483333)")),
+ ("Aadliye", "pp", GeomFromText("LINESTRING(33.366667 36.333333)")),
+ ("Aadloun", "pp", GeomFromText("LINESTRING(33.403889 35.273889)")),
+ ("Aadma", "pp", GeomFromText("LINESTRING(58.798333 22.663889)")),
+ ("Aadma Asundus", "pp", GeomFromText("LINESTRING(58.798333 22.663889)")),
+ ("Aadmoun", "pp", GeomFromText("LINESTRING(34.150000 35.650000)")),
+ ("Aadneram", "pp", GeomFromText("LINESTRING(59.016667 6.933333)")),
+ ("Aadneskaar", "pp", GeomFromText("LINESTRING(58.083333 6.983333)")),
+ ("Aadorf", "pp", GeomFromText("LINESTRING(47.483333 8.900000)")),
+ ("Aadorp", "pp", GeomFromText("LINESTRING(52.366667 6.633333)")),
+ ("Aadouane", "pp", GeomFromText("LINESTRING(32.816667 35.983333)")),
+ ("Aadoui", "pp", GeomFromText("LINESTRING(34.450000 35.983333)")),
+ ("Aadouiye", "pp", GeomFromText("LINESTRING(34.583333 36.183333)")),
+ ("Aadouss", "pp", GeomFromText("LINESTRING(33.512500 35.601389)")),
+ ("Aadra", "pp", GeomFromText("LINESTRING(33.616667 36.500000)")),
+ ("Aadzi", "pp", GeomFromText("LINESTRING(38.100000 64.850000)"));
ALTER TABLE t1 ENABLE KEYS;
INSERT INTO t1 (name, kind, line) VALUES ("austria", "pp", GeomFromText('LINESTRING(14.9906 48.9887,14.9946 48.9904,14.9947 48.9916)'));
diff --git a/mysql-test/suite/maria/maria-gis-rtree.result b/mysql-test/suite/maria/maria-gis-rtree.result
index 430f240d83e..1a7b08169dc 100644
--- a/mysql-test/suite/maria/maria-gis-rtree.result
+++ b/mysql-test/suite/maria/maria-gis-rtree.result
@@ -766,35 +766,35 @@ SPATIAL KEY (line)
) transactional=0 row_format=page;
ALTER TABLE t1 DISABLE KEYS;
INSERT INTO t1 (name, kind, line) VALUES
-("Aadaouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
-("Aadassiye", "pp", GeomFromText("POINT(35.816667 36.216667)")),
-("Aadbel", "pp", GeomFromText("POINT(34.533333 36.100000)")),
-("Aadchit", "pp", GeomFromText("POINT(33.347222 35.423611)")),
-("Aadchite", "pp", GeomFromText("POINT(33.347222 35.423611)")),
-("Aadchit el Qoussair", "pp", GeomFromText("POINT(33.283333 35.483333)")),
-("Aaddaye", "pp", GeomFromText("POINT(36.716667 40.833333)")),
-("'Aadeissa", "pp", GeomFromText("POINT(32.823889 35.698889)")),
-("Aaderup", "pp", GeomFromText("POINT(55.216667 11.766667)")),
-("Qalaat Aades", "pp", GeomFromText("POINT(33.503333 35.377500)")),
-("A ad'ino", "pp", GeomFromText("POINT(54.812222 38.209167)")),
-("Aadi Noia", "pp", GeomFromText("POINT(13.800000 39.833333)")),
-("Aad La Macta", "pp", GeomFromText("POINT(35.779444 -0.129167)")),
-("Aadland", "pp", GeomFromText("POINT(60.366667 5.483333)")),
-("Aadliye", "pp", GeomFromText("POINT(33.366667 36.333333)")),
-("Aadloun", "pp", GeomFromText("POINT(33.403889 35.273889)")),
-("Aadma", "pp", GeomFromText("POINT(58.798333 22.663889)")),
-("Aadma Asundus", "pp", GeomFromText("POINT(58.798333 22.663889)")),
-("Aadmoun", "pp", GeomFromText("POINT(34.150000 35.650000)")),
-("Aadneram", "pp", GeomFromText("POINT(59.016667 6.933333)")),
-("Aadneskaar", "pp", GeomFromText("POINT(58.083333 6.983333)")),
-("Aadorf", "pp", GeomFromText("POINT(47.483333 8.900000)")),
-("Aadorp", "pp", GeomFromText("POINT(52.366667 6.633333)")),
-("Aadouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
-("Aadoui", "pp", GeomFromText("POINT(34.450000 35.983333)")),
-("Aadouiye", "pp", GeomFromText("POINT(34.583333 36.183333)")),
-("Aadouss", "pp", GeomFromText("POINT(33.512500 35.601389)")),
-("Aadra", "pp", GeomFromText("POINT(33.616667 36.500000)")),
-("Aadzi", "pp", GeomFromText("POINT(38.100000 64.850000)"));
+("Aadaouane", "pp", GeomFromText("LINESTRING(32.816667 35.983333)")),
+("Aadassiye", "pp", GeomFromText("LINESTRING(35.816667 36.216667)")),
+("Aadbel", "pp", GeomFromText("LINESTRING(34.533333 36.100000)")),
+("Aadchit", "pp", GeomFromText("LINESTRING(33.347222 35.423611)")),
+("Aadchite", "pp", GeomFromText("LINESTRING(33.347222 35.423611)")),
+("Aadchit el Qoussair", "pp", GeomFromText("LINESTRING(33.283333 35.483333)")),
+("Aaddaye", "pp", GeomFromText("LINESTRING(36.716667 40.833333)")),
+("'Aadeissa", "pp", GeomFromText("LINESTRING(32.823889 35.698889)")),
+("Aaderup", "pp", GeomFromText("LINESTRING(55.216667 11.766667)")),
+("Qalaat Aades", "pp", GeomFromText("LINESTRING(33.503333 35.377500)")),
+("A ad'ino", "pp", GeomFromText("LINESTRING(54.812222 38.209167)")),
+("Aadi Noia", "pp", GeomFromText("LINESTRING(13.800000 39.833333)")),
+("Aad La Macta", "pp", GeomFromText("LINESTRING(35.779444 -0.129167)")),
+("Aadland", "pp", GeomFromText("LINESTRING(60.366667 5.483333)")),
+("Aadliye", "pp", GeomFromText("LINESTRING(33.366667 36.333333)")),
+("Aadloun", "pp", GeomFromText("LINESTRING(33.403889 35.273889)")),
+("Aadma", "pp", GeomFromText("LINESTRING(58.798333 22.663889)")),
+("Aadma Asundus", "pp", GeomFromText("LINESTRING(58.798333 22.663889)")),
+("Aadmoun", "pp", GeomFromText("LINESTRING(34.150000 35.650000)")),
+("Aadneram", "pp", GeomFromText("LINESTRING(59.016667 6.933333)")),
+("Aadneskaar", "pp", GeomFromText("LINESTRING(58.083333 6.983333)")),
+("Aadorf", "pp", GeomFromText("LINESTRING(47.483333 8.900000)")),
+("Aadorp", "pp", GeomFromText("LINESTRING(52.366667 6.633333)")),
+("Aadouane", "pp", GeomFromText("LINESTRING(32.816667 35.983333)")),
+("Aadoui", "pp", GeomFromText("LINESTRING(34.450000 35.983333)")),
+("Aadouiye", "pp", GeomFromText("LINESTRING(34.583333 36.183333)")),
+("Aadouss", "pp", GeomFromText("LINESTRING(33.512500 35.601389)")),
+("Aadra", "pp", GeomFromText("LINESTRING(33.616667 36.500000)")),
+("Aadzi", "pp", GeomFromText("LINESTRING(38.100000 64.850000)"));
ALTER TABLE t1 ENABLE KEYS;
INSERT INTO t1 (name, kind, line) VALUES ("austria", "pp", GeomFromText('LINESTRING(14.9906 48.9887,14.9946 48.9904,14.9947 48.9916)'));
drop table t1;
diff --git a/mysql-test/suite/maria/maria-gis-rtree.test b/mysql-test/suite/maria/maria-gis-rtree.test
index beffbfc99fe..a3845adb7b9 100644
--- a/mysql-test/suite/maria/maria-gis-rtree.test
+++ b/mysql-test/suite/maria/maria-gis-rtree.test
@@ -135,35 +135,35 @@ CREATE TABLE t1 (
ALTER TABLE t1 DISABLE KEYS;
INSERT INTO t1 (name, kind, line) VALUES
- ("Aadaouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
- ("Aadassiye", "pp", GeomFromText("POINT(35.816667 36.216667)")),
- ("Aadbel", "pp", GeomFromText("POINT(34.533333 36.100000)")),
- ("Aadchit", "pp", GeomFromText("POINT(33.347222 35.423611)")),
- ("Aadchite", "pp", GeomFromText("POINT(33.347222 35.423611)")),
- ("Aadchit el Qoussair", "pp", GeomFromText("POINT(33.283333 35.483333)")),
- ("Aaddaye", "pp", GeomFromText("POINT(36.716667 40.833333)")),
- ("'Aadeissa", "pp", GeomFromText("POINT(32.823889 35.698889)")),
- ("Aaderup", "pp", GeomFromText("POINT(55.216667 11.766667)")),
- ("Qalaat Aades", "pp", GeomFromText("POINT(33.503333 35.377500)")),
- ("A ad'ino", "pp", GeomFromText("POINT(54.812222 38.209167)")),
- ("Aadi Noia", "pp", GeomFromText("POINT(13.800000 39.833333)")),
- ("Aad La Macta", "pp", GeomFromText("POINT(35.779444 -0.129167)")),
- ("Aadland", "pp", GeomFromText("POINT(60.366667 5.483333)")),
- ("Aadliye", "pp", GeomFromText("POINT(33.366667 36.333333)")),
- ("Aadloun", "pp", GeomFromText("POINT(33.403889 35.273889)")),
- ("Aadma", "pp", GeomFromText("POINT(58.798333 22.663889)")),
- ("Aadma Asundus", "pp", GeomFromText("POINT(58.798333 22.663889)")),
- ("Aadmoun", "pp", GeomFromText("POINT(34.150000 35.650000)")),
- ("Aadneram", "pp", GeomFromText("POINT(59.016667 6.933333)")),
- ("Aadneskaar", "pp", GeomFromText("POINT(58.083333 6.983333)")),
- ("Aadorf", "pp", GeomFromText("POINT(47.483333 8.900000)")),
- ("Aadorp", "pp", GeomFromText("POINT(52.366667 6.633333)")),
- ("Aadouane", "pp", GeomFromText("POINT(32.816667 35.983333)")),
- ("Aadoui", "pp", GeomFromText("POINT(34.450000 35.983333)")),
- ("Aadouiye", "pp", GeomFromText("POINT(34.583333 36.183333)")),
- ("Aadouss", "pp", GeomFromText("POINT(33.512500 35.601389)")),
- ("Aadra", "pp", GeomFromText("POINT(33.616667 36.500000)")),
- ("Aadzi", "pp", GeomFromText("POINT(38.100000 64.850000)"));
+ ("Aadaouane", "pp", GeomFromText("LINESTRING(32.816667 35.983333)")),
+ ("Aadassiye", "pp", GeomFromText("LINESTRING(35.816667 36.216667)")),
+ ("Aadbel", "pp", GeomFromText("LINESTRING(34.533333 36.100000)")),
+ ("Aadchit", "pp", GeomFromText("LINESTRING(33.347222 35.423611)")),
+ ("Aadchite", "pp", GeomFromText("LINESTRING(33.347222 35.423611)")),
+ ("Aadchit el Qoussair", "pp", GeomFromText("LINESTRING(33.283333 35.483333)")),
+ ("Aaddaye", "pp", GeomFromText("LINESTRING(36.716667 40.833333)")),
+ ("'Aadeissa", "pp", GeomFromText("LINESTRING(32.823889 35.698889)")),
+ ("Aaderup", "pp", GeomFromText("LINESTRING(55.216667 11.766667)")),
+ ("Qalaat Aades", "pp", GeomFromText("LINESTRING(33.503333 35.377500)")),
+ ("A ad'ino", "pp", GeomFromText("LINESTRING(54.812222 38.209167)")),
+ ("Aadi Noia", "pp", GeomFromText("LINESTRING(13.800000 39.833333)")),
+ ("Aad La Macta", "pp", GeomFromText("LINESTRING(35.779444 -0.129167)")),
+ ("Aadland", "pp", GeomFromText("LINESTRING(60.366667 5.483333)")),
+ ("Aadliye", "pp", GeomFromText("LINESTRING(33.366667 36.333333)")),
+ ("Aadloun", "pp", GeomFromText("LINESTRING(33.403889 35.273889)")),
+ ("Aadma", "pp", GeomFromText("LINESTRING(58.798333 22.663889)")),
+ ("Aadma Asundus", "pp", GeomFromText("LINESTRING(58.798333 22.663889)")),
+ ("Aadmoun", "pp", GeomFromText("LINESTRING(34.150000 35.650000)")),
+ ("Aadneram", "pp", GeomFromText("LINESTRING(59.016667 6.933333)")),
+ ("Aadneskaar", "pp", GeomFromText("LINESTRING(58.083333 6.983333)")),
+ ("Aadorf", "pp", GeomFromText("LINESTRING(47.483333 8.900000)")),
+ ("Aadorp", "pp", GeomFromText("LINESTRING(52.366667 6.633333)")),
+ ("Aadouane", "pp", GeomFromText("LINESTRING(32.816667 35.983333)")),
+ ("Aadoui", "pp", GeomFromText("LINESTRING(34.450000 35.983333)")),
+ ("Aadouiye", "pp", GeomFromText("LINESTRING(34.583333 36.183333)")),
+ ("Aadouss", "pp", GeomFromText("LINESTRING(33.512500 35.601389)")),
+ ("Aadra", "pp", GeomFromText("LINESTRING(33.616667 36.500000)")),
+ ("Aadzi", "pp", GeomFromText("LINESTRING(38.100000 64.850000)"));
ALTER TABLE t1 ENABLE KEYS;
INSERT INTO t1 (name, kind, line) VALUES ("austria", "pp", GeomFromText('LINESTRING(14.9906 48.9887,14.9946 48.9904,14.9947 48.9916)'));
diff --git a/mysql-test/suite/maria/maria-recovery-rtree-ft.result b/mysql-test/suite/maria/maria-recovery-rtree-ft.result
index 030421ae06a..5c6c791d8f6 100644
--- a/mysql-test/suite/maria/maria-recovery-rtree-ft.result
+++ b/mysql-test/suite/maria/maria-recovery-rtree-ft.result
@@ -4,7 +4,7 @@ create database mysqltest;
use mysqltest;
* shut down mysqld, removed logs, restarted it
CREATE TABLE t1 (
-line LINESTRING NOT NULL,
+line POINT NOT NULL,
kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po',
name VARCHAR(32)
,SPATIAL key (line)
diff --git a/mysql-test/suite/maria/maria-recovery-rtree-ft.test b/mysql-test/suite/maria/maria-recovery-rtree-ft.test
index 11050ad676a..7112c00e5b7 100644
--- a/mysql-test/suite/maria/maria-recovery-rtree-ft.test
+++ b/mysql-test/suite/maria/maria-recovery-rtree-ft.test
@@ -31,7 +31,7 @@ use mysqltest;
let $mms_tables=2;
CREATE TABLE t1 (
- line LINESTRING NOT NULL,
+ line POINT NOT NULL,
kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po',
name VARCHAR(32)
,SPATIAL key (line)
diff --git a/mysql-test/suite/maria/maria.result b/mysql-test/suite/maria/maria.result
index 888c1c10c5e..0de42a9e7fe 100644
--- a/mysql-test/suite/maria/maria.result
+++ b/mysql-test/suite/maria/maria.result
@@ -2167,19 +2167,19 @@ t1 CREATE TABLE `t1` (
) ENGINE=Aria DEFAULT CHARSET=latin1 PAGE_CHECKSUM=0 TRANSACTIONAL=1
drop table t1;
CREATE TABLE t1 (line LINESTRING NOT NULL) engine=aria;
-INSERT INTO t1 VALUES (GeomFromText("POINT(0 0)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(0 0)"));
checksum table t1;
Table Checksum
-test.t1 326284887
+test.t1 310616673
CREATE TABLE t2 (line LINESTRING NOT NULL) engine=aria;
-INSERT INTO t2 VALUES (GeomFromText("POINT(0 0)"));
+INSERT INTO t2 VALUES (GeomFromText("LINESTRING(0 0)"));
checksum table t2;
Table Checksum
-test.t2 326284887
+test.t2 310616673
CREATE TABLE t3 select * from t1;
checksum table t3;
Table Checksum
-test.t3 326284887
+test.t3 310616673
drop table t1,t2,t3;
End of 5.1 tests
create table t2(a varchar(255),key(a))engine=aria row_format=dynamic transactional=0;
diff --git a/mysql-test/suite/maria/maria.test b/mysql-test/suite/maria/maria.test
index 6ebcf08d952..3fa7d755fe4 100644
--- a/mysql-test/suite/maria/maria.test
+++ b/mysql-test/suite/maria/maria.test
@@ -1437,10 +1437,10 @@ drop table t1;
#
CREATE TABLE t1 (line LINESTRING NOT NULL) engine=aria;
-INSERT INTO t1 VALUES (GeomFromText("POINT(0 0)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(0 0)"));
checksum table t1;
CREATE TABLE t2 (line LINESTRING NOT NULL) engine=aria;
-INSERT INTO t2 VALUES (GeomFromText("POINT(0 0)"));
+INSERT INTO t2 VALUES (GeomFromText("LINESTRING(0 0)"));
checksum table t2;
CREATE TABLE t3 select * from t1;
checksum table t3;
diff --git a/mysql-test/suite/parts/r/partition_alter4_innodb.result b/mysql-test/suite/parts/r/partition_alter4_innodb.result
index 5d3143e35bb..b0f340664b7 100644
--- a/mysql-test/suite/parts/r/partition_alter4_innodb.result
+++ b/mysql-test/suite/parts/r/partition_alter4_innodb.result
@@ -37566,7 +37566,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -38026,7 +38026,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -38497,7 +38497,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -38969,7 +38969,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -39435,7 +39435,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -39907,7 +39907,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -40384,7 +40384,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -40859,7 +40859,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -41324,7 +41324,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -41784,7 +41784,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -42255,7 +42255,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -42727,7 +42727,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -43193,7 +43193,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -43665,7 +43665,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -44142,7 +44142,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -44617,7 +44617,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -52582,7 +52582,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -53042,7 +53042,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -53513,7 +53513,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -53985,7 +53985,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -54451,7 +54451,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -54923,7 +54923,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -55400,7 +55400,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
@@ -55875,7 +55875,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1;
ALTER TABLE t1 OPTIMIZE PARTITION ALL;
Table Op Msg_type Msg_text
-test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.
test.t1 optimize status OK
INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig)
SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template
diff --git a/mysql-test/suite/perfschema/r/start_server_no_waits_history.result b/mysql-test/suite/perfschema/r/start_server_no_waits_history.result
new file mode 100644
index 00000000000..e89b15e524a
--- /dev/null
+++ b/mysql-test/suite/perfschema/r/start_server_no_waits_history.result
@@ -0,0 +1,63 @@
+show databases;
+Database
+information_schema
+mtr
+mysql
+performance_schema
+test
+select count(*) from performance_schema.performance_timers;
+count(*)
+5
+select count(*) from performance_schema.setup_consumers;
+count(*)
+8
+select count(*) > 0 from performance_schema.setup_instruments;
+count(*) > 0
+1
+select count(*) from performance_schema.setup_timers;
+count(*)
+1
+select * from performance_schema.cond_instances;
+select * from performance_schema.events_waits_current;
+select * from performance_schema.events_waits_history;
+select * from performance_schema.events_waits_history_long;
+select * from performance_schema.events_waits_summary_by_instance;
+select * from performance_schema.events_waits_summary_by_thread_by_event_name;
+select * from performance_schema.events_waits_summary_global_by_event_name;
+select * from performance_schema.file_instances;
+select * from performance_schema.file_summary_by_event_name;
+select * from performance_schema.file_summary_by_instance;
+select * from performance_schema.mutex_instances;
+select * from performance_schema.performance_timers;
+select * from performance_schema.rwlock_instances;
+select * from performance_schema.setup_consumers;
+select * from performance_schema.setup_instruments;
+select * from performance_schema.setup_timers;
+select * from performance_schema.threads;
+show variables like "performance_schema%";
+Variable_name Value
+performance_schema ON
+performance_schema_events_waits_history_long_size 10000
+performance_schema_events_waits_history_size 0
+performance_schema_max_cond_classes 80
+performance_schema_max_cond_instances 1000
+performance_schema_max_file_classes 50
+performance_schema_max_file_handles 32768
+performance_schema_max_file_instances 10000
+performance_schema_max_mutex_classes 200
+performance_schema_max_mutex_instances 10000
+performance_schema_max_rwlock_classes 30
+performance_schema_max_rwlock_instances 10000
+performance_schema_max_table_handles 1000
+performance_schema_max_table_instances 500
+performance_schema_max_thread_classes 50
+performance_schema_max_thread_instances 1000
+show engine PERFORMANCE_SCHEMA status;
+show status like "performance_schema%";
+show variables like "performance_schema_events_waits_history_size";
+Variable_name Value
+performance_schema_events_waits_history_size 0
+select count(*) from performance_schema.events_waits_history;
+count(*)
+0
+truncate table performance_schema.events_waits_history;
diff --git a/mysql-test/suite/perfschema/r/start_server_no_waits_history_long.result b/mysql-test/suite/perfschema/r/start_server_no_waits_history_long.result
new file mode 100644
index 00000000000..98172539625
--- /dev/null
+++ b/mysql-test/suite/perfschema/r/start_server_no_waits_history_long.result
@@ -0,0 +1,63 @@
+show databases;
+Database
+information_schema
+mtr
+mysql
+performance_schema
+test
+select count(*) from performance_schema.performance_timers;
+count(*)
+5
+select count(*) from performance_schema.setup_consumers;
+count(*)
+8
+select count(*) > 0 from performance_schema.setup_instruments;
+count(*) > 0
+1
+select count(*) from performance_schema.setup_timers;
+count(*)
+1
+select * from performance_schema.cond_instances;
+select * from performance_schema.events_waits_current;
+select * from performance_schema.events_waits_history;
+select * from performance_schema.events_waits_history_long;
+select * from performance_schema.events_waits_summary_by_instance;
+select * from performance_schema.events_waits_summary_by_thread_by_event_name;
+select * from performance_schema.events_waits_summary_global_by_event_name;
+select * from performance_schema.file_instances;
+select * from performance_schema.file_summary_by_event_name;
+select * from performance_schema.file_summary_by_instance;
+select * from performance_schema.mutex_instances;
+select * from performance_schema.performance_timers;
+select * from performance_schema.rwlock_instances;
+select * from performance_schema.setup_consumers;
+select * from performance_schema.setup_instruments;
+select * from performance_schema.setup_timers;
+select * from performance_schema.threads;
+show variables like "performance_schema%";
+Variable_name Value
+performance_schema ON
+performance_schema_events_waits_history_long_size 0
+performance_schema_events_waits_history_size 10
+performance_schema_max_cond_classes 80
+performance_schema_max_cond_instances 1000
+performance_schema_max_file_classes 50
+performance_schema_max_file_handles 32768
+performance_schema_max_file_instances 10000
+performance_schema_max_mutex_classes 200
+performance_schema_max_mutex_instances 10000
+performance_schema_max_rwlock_classes 30
+performance_schema_max_rwlock_instances 10000
+performance_schema_max_table_handles 1000
+performance_schema_max_table_instances 500
+performance_schema_max_thread_classes 50
+performance_schema_max_thread_instances 1000
+show engine PERFORMANCE_SCHEMA status;
+show status like "performance_schema%";
+show variables like "performance_schema_events_waits_history_long_size";
+Variable_name Value
+performance_schema_events_waits_history_long_size 0
+select count(*) from performance_schema.events_waits_history_long;
+count(*)
+0
+truncate table performance_schema.events_waits_history_long;
diff --git a/mysql-test/suite/perfschema/r/start_server_nothing.result b/mysql-test/suite/perfschema/r/start_server_nothing.result
new file mode 100644
index 00000000000..0933b18306b
--- /dev/null
+++ b/mysql-test/suite/perfschema/r/start_server_nothing.result
@@ -0,0 +1,122 @@
+show databases;
+Database
+information_schema
+mtr
+mysql
+performance_schema
+test
+select count(*) from performance_schema.performance_timers;
+count(*)
+5
+select count(*) from performance_schema.setup_consumers;
+count(*)
+8
+select count(*) > 0 from performance_schema.setup_instruments;
+count(*) > 0
+0
+select count(*) from performance_schema.setup_timers;
+count(*)
+1
+select * from performance_schema.cond_instances;
+select * from performance_schema.events_waits_current;
+select * from performance_schema.events_waits_history;
+select * from performance_schema.events_waits_history_long;
+select * from performance_schema.events_waits_summary_by_instance;
+select * from performance_schema.events_waits_summary_by_thread_by_event_name;
+select * from performance_schema.events_waits_summary_global_by_event_name;
+select * from performance_schema.file_instances;
+select * from performance_schema.file_summary_by_event_name;
+select * from performance_schema.file_summary_by_instance;
+select * from performance_schema.mutex_instances;
+select * from performance_schema.performance_timers;
+select * from performance_schema.rwlock_instances;
+select * from performance_schema.setup_consumers;
+select * from performance_schema.setup_instruments;
+select * from performance_schema.setup_timers;
+select * from performance_schema.threads;
+show variables like "performance_schema%";
+Variable_name Value
+performance_schema ON
+performance_schema_events_waits_history_long_size 0
+performance_schema_events_waits_history_size 0
+performance_schema_max_cond_classes 0
+performance_schema_max_cond_instances 0
+performance_schema_max_file_classes 0
+performance_schema_max_file_handles 0
+performance_schema_max_file_instances 0
+performance_schema_max_mutex_classes 0
+performance_schema_max_mutex_instances 0
+performance_schema_max_rwlock_classes 0
+performance_schema_max_rwlock_instances 0
+performance_schema_max_table_handles 1000
+performance_schema_max_table_instances 500
+performance_schema_max_thread_classes 0
+performance_schema_max_thread_instances 0
+show engine PERFORMANCE_SCHEMA status;
+show status like "performance_schema%";
+show variables like "performance_schema%";
+Variable_name Value
+performance_schema ON
+performance_schema_events_waits_history_long_size 0
+performance_schema_events_waits_history_size 0
+performance_schema_max_cond_classes 0
+performance_schema_max_cond_instances 0
+performance_schema_max_file_classes 0
+performance_schema_max_file_handles 0
+performance_schema_max_file_instances 0
+performance_schema_max_mutex_classes 0
+performance_schema_max_mutex_instances 0
+performance_schema_max_rwlock_classes 0
+performance_schema_max_rwlock_instances 0
+performance_schema_max_table_handles 1000
+performance_schema_max_table_instances 500
+performance_schema_max_thread_classes 0
+performance_schema_max_thread_instances 0
+select * from performance_schema.setup_instruments;
+NAME ENABLED TIMED
+select TIMER_NAME from performance_schema.performance_timers;
+TIMER_NAME
+CYCLE
+NANOSECOND
+MICROSECOND
+MILLISECOND
+TICK
+select * from performance_schema.setup_consumers;
+NAME ENABLED
+events_waits_current YES
+events_waits_history YES
+events_waits_history_long YES
+events_waits_summary_by_thread_by_event_name YES
+events_waits_summary_by_event_name YES
+events_waits_summary_by_instance YES
+file_summary_by_event_name YES
+file_summary_by_instance YES
+select NAME from performance_schema.setup_timers;
+NAME
+wait
+select * from performance_schema.cond_instances;
+NAME OBJECT_INSTANCE_BEGIN
+select * from performance_schema.events_waits_current;
+THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS
+select * from performance_schema.events_waits_history;
+THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS
+select * from performance_schema.events_waits_history_long;
+THREAD_ID EVENT_ID EVENT_NAME SOURCE TIMER_START TIMER_END TIMER_WAIT SPINS OBJECT_SCHEMA OBJECT_NAME OBJECT_TYPE OBJECT_INSTANCE_BEGIN NESTING_EVENT_ID OPERATION NUMBER_OF_BYTES FLAGS
+select * from performance_schema.events_waits_summary_by_instance;
+EVENT_NAME OBJECT_INSTANCE_BEGIN COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT
+select * from performance_schema.events_waits_summary_by_thread_by_event_name;
+THREAD_ID EVENT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT
+select * from performance_schema.events_waits_summary_global_by_event_name;
+EVENT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT
+select * from performance_schema.file_instances;
+FILE_NAME EVENT_NAME OPEN_COUNT
+select * from performance_schema.file_summary_by_event_name;
+EVENT_NAME COUNT_READ COUNT_WRITE SUM_NUMBER_OF_BYTES_READ SUM_NUMBER_OF_BYTES_WRITE
+select * from performance_schema.file_summary_by_instance;
+FILE_NAME EVENT_NAME COUNT_READ COUNT_WRITE SUM_NUMBER_OF_BYTES_READ SUM_NUMBER_OF_BYTES_WRITE
+select * from performance_schema.mutex_instances;
+NAME OBJECT_INSTANCE_BEGIN LOCKED_BY_THREAD_ID
+select * from performance_schema.rwlock_instances;
+NAME OBJECT_INSTANCE_BEGIN WRITE_LOCKED_BY_THREAD_ID READ_LOCKED_BY_COUNT
+select * from performance_schema.threads;
+THREAD_ID PROCESSLIST_ID NAME
diff --git a/mysql-test/suite/perfschema/t/start_server_no_waits_history-master.opt b/mysql-test/suite/perfschema/t/start_server_no_waits_history-master.opt
new file mode 100644
index 00000000000..334f805e2d5
--- /dev/null
+++ b/mysql-test/suite/perfschema/t/start_server_no_waits_history-master.opt
@@ -0,0 +1,2 @@
+--loose-enable-performance-schema
+--loose-performance_schema_events_waits_history_size=0
diff --git a/mysql-test/suite/perfschema/t/start_server_no_waits_history.test b/mysql-test/suite/perfschema/t/start_server_no_waits_history.test
new file mode 100644
index 00000000000..2ee7dba2526
--- /dev/null
+++ b/mysql-test/suite/perfschema/t/start_server_no_waits_history.test
@@ -0,0 +1,14 @@
+# Tests for PERFORMANCE_SCHEMA
+
+--source include/not_embedded.inc
+--source include/have_perfschema.inc
+
+--source ../include/start_server_common.inc
+
+# Expect no history
+show variables like "performance_schema_events_waits_history_size";
+select count(*) from performance_schema.events_waits_history;
+
+# Valid operation, edge case
+truncate table performance_schema.events_waits_history;
+
diff --git a/mysql-test/suite/perfschema/t/start_server_no_waits_history_long-master.opt b/mysql-test/suite/perfschema/t/start_server_no_waits_history_long-master.opt
new file mode 100644
index 00000000000..ca6699f8111
--- /dev/null
+++ b/mysql-test/suite/perfschema/t/start_server_no_waits_history_long-master.opt
@@ -0,0 +1,2 @@
+--loose-enable-performance-schema
+--loose-performance_schema_events_waits_history_long_size=0
diff --git a/mysql-test/suite/perfschema/t/start_server_no_waits_history_long.test b/mysql-test/suite/perfschema/t/start_server_no_waits_history_long.test
new file mode 100644
index 00000000000..e393304a94d
--- /dev/null
+++ b/mysql-test/suite/perfschema/t/start_server_no_waits_history_long.test
@@ -0,0 +1,14 @@
+# Tests for PERFORMANCE_SCHEMA
+
+--source include/not_embedded.inc
+--source include/have_perfschema.inc
+
+--source ../include/start_server_common.inc
+
+# Expect no history long
+show variables like "performance_schema_events_waits_history_long_size";
+select count(*) from performance_schema.events_waits_history_long;
+
+# Valid operation, edge case
+truncate table performance_schema.events_waits_history_long;
+
diff --git a/mysql-test/suite/perfschema/t/start_server_nothing-master.opt b/mysql-test/suite/perfschema/t/start_server_nothing-master.opt
new file mode 100644
index 00000000000..529d3a1703b
--- /dev/null
+++ b/mysql-test/suite/perfschema/t/start_server_nothing-master.opt
@@ -0,0 +1,19 @@
+--loose-enable-performance-schema
+
+--loose-performance_schema_events_waits_history_long_size=0
+--loose-performance_schema_events_waits_history_size=0
+
+--loose-performance_schema_max_mutex_classes=0
+--loose-performance_schema_max_rwlock_classes=0
+--loose-performance_schema_max_cond_classes=0
+--loose-performance_schema_max_file_classes=0
+--loose-performance_schema_max_thread_classes=0
+
+--loose-performance_schema_max_mutex_instances=0
+--loose-performance_schema_max_rwlock_instances=0
+--loose-performance_schema_max_cond_instances=0
+--loose-performance_schema_max_file_instances=0
+--loose-performance_schema_max_thread_instances=0
+
+--loose-performance_schema_max_file_handles=0
+
diff --git a/mysql-test/suite/perfschema/t/start_server_nothing.test b/mysql-test/suite/perfschema/t/start_server_nothing.test
new file mode 100644
index 00000000000..b2deae35ba6
--- /dev/null
+++ b/mysql-test/suite/perfschema/t/start_server_nothing.test
@@ -0,0 +1,30 @@
+# Tests for PERFORMANCE_SCHEMA
+
+--source include/not_embedded.inc
+--source include/have_perfschema.inc
+
+--source ../include/start_server_common.inc
+
+show variables like "performance_schema%";
+
+# Not empty
+select * from performance_schema.setup_instruments;
+select TIMER_NAME from performance_schema.performance_timers;
+select * from performance_schema.setup_consumers;
+select NAME from performance_schema.setup_timers;
+
+# All empty
+select * from performance_schema.cond_instances;
+select * from performance_schema.events_waits_current;
+select * from performance_schema.events_waits_history;
+select * from performance_schema.events_waits_history_long;
+select * from performance_schema.events_waits_summary_by_instance;
+select * from performance_schema.events_waits_summary_by_thread_by_event_name;
+select * from performance_schema.events_waits_summary_global_by_event_name;
+select * from performance_schema.file_instances;
+select * from performance_schema.file_summary_by_event_name;
+select * from performance_schema.file_summary_by_instance;
+select * from performance_schema.mutex_instances;
+select * from performance_schema.rwlock_instances;
+select * from performance_schema.threads;
+
diff --git a/mysql-test/suite/rpl/disabled.def b/mysql-test/suite/rpl/disabled.def
index a45fdb47ae6..9eb5f57c7be 100644
--- a/mysql-test/suite/rpl/disabled.def
+++ b/mysql-test/suite/rpl/disabled.def
@@ -13,5 +13,4 @@
rpl_row_create_table : Bug#11759274 2010-02-27 andrei failed different way than earlier with bug#45576
rpl_spec_variables : BUG#11755836 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux
rpl_get_master_version_and_clock : Bug#11766137 Jan 05 2011 joro Valgrind warnings rpl_get_master_version_and_clock
-rpl_row_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out
rpl_stm_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out
diff --git a/mysql-test/suite/rpl/r/replace.result b/mysql-test/suite/rpl/r/replace.result
new file mode 100644
index 00000000000..855c54ef8fa
--- /dev/null
+++ b/mysql-test/suite/rpl/r/replace.result
@@ -0,0 +1,22 @@
+include/master-slave.inc
+[connection master]
+drop table if exists t1;
+Warnings:
+Note 1051 Unknown table 't1'
+CREATE TABLE t1 (pr_id int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, pr_page int(11) NOT NULL, pr_type varbinary(60) NOT NULL, test int, UNIQUE KEY pr_pagetype (pr_page,pr_type)) ENGINE=myisam AUTO_INCREMENT=136;
+insert into t1 (pr_page, pr_type, test) values(1,"one",0),(2,"two",0);
+select * from t1;
+pr_id pr_page pr_type test
+136 1 one 0
+137 2 two 0
+replace into t1 (pr_page, pr_type,test) values(1,"one",2);
+select * from t1;
+pr_id pr_page pr_type test
+138 1 one 2
+137 2 two 0
+select * from t1;
+pr_id pr_page pr_type test
+138 1 one 2
+137 2 two 0
+drop table t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_bug31076.result b/mysql-test/suite/rpl/r/rpl_bug31076.result
index 1cf8b87f68d..e09960e848e 100644
--- a/mysql-test/suite/rpl/r/rpl_bug31076.result
+++ b/mysql-test/suite/rpl/r/rpl_bug31076.result
@@ -35,6 +35,7 @@ KEY `event_id` (`event_id`),
KEY `visit_id` (`visit_id`),
KEY `data` (`data`)
) ENGINE=MyISAM AUTO_INCREMENT=33900731 DEFAULT CHARSET=latin1;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
BINLOG '
@@ -47,6 +48,7 @@ Bk3vRhe0AQAAWgAAABEMyQkQAJlXFwIAAAEABv/AIE4AvvVDAQZN70YAK0Rvd25sb2Fkcy9NeVNR
TC00LjEvbXlzcWwtNC4xLjEyYS13aW4zMi56aXBPaAIC
'/*!*/;
SET INSERT_ID=21231039/*!*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
use track/*!*/;
SET TIMESTAMP=1190087942/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
diff --git a/mysql-test/suite/rpl/r/rpl_hrtime.result b/mysql-test/suite/rpl/r/rpl_hrtime.result
index fbe4ba28409..e03257b8901 100644
--- a/mysql-test/suite/rpl/r/rpl_hrtime.result
+++ b/mysql-test/suite/rpl/r/rpl_hrtime.result
@@ -26,6 +26,7 @@ a b c
0000-00-00 00:00:00.0000 0 2022-02-02 02:02:02.65
drop table t1;
include/rpl_end.inc
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -95,3 +96,4 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
diff --git a/mysql-test/suite/rpl/r/rpl_mdev382.result b/mysql-test/suite/rpl/r/rpl_mdev382.result
index bbc57006d0d..f904561b722 100644
--- a/mysql-test/suite/rpl/r/rpl_mdev382.result
+++ b/mysql-test/suite/rpl/r/rpl_mdev382.result
@@ -154,6 +154,7 @@ master-bin.000001 # Query # # BEGIN
master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f\'le.txt' INTO TABLE `db1``; select 'oops!'`.`t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`= concat('|', "b""a'z", "!") ;file_id=#
master-bin.000001 # Query # # COMMIT
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -197,6 +198,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
SELECT * FROM `db1``; select 'oops!'`.`t``1`;
a`1 b`2 c`3
fo\o bar |b"a'z!
@@ -246,6 +248,7 @@ master-bin.000001 # User var # # @```c`=-123450123456789012345678901234567890123
master-bin.000001 # User var # # @```d```=_latin1 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 COLLATE latin1_swedish_ci
master-bin.000001 # Query # # use `db1``; select 'oops!'`; INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98))
master-bin.000001 # Query # # COMMIT
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -291,6 +294,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
SELECT * FROM `db1``; select 'oops!'`.t1 ORDER BY a1;
a1 a2 a3 a4 b c d
-9223372036854775808 42 9223372036854775807 18446744073709551615 -1.234560123456789e125 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
@@ -337,6 +341,7 @@ Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000002 # Query # # BEGIN
master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES(1)
master-bin.000002 # Query # # COMMIT
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -363,5 +368,6 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
DROP TABLE t1;
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_report_port.result b/mysql-test/suite/rpl/r/rpl_report_port.result
index 6a9ac341780..2f422c8b577 100644
--- a/mysql-test/suite/rpl/r/rpl_report_port.result
+++ b/mysql-test/suite/rpl/r/rpl_report_port.result
@@ -2,10 +2,12 @@ include/master-slave.inc
[connection master]
include/rpl_restart_server.inc [server_number=2 parameters: --report-port=9000]
include/start_slave.inc
+include/wait_for_slave_param.inc [Slave_IO_State]
[Slave restarted with the report-port set to some value]
include/assert.inc [The value shown for the slave's port number is user specified port number which is the value set for report-port.]
include/rpl_restart_server.inc [server_number=2]
include/start_slave.inc
+include/wait_for_slave_param.inc [Slave_IO_State]
[Slave restarted with the report-port set to the value of slave's port number]
include/assert.inc [The default value shown for the slave's port number is the actual port number of the slave.]
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result
index 1a4d5c7574d..1489af830cc 100644
--- a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result
+++ b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result
@@ -150,6 +150,7 @@ c1 c3 c4 c5
5 2006-02-22 00:00:00 Tested in Texas 11
--- Test 2 position test --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -170,8 +171,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- Test 3 First Remote test --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -201,6 +204,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- Test 4 Second Remote test --
DROP TABLE t1;
@@ -274,6 +278,7 @@ c1 c3 c4 c5
5 2006-02-22 00:00:00 Tested in Texas 11
--- Test 5 LOAD DATA --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -281,8 +286,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- Test 6 reading stdin --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -312,8 +319,10 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- Test 7 reading stdin w/position --
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -334,6 +343,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
--- Test 8 switch internal charset --
stop slave;
diff --git a/mysql-test/suite/rpl/r/rpl_sp.result b/mysql-test/suite/rpl/r/rpl_sp.result
index 8a2a88a8c90..2f5052f0180 100644
--- a/mysql-test/suite/rpl/r/rpl_sp.result
+++ b/mysql-test/suite/rpl/r/rpl_sp.result
@@ -652,6 +652,7 @@ show function status like '%mysqltestbug36570%';
Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation
test mysqltestbug36570_f1 FUNCTION root@localhost t t DEFINER latin1 latin1_swedish_ci latin1_swedish_ci
flush logs;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
@@ -1178,6 +1179,7 @@ DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
use test;
drop procedure mysqltestbug36570_p1;
drop procedure ` mysqltestbug36570_p2`;
diff --git a/mysql-test/suite/rpl/r/semisync_memleak_4066.result b/mysql-test/suite/rpl/r/semisync_memleak_4066.result
new file mode 100644
index 00000000000..c0dd9f0c993
--- /dev/null
+++ b/mysql-test/suite/rpl/r/semisync_memleak_4066.result
@@ -0,0 +1,6 @@
+include/master-slave.inc
+[connection master]
+INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
+CREATE TEMPORARY TABLE tmp (i INT);
+include/rpl_end.inc
+uninstall plugin rpl_semi_sync_master;
diff --git a/mysql-test/suite/rpl/t/replace.test b/mysql-test/suite/rpl/t/replace.test
new file mode 100644
index 00000000000..36afda0d927
--- /dev/null
+++ b/mysql-test/suite/rpl/t/replace.test
@@ -0,0 +1,24 @@
+#
+# Test of REPLACE with replication
+#
+
+source include/master-slave.inc;
+
+#
+# Test of doing replace on unique key on table with auto_increment
+#
+
+drop table if exists t1;
+CREATE TABLE t1 (pr_id int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, pr_page int(11) NOT NULL, pr_type varbinary(60) NOT NULL, test int, UNIQUE KEY pr_pagetype (pr_page,pr_type)) ENGINE=myisam AUTO_INCREMENT=136;
+insert into t1 (pr_page, pr_type, test) values(1,"one",0),(2,"two",0);
+select * from t1;
+replace into t1 (pr_page, pr_type,test) values(1,"one",2);
+select * from t1;
+sync_slave_with_master;
+connection slave;
+select * from t1;
+connection master;
+drop table t1;
+
+# End of 5.5 tests
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_bug31076.test b/mysql-test/suite/rpl/t/rpl_bug31076.test
index 028ca32636a..4e9517fbf2a 100644
--- a/mysql-test/suite/rpl/t/rpl_bug31076.test
+++ b/mysql-test/suite/rpl/t/rpl_bug31076.test
@@ -40,6 +40,7 @@ CREATE TABLE `visits_events` (
KEY `data` (`data`)
) ENGINE=MyISAM AUTO_INCREMENT=33900731 DEFAULT CHARSET=latin1;
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
--delimiter /*!*/;
@@ -119,6 +120,7 @@ SET INSERT_ID=21231039/*!*/;
# 9c90ded 2d 63 6f 6e 6e 65 63 74 6f 72 2d 6a 61 76 61 2d |.connector.java.|
# 9c90dfd 33 2e 30 2e 31 37 2d 67 61 2e 7a 69 70 |3.0.17.ga.zip|
# Query thread_id=28278824 exec_time=0 error_code=0
+/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
use track/*!*/;
SET TIMESTAMP=1190087942/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
diff --git a/mysql-test/suite/rpl/t/rpl_report_port.test b/mysql-test/suite/rpl/t/rpl_report_port.test
index 12c34ce01b1..6e728a678ad 100644
--- a/mysql-test/suite/rpl/t/rpl_report_port.test
+++ b/mysql-test/suite/rpl/t/rpl_report_port.test
@@ -32,6 +32,9 @@ connection master;
connection slave;
--source include/start_slave.inc
+--let $slave_param= Slave_IO_State
+--let $slave_param_value= Waiting for master to send event
+--source include/wait_for_slave_param.inc
--echo [Slave restarted with the report-port set to some value]
connection master;
@@ -52,6 +55,9 @@ connection master;
connection slave;
--source include/start_slave.inc
+--let $slave_param= Slave_IO_State
+--let $slave_param_value= Waiting for master to send event
+--source include/wait_for_slave_param.inc
connection master;
sync_slave_with_master;
diff --git a/mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock.test b/mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock.test
index a63844b451c..6db4e2bea04 100644
--- a/mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock.test
+++ b/mysql-test/suite/rpl/t/rpl_rotate_purge_deadlock.test
@@ -1,10 +1,10 @@
#
# Bug#11763573 - 56299: MUTEX DEADLOCK WITH COM_BINLOG_DUMP, BINLOG PURGE, AND PROCESSLIST/KILL
#
-source include/master-slave.inc;
source include/have_debug_sync.inc;
source include/have_binlog_format_row.inc;
source include/have_innodb.inc;
+source include/master-slave.inc;
#
# Testing that execution of two concurrent INSERTing connections both
diff --git a/mysql-test/suite/rpl/t/semisync_memleak_4066.test b/mysql-test/suite/rpl/t/semisync_memleak_4066.test
new file mode 100644
index 00000000000..687af883936
--- /dev/null
+++ b/mysql-test/suite/rpl/t/semisync_memleak_4066.test
@@ -0,0 +1,19 @@
+#
+# MDEV-4066 semisync_master + temporary tables causes memory leaks
+#
+source include/have_semisync_plugin.inc;
+source include/have_binlog_format_row.inc;
+source include/master-slave.inc;
+
+connection master;
+
+--replace_result .dll .so
+eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO';
+
+--connect (con1,localhost,root,,)
+CREATE TEMPORARY TABLE tmp (i INT);
+--disconnect con1
+
+source include/rpl_end.inc;
+uninstall plugin rpl_semi_sync_master;
+
diff --git a/mysql-test/suite/sys_vars/disabled.def b/mysql-test/suite/sys_vars/disabled.def
index 1ae495e4863..596191d09b6 100644
--- a/mysql-test/suite/sys_vars/disabled.def
+++ b/mysql-test/suite/sys_vars/disabled.def
@@ -10,6 +10,5 @@
#
##############################################################################
-innodb_trx_rseg_n_slots_debug_basic: variable innodb_trx_rseg_n_slots_debug is removed in MariaDB
innodb_flush_checkpoint_debug_basic: removed from XtraDB-26.0
diff --git a/mysql-test/suite/sys_vars/r/innodb_limit_optimistic_insert_debug_basic.result b/mysql-test/suite/sys_vars/r/innodb_limit_optimistic_insert_debug_basic.result
new file mode 100644
index 00000000000..3d4f401aad1
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/innodb_limit_optimistic_insert_debug_basic.result
@@ -0,0 +1,58 @@
+SET @start_global_value = @@global.innodb_limit_optimistic_insert_debug;
+SELECT @start_global_value;
+@start_global_value
+0
+select @@global.innodb_limit_optimistic_insert_debug;
+@@global.innodb_limit_optimistic_insert_debug
+0
+select @@session.innodb_limit_optimistic_insert_debug;
+ERROR HY000: Variable 'innodb_limit_optimistic_insert_debug' is a GLOBAL variable
+show global variables like 'innodb_limit_optimistic_insert_debug';
+Variable_name Value
+innodb_limit_optimistic_insert_debug 0
+show session variables like 'innodb_limit_optimistic_insert_debug';
+Variable_name Value
+innodb_limit_optimistic_insert_debug 0
+select * from information_schema.global_variables where variable_name='innodb_limit_optimistic_insert_debug';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG 0
+select * from information_schema.session_variables where variable_name='innodb_limit_optimistic_insert_debug';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG 0
+set global innodb_limit_optimistic_insert_debug=1;
+select @@global.innodb_limit_optimistic_insert_debug;
+@@global.innodb_limit_optimistic_insert_debug
+1
+select * from information_schema.global_variables where variable_name='innodb_limit_optimistic_insert_debug';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG 1
+select * from information_schema.session_variables where variable_name='innodb_limit_optimistic_insert_debug';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG 1
+set @@global.innodb_limit_optimistic_insert_debug=0;
+select @@global.innodb_limit_optimistic_insert_debug;
+@@global.innodb_limit_optimistic_insert_debug
+0
+select * from information_schema.global_variables where variable_name='innodb_limit_optimistic_insert_debug';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG 0
+select * from information_schema.session_variables where variable_name='innodb_limit_optimistic_insert_debug';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG 0
+set session innodb_limit_optimistic_insert_debug='some';
+ERROR HY000: Variable 'innodb_limit_optimistic_insert_debug' is a GLOBAL variable and should be set with SET GLOBAL
+set @@session.innodb_limit_optimistic_insert_debug='some';
+ERROR HY000: Variable 'innodb_limit_optimistic_insert_debug' is a GLOBAL variable and should be set with SET GLOBAL
+set global innodb_limit_optimistic_insert_debug=1.1;
+ERROR 42000: Incorrect argument type to variable 'innodb_limit_optimistic_insert_debug'
+set global innodb_limit_optimistic_insert_debug='foo';
+ERROR 42000: Incorrect argument type to variable 'innodb_limit_optimistic_insert_debug'
+set global innodb_limit_optimistic_insert_debug=-2;
+Warnings:
+Warning 1292 Truncated incorrect innodb_limit_optimistic_insert_d value: '-2'
+set global innodb_limit_optimistic_insert_debug=1e1;
+ERROR 42000: Incorrect argument type to variable 'innodb_limit_optimistic_insert_debug'
+SET @@global.innodb_limit_optimistic_insert_debug = @start_global_value;
+SELECT @@global.innodb_limit_optimistic_insert_debug;
+@@global.innodb_limit_optimistic_insert_debug
+0
diff --git a/mysql-test/suite/sys_vars/r/innodb_changed_pages_limit_basic.result b/mysql-test/suite/sys_vars/r/innodb_max_changed_pages_basic.result
index d9d067c2cf9..d9d067c2cf9 100644
--- a/mysql-test/suite/sys_vars/r/innodb_changed_pages_limit_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_max_changed_pages_basic.result
diff --git a/mysql-test/suite/sys_vars/r/innodb_print_all_deadlocks_basic.result b/mysql-test/suite/sys_vars/r/innodb_print_all_deadlocks_basic.result
new file mode 100644
index 00000000000..1bd078dfd7e
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/innodb_print_all_deadlocks_basic.result
@@ -0,0 +1,22 @@
+SELECT @@innodb_print_all_deadlocks;
+@@innodb_print_all_deadlocks
+0
+SET GLOBAL innodb_print_all_deadlocks=1;
+CREATE TABLE t1 (c1 INT, PRIMARY KEY (c1)) ENGINE=INNODB;
+INSERT INTO t1 VALUES (123);
+CREATE TABLE t2 (c2 INT, PRIMARY KEY (c2)) ENGINE=INNODB;
+INSERT INTO t2 VALUES (456);
+BEGIN;
+SELECT * FROM t1 FOR UPDATE;
+c1
+123
+BEGIN;
+SELECT * FROM t2 FOR UPDATE;
+c2
+456
+SELECT * FROM t2 FOR UPDATE;
+SELECT * FROM t1 FOR UPDATE;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+DROP TABLE t2;
+DROP TABLE t1;
+SET GLOBAL innodb_print_all_deadlocks=default;
diff --git a/mysql-test/suite/sys_vars/r/innodb_trx_purge_view_update_only_debug_basic.result b/mysql-test/suite/sys_vars/r/innodb_trx_purge_view_update_only_debug_basic.result
new file mode 100644
index 00000000000..1779cbb48df
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/innodb_trx_purge_view_update_only_debug_basic.result
@@ -0,0 +1,62 @@
+SET @start_global_value = @@global.innodb_trx_purge_view_update_only_debug;
+SELECT @start_global_value;
+@start_global_value
+0
+select @@global.innodb_trx_purge_view_update_only_debug in (0, 1);
+@@global.innodb_trx_purge_view_update_only_debug in (0, 1)
+1
+select @@global.innodb_trx_purge_view_update_only_debug;
+@@global.innodb_trx_purge_view_update_only_debug
+0
+select @@session.innodb_trx_purge_view_update_only_debug;
+ERROR HY000: Variable 'innodb_trx_purge_view_update_only_debug' is a GLOBAL variable
+show global variables like 'innodb_trx_purge_view_update_only_debug';
+Variable_name Value
+innodb_trx_purge_view_update_only_debug OFF
+show session variables like 'innodb_trx_purge_view_update_only_debug';
+Variable_name Value
+innodb_trx_purge_view_update_only_debug OFF
+select * from information_schema.global_variables where variable_name='innodb_trx_purge_view_update_only_debug';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG OFF
+select * from information_schema.session_variables where variable_name='innodb_trx_purge_view_update_only_debug';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG OFF
+set global innodb_trx_purge_view_update_only_debug=1;
+select @@global.innodb_trx_purge_view_update_only_debug;
+@@global.innodb_trx_purge_view_update_only_debug
+1
+select * from information_schema.global_variables where variable_name='innodb_trx_purge_view_update_only_debug';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG ON
+select * from information_schema.session_variables where variable_name='innodb_trx_purge_view_update_only_debug';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG ON
+set @@global.innodb_trx_purge_view_update_only_debug=0;
+select @@global.innodb_trx_purge_view_update_only_debug;
+@@global.innodb_trx_purge_view_update_only_debug
+0
+select * from information_schema.global_variables where variable_name='innodb_trx_purge_view_update_only_debug';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG OFF
+select * from information_schema.session_variables where variable_name='innodb_trx_purge_view_update_only_debug';
+VARIABLE_NAME VARIABLE_VALUE
+INNODB_TRX_PURGE_VIEW_UPDATE_ONLY_DEBUG OFF
+set session innodb_trx_purge_view_update_only_debug='some';
+ERROR HY000: Variable 'innodb_trx_purge_view_update_only_debug' is a GLOBAL variable and should be set with SET GLOBAL
+set @@session.innodb_trx_purge_view_update_only_debug='some';
+ERROR HY000: Variable 'innodb_trx_purge_view_update_only_debug' is a GLOBAL variable and should be set with SET GLOBAL
+set global innodb_trx_purge_view_update_only_debug=1.1;
+ERROR 42000: Incorrect argument type to variable 'innodb_trx_purge_view_update_only_debug'
+set global innodb_trx_purge_view_update_only_debug='foo';
+ERROR 42000: Variable 'innodb_trx_purge_view_update_only_debug' can't be set to the value of 'foo'
+set global innodb_trx_purge_view_update_only_debug=-2;
+ERROR 42000: Variable 'innodb_trx_purge_view_update_only_debug' can't be set to the value of '-2'
+set global innodb_trx_purge_view_update_only_debug=1e1;
+ERROR 42000: Incorrect argument type to variable 'innodb_trx_purge_view_update_only_debug'
+set global innodb_trx_purge_view_update_only_debug=2;
+ERROR 42000: Variable 'innodb_trx_purge_view_update_only_debug' can't be set to the value of '2'
+SET @@global.innodb_trx_purge_view_update_only_debug = @start_global_value;
+SELECT @@global.innodb_trx_purge_view_update_only_debug;
+@@global.innodb_trx_purge_view_update_only_debug
+0
diff --git a/mysql-test/suite/sys_vars/r/ndb_log_update_as_write_basic.result b/mysql-test/suite/sys_vars/r/ndb_log_update_as_write_basic.result
deleted file mode 100644
index 6353fba2b7c..00000000000
--- a/mysql-test/suite/sys_vars/r/ndb_log_update_as_write_basic.result
+++ /dev/null
@@ -1,14 +0,0 @@
-SET @global_start_value = @@global.ndb_log_update_as_write;
-ERROR HY000: Unknown system variable 'ndb_log_update_as_write'
-SELECT @@global.ndb_log_update_as_write;
-ERROR HY000: Unknown system variable 'ndb_log_update_as_write'
-'Bug: The value is not a system variable or atleast not supported in version 5.1.22'
-'#--------------------FN_DYNVARS_102_01------------------------#'
-'#---------------------FN_DYNVARS_102_02-------------------------#'
-'#--------------------FN_DYNVARS_102_03------------------------#'
-'#--------------------FN_DYNVARS_102_04-------------------------#'
-'#-------------------FN_DYNVARS_102_05----------------------------#'
-'#----------------------FN_DYNVARS_102_06------------------------#'
-'#----------------------FN_DYNVARS_102_07------------------------#'
-'#---------------------FN_DYNVARS_102_08-------------------------#'
-'#---------------------FN_DYNVARS_102_09----------------------#'
diff --git a/mysql-test/suite/sys_vars/r/ndb_log_updated_only_basic.result b/mysql-test/suite/sys_vars/r/ndb_log_updated_only_basic.result
deleted file mode 100644
index 38abb7cc263..00000000000
--- a/mysql-test/suite/sys_vars/r/ndb_log_updated_only_basic.result
+++ /dev/null
@@ -1,14 +0,0 @@
-SET @global_start_value = @@global.ndb_log_updated_only;
-ERROR HY000: Unknown system variable 'ndb_log_updated_only'
-SELECT @@global.ndb_log_updated_only;
-ERROR HY000: Unknown system variable 'ndb_log_updated_only'
-'Bug: The value is not a system variable or atleast not supported in version 5.1.22'
-'#--------------------FN_DYNVARS_103_01------------------------#'
-'#---------------------FN_DYNVARS_103_02-------------------------#'
-'#--------------------FN_DYNVARS_103_03------------------------#'
-'#--------------------FN_DYNVARS_103_04-------------------------#'
-'#-------------------FN_DYNVARS_103_05----------------------------#'
-'#----------------------FN_DYNVARS_103_06------------------------#'
-'#----------------------FN_DYNVARS_103_07------------------------#'
-'#---------------------FN_DYNVARS_103_08-------------------------#'
-'#---------------------FN_DYNVARS_103_09----------------------#'
diff --git a/mysql-test/suite/sys_vars/r/pseudo_slave_mode_basic.result b/mysql-test/suite/sys_vars/r/pseudo_slave_mode_basic.result
new file mode 100644
index 00000000000..c98dd338909
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/pseudo_slave_mode_basic.result
@@ -0,0 +1,119 @@
+SET @session_start_value = @@session.pseudo_slave_mode;
+SELECT @session_start_value;
+@session_start_value
+0
+'#--------------------FN_DYNVARS_156_01------------------------#'
+SET @@session.pseudo_slave_mode = 0;
+Warnings:
+Warning 1231 'pseudo_slave_mode' change was ineffective.
+SET @@session.pseudo_slave_mode = DEFAULT;
+Warnings:
+Warning 1231 'pseudo_slave_mode' change was ineffective.
+SELECT @@session.pseudo_slave_mode;
+@@session.pseudo_slave_mode
+0
+SET @@session.pseudo_slave_mode = 1;
+SET @@session.pseudo_slave_mode = DEFAULT;
+Warnings:
+Warning 1231 Slave applier execution mode not active, statement ineffective.
+SELECT @@session.pseudo_slave_mode;
+@@session.pseudo_slave_mode
+0
+'#---------------------FN_DYNVARS_156_02-------------------------#'
+SET pseudo_slave_mode = 1;
+SELECT @@pseudo_slave_mode;
+@@pseudo_slave_mode
+1
+SELECT session.pseudo_slave_mode;
+ERROR 42S02: Unknown table 'session' in field list
+SELECT local.pseudo_slave_mode;
+ERROR 42S02: Unknown table 'local' in field list
+SET session pseudo_slave_mode = 0;
+Warnings:
+Warning 1231 Slave applier execution mode not active, statement ineffective.
+SELECT @@session.pseudo_slave_mode;
+@@session.pseudo_slave_mode
+0
+'#--------------------FN_DYNVARS_156_03------------------------#'
+SET @@session.pseudo_slave_mode = 0;
+Warnings:
+Warning 1231 'pseudo_slave_mode' change was ineffective.
+SELECT @@session.pseudo_slave_mode;
+@@session.pseudo_slave_mode
+0
+SET @@session.pseudo_slave_mode = 1;
+SELECT @@session.pseudo_slave_mode;
+@@session.pseudo_slave_mode
+1
+'#--------------------FN_DYNVARS_156_04-------------------------#'
+SET @@session.pseudo_slave_mode = -1;
+ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of '-1'
+SET @@session.pseudo_slave_mode = 2;
+ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of '2'
+SET @@session.pseudo_slave_mode = "T";
+ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'T'
+SET @@session.pseudo_slave_mode = "Y";
+ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'Y'
+SET @@session.pseudo_slave_mode = TRÜE;
+ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'TRÜE'
+SET @@session.pseudo_slave_mode = ÕN;
+ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'ÕN'
+SET @@session.pseudo_slave_mode = OF;
+ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'OF'
+SET @@session.pseudo_slave_mode = ÓFF;
+ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'ÓFF'
+SET @@session.pseudo_slave_mode = '¹';
+ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of '¹'
+SET @@session.pseudo_slave_mode = NO;
+ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'NO'
+'#-------------------FN_DYNVARS_156_05----------------------------#'
+SET @@global.pseudo_slave_mode = 0;
+ERROR HY000: Variable 'pseudo_slave_mode' is a SESSION variable and can't be used with SET GLOBAL
+SELECT @@global.pseudo_slave_mode;
+ERROR HY000: Variable 'pseudo_slave_mode' is a SESSION variable
+'#----------------------FN_DYNVARS_156_06------------------------#'
+SELECT count(VARIABLE_VALUE) FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='pseudo_slave_mode';
+count(VARIABLE_VALUE)
+1
+'#----------------------FN_DYNVARS_156_07------------------------#'
+SELECT IF(@@session.pseudo_slave_mode, "ON", "OFF") = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='pseudo_slave_mode';
+IF(@@session.pseudo_slave_mode, "ON", "OFF") = VARIABLE_VALUE
+1
+SELECT @@session.pseudo_slave_mode;
+@@session.pseudo_slave_mode
+1
+SELECT VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='pseudo_slave_mode';
+VARIABLE_VALUE
+ON
+'#---------------------FN_DYNVARS_156_08-------------------------#'
+SET @@session.pseudo_slave_mode = OFF;
+Warnings:
+Warning 1231 Slave applier execution mode not active, statement ineffective.
+SELECT @@session.pseudo_slave_mode;
+@@session.pseudo_slave_mode
+0
+SET @@session.pseudo_slave_mode = ON;
+SELECT @@session.pseudo_slave_mode;
+@@session.pseudo_slave_mode
+1
+'#---------------------FN_DYNVARS_156_09----------------------#'
+SET @@session.pseudo_slave_mode = TRUE;
+SELECT @@session.pseudo_slave_mode;
+@@session.pseudo_slave_mode
+1
+SET @@session.pseudo_slave_mode = FALSE;
+Warnings:
+Warning 1231 Slave applier execution mode not active, statement ineffective.
+SELECT @@session.pseudo_slave_mode;
+@@session.pseudo_slave_mode
+0
+SET @@session.pseudo_slave_mode = @session_start_value;
+Warnings:
+Warning 1231 'pseudo_slave_mode' change was ineffective.
+SELECT @@session.pseudo_slave_mode;
+@@session.pseudo_slave_mode
+0
diff --git a/mysql-test/suite/sys_vars/t/innodb_limit_optimistic_insert_debug_basic.test b/mysql-test/suite/sys_vars/t/innodb_limit_optimistic_insert_debug_basic.test
new file mode 100644
index 00000000000..7998297c69e
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/innodb_limit_optimistic_insert_debug_basic.test
@@ -0,0 +1,50 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+
+SET @start_global_value = @@global.innodb_limit_optimistic_insert_debug;
+SELECT @start_global_value;
+
+#
+# exists as global only
+#
+select @@global.innodb_limit_optimistic_insert_debug;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.innodb_limit_optimistic_insert_debug;
+show global variables like 'innodb_limit_optimistic_insert_debug';
+show session variables like 'innodb_limit_optimistic_insert_debug';
+select * from information_schema.global_variables where variable_name='innodb_limit_optimistic_insert_debug';
+select * from information_schema.session_variables where variable_name='innodb_limit_optimistic_insert_debug';
+
+#
+# show that it's writable
+#
+set global innodb_limit_optimistic_insert_debug=1;
+select @@global.innodb_limit_optimistic_insert_debug;
+select * from information_schema.global_variables where variable_name='innodb_limit_optimistic_insert_debug';
+select * from information_schema.session_variables where variable_name='innodb_limit_optimistic_insert_debug';
+set @@global.innodb_limit_optimistic_insert_debug=0;
+select @@global.innodb_limit_optimistic_insert_debug;
+select * from information_schema.global_variables where variable_name='innodb_limit_optimistic_insert_debug';
+select * from information_schema.session_variables where variable_name='innodb_limit_optimistic_insert_debug';
+--error ER_GLOBAL_VARIABLE
+set session innodb_limit_optimistic_insert_debug='some';
+--error ER_GLOBAL_VARIABLE
+set @@session.innodb_limit_optimistic_insert_debug='some';
+
+#
+# incorrect types
+#
+--error ER_WRONG_TYPE_FOR_VAR
+set global innodb_limit_optimistic_insert_debug=1.1;
+--error ER_WRONG_TYPE_FOR_VAR
+set global innodb_limit_optimistic_insert_debug='foo';
+set global innodb_limit_optimistic_insert_debug=-2;
+--error ER_WRONG_TYPE_FOR_VAR
+set global innodb_limit_optimistic_insert_debug=1e1;
+
+#
+# Cleanup
+#
+
+SET @@global.innodb_limit_optimistic_insert_debug = @start_global_value;
+SELECT @@global.innodb_limit_optimistic_insert_debug;
diff --git a/mysql-test/suite/sys_vars/t/innodb_changed_pages_limit_basic.test b/mysql-test/suite/sys_vars/t/innodb_max_changed_pages_basic.test
index 00aa476e8d2..00aa476e8d2 100644
--- a/mysql-test/suite/sys_vars/t/innodb_changed_pages_limit_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_max_changed_pages_basic.test
diff --git a/mysql-test/suite/sys_vars/t/innodb_print_all_deadlocks_basic.test b/mysql-test/suite/sys_vars/t/innodb_print_all_deadlocks_basic.test
new file mode 100644
index 00000000000..5ad0ae485e0
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/innodb_print_all_deadlocks_basic.test
@@ -0,0 +1,48 @@
+#
+# innodb_print_all_deadlocks
+#
+
+-- source include/have_innodb.inc
+
+SELECT @@innodb_print_all_deadlocks;
+
+SET GLOBAL innodb_print_all_deadlocks=1;
+
+CREATE TABLE t1 (c1 INT, PRIMARY KEY (c1)) ENGINE=INNODB;
+INSERT INTO t1 VALUES (123);
+
+CREATE TABLE t2 (c2 INT, PRIMARY KEY (c2)) ENGINE=INNODB;
+INSERT INTO t2 VALUES (456);
+
+-- connect (con1,localhost,root,,)
+-- connect (con2,localhost,root,,)
+
+-- connection con1
+BEGIN;
+SELECT * FROM t1 FOR UPDATE;
+
+-- connection con2
+BEGIN;
+SELECT * FROM t2 FOR UPDATE;
+
+-- connection con1
+-- send
+SELECT * FROM t2 FOR UPDATE;
+
+-- connection con2
+let $wait_condition=
+SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE state = 'Sending data' AND info = 'SELECT * FROM t2 FOR UPDATE';
+-- source include/wait_condition.inc
+-- error ER_LOCK_DEADLOCK
+SELECT * FROM t1 FOR UPDATE;
+
+-- connection default
+
+-- disconnect con1
+-- disconnect con2
+
+DROP TABLE t2;
+DROP TABLE t1;
+
+SET GLOBAL innodb_print_all_deadlocks=default;
diff --git a/mysql-test/suite/sys_vars/t/innodb_trx_purge_view_update_only_debug_basic.test b/mysql-test/suite/sys_vars/t/innodb_trx_purge_view_update_only_debug_basic.test
new file mode 100644
index 00000000000..d7207515fe1
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/innodb_trx_purge_view_update_only_debug_basic.test
@@ -0,0 +1,54 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+
+SET @start_global_value = @@global.innodb_trx_purge_view_update_only_debug;
+SELECT @start_global_value;
+
+#
+# exists as global only
+#
+select @@global.innodb_trx_purge_view_update_only_debug in (0, 1);
+select @@global.innodb_trx_purge_view_update_only_debug;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.innodb_trx_purge_view_update_only_debug;
+show global variables like 'innodb_trx_purge_view_update_only_debug';
+show session variables like 'innodb_trx_purge_view_update_only_debug';
+select * from information_schema.global_variables where variable_name='innodb_trx_purge_view_update_only_debug';
+select * from information_schema.session_variables where variable_name='innodb_trx_purge_view_update_only_debug';
+
+#
+# show that it's writable
+#
+set global innodb_trx_purge_view_update_only_debug=1;
+select @@global.innodb_trx_purge_view_update_only_debug;
+select * from information_schema.global_variables where variable_name='innodb_trx_purge_view_update_only_debug';
+select * from information_schema.session_variables where variable_name='innodb_trx_purge_view_update_only_debug';
+set @@global.innodb_trx_purge_view_update_only_debug=0;
+select @@global.innodb_trx_purge_view_update_only_debug;
+select * from information_schema.global_variables where variable_name='innodb_trx_purge_view_update_only_debug';
+select * from information_schema.session_variables where variable_name='innodb_trx_purge_view_update_only_debug';
+--error ER_GLOBAL_VARIABLE
+set session innodb_trx_purge_view_update_only_debug='some';
+--error ER_GLOBAL_VARIABLE
+set @@session.innodb_trx_purge_view_update_only_debug='some';
+
+#
+# incorrect types
+#
+--error ER_WRONG_TYPE_FOR_VAR
+set global innodb_trx_purge_view_update_only_debug=1.1;
+--error ER_WRONG_VALUE_FOR_VAR
+set global innodb_trx_purge_view_update_only_debug='foo';
+--error ER_WRONG_VALUE_FOR_VAR
+set global innodb_trx_purge_view_update_only_debug=-2;
+--error ER_WRONG_TYPE_FOR_VAR
+set global innodb_trx_purge_view_update_only_debug=1e1;
+--error ER_WRONG_VALUE_FOR_VAR
+set global innodb_trx_purge_view_update_only_debug=2;
+
+#
+# Cleanup
+#
+
+SET @@global.innodb_trx_purge_view_update_only_debug = @start_global_value;
+SELECT @@global.innodb_trx_purge_view_update_only_debug;
diff --git a/mysql-test/suite/sys_vars/t/ndb_log_update_as_write_basic.test b/mysql-test/suite/sys_vars/t/ndb_log_update_as_write_basic.test
deleted file mode 100644
index e616a807a38..00000000000
--- a/mysql-test/suite/sys_vars/t/ndb_log_update_as_write_basic.test
+++ /dev/null
@@ -1,216 +0,0 @@
-############## mysql-test\t\ndb_log_update_as_write_basic.test ###############
-# #
-# Variable Name: ndb_log_update_as_write #
-# Scope: GLOBAL #
-# Access Type: Dynamic #
-# Data Type: boolean #
-# Default Value: #
-# Range: #
-# #
-# #
-# Creation Date: 2008-02-07 #
-# Author: Rizwan #
-# #
-# Description: Test Cases of Dynamic System Variable ndb_log_update_as_write #
-# that checks the behavior of this variable in the following ways#
-# * Default Value #
-# * Valid & Invalid values #
-# * Scope & Access method #
-# * Data Integrity #
-# #
-# Reference: http://dev.mysql.com/doc/refman/5.1/en/ #
-# server-system-variables.html #
-# #
-###############################################################################
-############## mysql-test\t\ndb_log_update_as_write_basic.test ################
-# #
-# Variable Name: ndb_log_update_as_write #
-# Scope: GLOBAL & SESSION #
-# Access Type: Dynamic #
-# Data Type: Numeric #
-# Default Value: 1 #
-# Range: 1 - 65536 #
-# #
-# #
-# Creation Date: 2008-02-07 #
-# Author: Rizwan Maredia #
-# #
-# Description: Test Cases of Dynamic System Variable ndb_log_update_as_write #
-# that checks the behavior of this variable in the following ways #
-# * Default Value #
-# * Valid & Invalid values #
-# * Scope & Access method #
-# * Data Integrity #
-# #
-# Reference: http://dev.mysql.com/doc/refman/5.1/en/ #
-# server-system-variables.html #
-# #
-################################################################################
-################# mysql-test\t\ndb_log_update_as_write_basic.test ######
-# #
-# #
-# Creation Date: 2008-02-07 #
-# Author: Rizwan Maredia #
-# #
-# Description: Test Cases of Dynamic System Variable #
-# ndb_log_update_as_write that check behavior of this #
-# variable with valid values, invalid values, #
-# accessing variable with scope that is #
-# allowed and with scope that is now allowed. #
-# Scope: Global #
-# Reference: http://dev.mysql.com/doc/refman/5.1/en/server-system #
-# -variables.html #
-# #
-########################################################################
-
---source include/load_sysvars.inc
-
-########################################################################
-# START OF ndb_log_update_as_write TESTS #
-########################################################################
-
-
-################################################################################
-# Saving initial value of ndb_log_update_as_write in a temporary variable #
-################################################################################
-
-
---Error ER_UNKNOWN_SYSTEM_VARIABLE
-SET @global_start_value = @@global.ndb_log_update_as_write;
---Error ER_UNKNOWN_SYSTEM_VARIABLE
-SELECT @@global.ndb_log_update_as_write;
-
---echo 'Bug: The value is not a system variable or atleast not supported in version 5.1.22'
-
-
---echo '#--------------------FN_DYNVARS_102_01------------------------#'
-########################################################################
-# Display the DEFAULT value of ndb_log_update_as_write #
-########################################################################
-
-#SET @@ndb_log_update_as_write = 0;
-#SET @@ndb_log_update_as_write = DEFAULT;
-#SELECT @@ndb_log_update_as_write;
-#
-#SET @@ndb_log_update_as_write = 1;
-#SET @@ndb_log_update_as_write = DEFAULT;
-#SELECT @@ndb_log_update_as_write;
-
-
---echo '#---------------------FN_DYNVARS_102_02-------------------------#'
-#############################################################################
-# Check if ndb_log_update_as_write can be accessed with and without @@ sign #
-#############################################################################
-
-#SET ndb_log_update_as_write = 1;
-#SELECT @@ndb_log_update_as_write;
-#--Error ER_UNKNOWN_TABLE
-#SELECT global.ndb_log_update_as_write;
-#
-#SET global ndb_log_update_as_write = 1;
-#SELECT @@global.ndb_log_update_as_write;
-
-
---echo '#--------------------FN_DYNVARS_102_03------------------------#'
-########################################################################
-# Change the value of ndb_log_update_as_write to a valid value #
-########################################################################
-
-#SET @@global.ndb_log_update_as_write = 0;
-#SELECT @@global.ndb_log_update_as_write;
-#SET @@global.ndb_log_update_as_write = 1;
-#SELECT @@global.ndb_log_update_as_write;
-## a value of 2 is used to just flush logs and then shutdown cold.
-#SET @@global.ndb_log_update_as_write = 2;
-#SELECT @@global.ndb_log_update_as_write;
-
---echo '#--------------------FN_DYNVARS_102_04-------------------------#'
-###########################################################################
-# Change the value of ndb_log_update_as_write to invalid value #
-###########################################################################
-
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_update_as_write = -1;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_update_as_write = TRU;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_update_as_write = TRUE_F;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_update_as_write = FALS;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_update_as_write = OON;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_update_as_write = ONN;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_update_as_write = OOFF;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_update_as_write = 0FF;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_update_as_write = ' 1';
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_update_as_write = "0 ";
-
-
-
---echo '#-------------------FN_DYNVARS_102_05----------------------------#'
-###########################################################################
-# Test if accessing session ndb_log_update_as_write gives error #
-###########################################################################
-
-#--Error ER_LOCAL_VARIABLE
-#SET @@session.ndb_log_update_as_write = 0;
-#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
-#SET @@ndb_log_update_as_write = 0;
-#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
-#SET @@local.ndb_log_update_as_write = 0;
-#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
-#SELECT @@session.ndb_log_update_as_write;
-#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
-#SELECT @@local.ndb_log_update_as_write;
-
---echo '#----------------------FN_DYNVARS_102_06------------------------#'
-#########################################################################
-# Check if the value in SESSION Table contains variable value #
-#########################################################################
-
-#SELECT count(VARIABLE_VALUE) AS res_is_0 FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='ndb_log_update_as_write';
-
-
---echo '#----------------------FN_DYNVARS_102_07------------------------#'
-#########################################################################
-# Check if the value in GLOBAL Table matches value in variable #
-#########################################################################
-
-#SELECT @@global.ndb_log_update_as_write = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='ndb_log_update_as_write';
-
-
---echo '#---------------------FN_DYNVARS_102_08-------------------------#'
-###################################################################
-# Check if ON and OFF values can be used on variable #
-###################################################################
-
-#SET @@ndb_log_update_as_write = OFF;
-#SELECT @@ndb_log_update_as_write;
-#SET @@ndb_log_update_as_write = ON;
-#SELECT @@ndb_log_update_as_write;
-
---echo '#---------------------FN_DYNVARS_102_09----------------------#'
-###################################################################
-# Check if TRUE and FALSE values can be used on variable #
-###################################################################
-
-#SET @@ndb_log_update_as_write = TRUE;
-#SELECT @@ndb_log_update_as_write;
-#SET @@ndb_log_update_as_write = 'FALSE';
-#SELECT @@ndb_log_update_as_write;
-
-##############################
-# Restore initial value #
-##############################
-
-#SET @@ndb_log_update_as_write = @global_start_value;
-#SELECT @@ndb_log_update_as_write;
-
-########################################################################
-# END OF ndb_log_update_as_write TESTS #
-########################################################################
diff --git a/mysql-test/suite/sys_vars/t/ndb_log_updated_only_basic.test b/mysql-test/suite/sys_vars/t/ndb_log_updated_only_basic.test
deleted file mode 100644
index c00ecf2e2fa..00000000000
--- a/mysql-test/suite/sys_vars/t/ndb_log_updated_only_basic.test
+++ /dev/null
@@ -1,216 +0,0 @@
-############## mysql-test\t\ndb_log_updated_only_basic.test ###############
-# #
-# Variable Name: ndb_log_updated_only #
-# Scope: GLOBAL #
-# Access Type: Dynamic #
-# Data Type: boolean #
-# Default Value: #
-# Range: #
-# #
-# #
-# Creation Date: 2008-02-07 #
-# Author: Rizwan #
-# #
-# Description: Test Cases of Dynamic System Variable ndb_log_updated_only #
-# that checks the behavior of this variable in the following ways#
-# * Default Value #
-# * Valid & Invalid values #
-# * Scope & Access method #
-# * Data Integrity #
-# #
-# Reference: http://dev.mysql.com/doc/refman/5.1/en/ #
-# server-system-variables.html #
-# #
-###############################################################################
-############## mysql-test\t\ndb_log_updated_only_basic.test ################
-# #
-# Variable Name: ndb_log_updated_only #
-# Scope: GLOBAL & SESSION #
-# Access Type: Dynamic #
-# Data Type: Numeric #
-# Default Value: 1 #
-# Range: 1 - 65536 #
-# #
-# #
-# Creation Date: 2008-02-07 #
-# Author: Rizwan Maredia #
-# #
-# Description: Test Cases of Dynamic System Variable ndb_log_updated_only #
-# that checks the behavior of this variable in the following ways #
-# * Default Value #
-# * Valid & Invalid values #
-# * Scope & Access method #
-# * Data Integrity #
-# #
-# Reference: http://dev.mysql.com/doc/refman/5.1/en/ #
-# server-system-variables.html #
-# #
-################################################################################
-################# mysql-test\t\ndb_log_updated_only_basic.test #########
-# #
-# #
-# Creation Date: 2008-02-07 #
-# Author: Rizwan Maredia #
-# #
-# Description: Test Cases of Dynamic System Variable #
-# ndb_log_updated_only that check behavior of this #
-# variable with valid values, invalid values, #
-# accessing variable with scope that is #
-# allowed and with scope that is now allowed. #
-# Scope: Global #
-# Reference: http://dev.mysql.com/doc/refman/5.1/en/server-system #
-# -variables.html #
-# #
-########################################################################
-
---source include/load_sysvars.inc
-
-########################################################################
-# START OF ndb_log_updated_only TESTS #
-########################################################################
-
-
-################################################################################
-# Saving initial value of ndb_log_updated_only in a temporary variable #
-################################################################################
-
-
---Error ER_UNKNOWN_SYSTEM_VARIABLE
-SET @global_start_value = @@global.ndb_log_updated_only;
---Error ER_UNKNOWN_SYSTEM_VARIABLE
-SELECT @@global.ndb_log_updated_only;
-
---echo 'Bug: The value is not a system variable or atleast not supported in version 5.1.22'
-
-
---echo '#--------------------FN_DYNVARS_103_01------------------------#'
-########################################################################
-# Display the DEFAULT value of ndb_log_updated_only #
-########################################################################
-
-#SET @@ndb_log_updated_only = 0;
-#SET @@ndb_log_updated_only = DEFAULT;
-#SELECT @@ndb_log_updated_only;
-#
-#SET @@ndb_log_updated_only = 1;
-#SET @@ndb_log_updated_only = DEFAULT;
-#SELECT @@ndb_log_updated_only;
-
-
---echo '#---------------------FN_DYNVARS_103_02-------------------------#'
-#############################################################################
-# Check if ndb_log_updated_only can be accessed with and without @@ sign #
-#############################################################################
-
-#SET ndb_log_updated_only = 1;
-#SELECT @@ndb_log_updated_only;
-#--Error ER_UNKNOWN_TABLE
-#SELECT global.ndb_log_updated_only;
-#
-#SET global ndb_log_updated_only = 1;
-#SELECT @@global.ndb_log_updated_only;
-
-
---echo '#--------------------FN_DYNVARS_103_03------------------------#'
-########################################################################
-# Change the value of ndb_log_updated_only to a valid value #
-########################################################################
-
-#SET @@global.ndb_log_updated_only = 0;
-#SELECT @@global.ndb_log_updated_only;
-#SET @@global.ndb_log_updated_only = 1;
-#SELECT @@global.ndb_log_updated_only;
-## a value of 2 is used to just flush logs and then shutdown cold.
-#SET @@global.ndb_log_updated_only = 2;
-#SELECT @@global.ndb_log_updated_only;
-
---echo '#--------------------FN_DYNVARS_103_04-------------------------#'
-###########################################################################
-# Change the value of ndb_log_updated_only to invalid value #
-###########################################################################
-
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_updated_only = -1;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_updated_only = TRU;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_updated_only = TRUE_F;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_updated_only = FALS;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_updated_only = OON;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_updated_only = ONN;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_updated_only = OOFF;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_updated_only = 0FF;
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_updated_only = ' 1';
-#--Error ER_WRONG_VALUE_FOR_VAR
-#SET @@global.ndb_log_updated_only = "0 ";
-
-
-
---echo '#-------------------FN_DYNVARS_103_05----------------------------#'
-###########################################################################
-# Test if accessing session ndb_log_updated_only gives error #
-###########################################################################
-
-#--Error ER_LOCAL_VARIABLE
-#SET @@session.ndb_log_updated_only = 0;
-#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
-#SET @@ndb_log_updated_only = 0;
-#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
-#SET @@local.ndb_log_updated_only = 0;
-#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
-#SELECT @@session.ndb_log_updated_only;
-#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
-#SELECT @@local.ndb_log_updated_only;
-
---echo '#----------------------FN_DYNVARS_103_06------------------------#'
-#########################################################################
-# Check if the value in SESSION Table contains variable value #
-#########################################################################
-
-#SELECT count(VARIABLE_VALUE) AS res_is_0 FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='ndb_log_updated_only';
-
-
---echo '#----------------------FN_DYNVARS_103_07------------------------#'
-#########################################################################
-# Check if the value in GLOBAL Table matches value in variable #
-#########################################################################
-
-#SELECT @@global.ndb_log_updated_only = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='ndb_log_updated_only';
-
-
---echo '#---------------------FN_DYNVARS_103_08-------------------------#'
-###################################################################
-# Check if ON and OFF values can be used on variable #
-###################################################################
-
-#SET @@ndb_log_updated_only = OFF;
-#SELECT @@ndb_log_updated_only;
-#SET @@ndb_log_updated_only = ON;
-#SELECT @@ndb_log_updated_only;
-
---echo '#---------------------FN_DYNVARS_103_09----------------------#'
-###################################################################
-# Check if TRUE and FALSE values can be used on variable #
-###################################################################
-
-#SET @@ndb_log_updated_only = TRUE;
-#SELECT @@ndb_log_updated_only;
-#SET @@ndb_log_updated_only = 'FALSE';
-#SELECT @@ndb_log_updated_only;
-
-##############################
-# Restore initial value #
-##############################
-
-#SET @@ndb_log_updated_only = @global_start_value;
-#SELECT @@ndb_log_updated_only;
-
-########################################################################
-# END OF ndb_log_updated_only TESTS #
-########################################################################
diff --git a/mysql-test/suite/sys_vars/t/pseudo_slave_mode_basic.test b/mysql-test/suite/sys_vars/t/pseudo_slave_mode_basic.test
new file mode 100644
index 00000000000..3ef39bb8667
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/pseudo_slave_mode_basic.test
@@ -0,0 +1,168 @@
+####################### mysql-test\t\pseudo_slave_mode_basic.test ###################
+# #
+# Variable Name: pseudo_slave_mode #
+# Scope: SESSION #
+# Access Type: Dynamic #
+# Data Type: boolean #
+# Default Value: #
+# Valid Values: 0,1 #
+# #
+# #
+# Creation Date: 2012-11-16 #
+# #
+# Description: Test Cases of Dynamic System Variable pseudo_slave_mode #
+# that checks the behavior of this variable in the following ways#
+# * Default Value #
+# * Valid & Invalid values #
+# * Scope & Access method #
+# * Data Integrity #
+# #
+# Reference: http://dev.mysql.com/doc/refman/5.5/en/ #
+# server-system-variables.html #
+# #
+###############################################################################
+
+--source include/load_sysvars.inc
+
+########################################################################
+# START OF pseudo_slave_mode TESTS #
+########################################################################
+
+
+##############################################################################
+# Saving initial value of pseudo_slave_mode in a temporary variable #
+##############################################################################
+
+SET @session_start_value = @@session.pseudo_slave_mode;
+SELECT @session_start_value;
+
+--echo '#--------------------FN_DYNVARS_156_01------------------------#'
+########################################################################
+# Display the DEFAULT value of pseudo_slave_mode #
+########################################################################
+
+SET @@session.pseudo_slave_mode = 0;
+SET @@session.pseudo_slave_mode = DEFAULT;
+SELECT @@session.pseudo_slave_mode;
+
+SET @@session.pseudo_slave_mode = 1;
+SET @@session.pseudo_slave_mode = DEFAULT;
+SELECT @@session.pseudo_slave_mode;
+
+
+--echo '#---------------------FN_DYNVARS_156_02-------------------------#'
+#############################################################################
+# Check if pseudo_slave_mode can be accessed with and without @@ sign #
+#############################################################################
+
+SET pseudo_slave_mode = 1;
+SELECT @@pseudo_slave_mode;
+
+--Error ER_UNKNOWN_TABLE
+SELECT session.pseudo_slave_mode;
+
+--Error ER_UNKNOWN_TABLE
+SELECT local.pseudo_slave_mode;
+
+SET session pseudo_slave_mode = 0;
+SELECT @@session.pseudo_slave_mode;
+
+
+--echo '#--------------------FN_DYNVARS_156_03------------------------#'
+########################################################################
+# change the value of pseudo_slave_mode to a valid value #
+########################################################################
+
+SET @@session.pseudo_slave_mode = 0;
+SELECT @@session.pseudo_slave_mode;
+SET @@session.pseudo_slave_mode = 1;
+SELECT @@session.pseudo_slave_mode;
+
+
+--echo '#--------------------FN_DYNVARS_156_04-------------------------#'
+###########################################################################
+# Change the value of pseudo_slave_mode to invalid value #
+###########################################################################
+
+--Error ER_WRONG_VALUE_FOR_VAR
+SET @@session.pseudo_slave_mode = -1;
+--Error ER_WRONG_VALUE_FOR_VAR
+SET @@session.pseudo_slave_mode = 2;
+--Error ER_WRONG_VALUE_FOR_VAR
+SET @@session.pseudo_slave_mode = "T";
+--Error ER_WRONG_VALUE_FOR_VAR
+SET @@session.pseudo_slave_mode = "Y";
+--Error ER_WRONG_VALUE_FOR_VAR
+SET @@session.pseudo_slave_mode = TRÜE;
+--Error ER_WRONG_VALUE_FOR_VAR
+SET @@session.pseudo_slave_mode = ÕN;
+--Error ER_WRONG_VALUE_FOR_VAR
+SET @@session.pseudo_slave_mode = OF;
+--Error ER_WRONG_VALUE_FOR_VAR
+SET @@session.pseudo_slave_mode = ÓFF;
+--Error ER_WRONG_VALUE_FOR_VAR
+SET @@session.pseudo_slave_mode = '¹';
+--Error ER_WRONG_VALUE_FOR_VAR
+SET @@session.pseudo_slave_mode = NO;
+
+
+--echo '#-------------------FN_DYNVARS_156_05----------------------------#'
+###########################################################################
+# Test if accessing global pseudo_slave_mode gives error #
+###########################################################################
+
+--error ER_LOCAL_VARIABLE
+SET @@global.pseudo_slave_mode = 0;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@global.pseudo_slave_mode;
+
+--echo '#----------------------FN_DYNVARS_156_06------------------------#'
+#########################################################################
+# Check if the value in SESSION Table contains variable value #
+#########################################################################
+
+SELECT count(VARIABLE_VALUE) FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='pseudo_slave_mode';
+
+--echo '#----------------------FN_DYNVARS_156_07------------------------#'
+#########################################################################
+# Check if the value in SESSION Table matches value in variable #
+#########################################################################
+
+SELECT IF(@@session.pseudo_slave_mode, "ON", "OFF") = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='pseudo_slave_mode';
+SELECT @@session.pseudo_slave_mode;
+SELECT VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='pseudo_slave_mode';
+
+--echo '#---------------------FN_DYNVARS_156_08-------------------------#'
+###################################################################
+# Check if ON and OFF values can be used on variable #
+###################################################################
+
+SET @@session.pseudo_slave_mode = OFF;
+SELECT @@session.pseudo_slave_mode;
+SET @@session.pseudo_slave_mode = ON;
+SELECT @@session.pseudo_slave_mode;
+
+--echo '#---------------------FN_DYNVARS_156_09----------------------#'
+###################################################################
+# Check if TRUE and FALSE values can be used on variable #
+###################################################################
+
+SET @@session.pseudo_slave_mode = TRUE;
+SELECT @@session.pseudo_slave_mode;
+SET @@session.pseudo_slave_mode = FALSE;
+SELECT @@session.pseudo_slave_mode;
+
+##############################
+# Restore initial value #
+##############################
+
+SET @@session.pseudo_slave_mode = @session_start_value;
+SELECT @@session.pseudo_slave_mode;
+
+###############################################################
+# END OF pseudo_slave_mode TESTS #
+###############################################################
diff --git a/mysql-test/t/bug13633383.test b/mysql-test/t/bug13633383.test
index 72eb2f81c98..e31d4a8c9f6 100644
--- a/mysql-test/t/bug13633383.test
+++ b/mysql-test/t/bug13633383.test
@@ -5,19 +5,19 @@
CREATE TABLE t1 (
`a` int(11) DEFAULT NULL,
`col432` bit(8) DEFAULT NULL,
- `col433` multipoint DEFAULT NULL,
- `col434` polygon DEFAULT NULL,
+ `col433` geometry DEFAULT NULL,
+ `col434` geometry DEFAULT NULL,
`col435` decimal(50,17) unsigned DEFAULT NULL,
`col436` geometry NOT NULL,
`col437` tinyblob NOT NULL,
- `col438` multipolygon DEFAULT NULL,
+ `col438` geometry DEFAULT NULL,
`col439` mediumblob NOT NULL,
`col440` tinyblob NOT NULL,
`col441` double unsigned DEFAULT NULL
);
CREATE TABLE t2 (
- `a` multipoint DEFAULT NULL,
+ `a` geometry DEFAULT NULL,
`col460` date DEFAULT NULL,
`col461` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`col462` date NOT NULL,
@@ -34,7 +34,7 @@ CREATE TABLE t3 (
`col579` bit(38) NOT NULL,
`col580` varchar(93) NOT NULL,
`col581` datetime DEFAULT NULL,
- `col583` multipolygon DEFAULT NULL,
+ `col583` geometry DEFAULT NULL,
`col584` bit(47) NOT NULL
);
diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test
index 4cf5cccc254..381c87c635c 100644
--- a/mysql-test/t/derived.test
+++ b/mysql-test/t/derived.test
@@ -343,3 +343,18 @@ SELECT 1 FROM t1 JOIN v1 ON 1 > (SELECT 1 FROM v2);
DROP TABLE t1, t2;
DROP VIEW v1, v2;
set optimizer_switch=@save_derived_optimizer_switch;
+
+#
+# MDEV-614 lp:1050806 - different result for a query using subquery between 5.5.25 and 5.5.27
+# MySQL Bug#66845 Wrong result (extra row) on a FROM subquery with a variable and ORDER BY
+#
+create table t1 (n bigint(20) unsigned, d1 datetime, d2 datetime, key (d1));
+insert t1 values (2085,'2012-01-01 00:00:00','2013-01-01 00:00:00');
+insert t1 values (2084,'2012-02-01 00:00:00','2013-01-01 00:00:00');
+insert t1 values (2088,'2012-03-01 00:00:00','2013-01-01 00:00:00');
+select * from (
+ select n, d1, d2, @result := 0 as result
+ from t1
+ where d1 < '2012-12-12 12:12:12' and n in (2085, 2084) order by d2 asc
+) as calculated_result;
+drop table t1;
diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test
index c7705294ef2..4b7e76e11ca 100644
--- a/mysql-test/t/derived_view.test
+++ b/mysql-test/t/derived_view.test
@@ -1512,6 +1512,40 @@ set optimizer_switch=@save3912_optimizer_switch;
drop table t1, t2, t3;
--echo #
+--echo # MDEV-4209: equi-join on BLOB column from materialized view
+--echo # or derived table
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_with_keys=on';
+
+CREATE TABLE t1 (c1 text, c2 int);
+INSERT INTO t1 VALUES ('a',1), ('c',3), ('g',7), ('d',4), ('c',3);
+CREATE TABLE t2 (c1 text, c2 int);
+INSERT INTO t2 VALUES ('b',2), ('c',3);
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+
+EXPLAIN EXTENDED
+SELECT v1.c1, v1.c2 FROM v1, t2 WHERE v1.c1=t2.c1 AND v1.c2=t2.c2;
+SELECT v1.c1, v1.c2 FROM v1, t2 WHERE v1.c1=t2.c1 AND v1.c2=t2.c2;
+
+EXPLAIN EXTENDED
+SELECT t2.c1, t2.c2 FROM (SELECT c1 g, MAX(c2) m FROM t1 GROUP BY c1) t, t2
+ WHERE t.g=t2.c1 AND t.m=t2.c2;
+SELECT t2.c1, t2.c2 FROM (SELECT c1 g, MAX(c2) m FROM t1 GROUP BY c1) t, t2
+ WHERE t.g=t2.c1 AND t.m=t2.c2;
+
+EXPLAIN EXTENDED
+SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1;
+SELECT v1.c1, v1.c2, t2.c1, t2.c2 FROM v1, t2 WHERE v1.c1=t2.c1;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+set optimizer_switch=@save_optimizer_switch;
+
+
+--echo #
--echo # end of 5.3 tests
--echo #
diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test
index e7e6fa59df0..731efe5648e 100644
--- a/mysql-test/t/gis-rtree.test
+++ b/mysql-test/t/gis-rtree.test
@@ -120,7 +120,7 @@ INSERT INTO t1 (g) VALUES (GeomFromText('LineString(1 2, 2 3)')),(GeomFromText('
drop table t1;
CREATE TABLE t1 (
- line LINESTRING NOT NULL,
+ line GEOMETRY NOT NULL,
kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po',
name VARCHAR(32),
@@ -935,7 +935,7 @@ DROP TABLE t1;
--echo # and invalid spatial data
--echo #
-CREATE TABLE t1(a LINESTRING NOT NULL, b GEOMETRY NOT NULL,
+CREATE TABLE t1(a POINT NOT NULL, b GEOMETRY NOT NULL,
SPATIAL KEY(a), SPATIAL KEY(b)) ENGINE=MyISAM;
INSERT INTO t1 VALUES(GEOMFROMTEXT("point (0 0)"), GEOMFROMTEXT("point (1 1)"));
--error ER_CANT_CREATE_GEOMETRY_OBJECT
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index b0ad8329cfb..190445e9c09 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -741,7 +741,7 @@ SET @a=POLYFROMWKB(@a);
# Bug #57321 crashes and valgrind errors from spatial types
#
-create table t1(a polygon NOT NULL)engine=myisam;
+create table t1(a geometry NOT NULL)engine=myisam;
insert into t1 values (geomfromtext("point(0 1)"));
insert into t1 values (geomfromtext("point(1 0)"));
select * from (select polygon(t1.a) as p from t1 order by t1.a) d;
@@ -1358,4 +1358,20 @@ SELECT 1 FROM g1 WHERE a >= ANY
DROP TABLE g1;
+--echo #
+--echo # MDEV-3819 missing constraints for spatial column types
+--echo #
+
+create table t1 (pt point);
+--error ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
+insert into t1 values(Geomfromtext('POLYGON((1 1, 2 2, 2 1, 1 1))'));
+drop table t1;
+
+--echo #
+--echo # TODO-424 geometry query crashes server
+--echo #
+select astext(0x0100000000030000000100000000000010);
+select st_area(0x0100000000030000000100000000000010);
+select astext(st_exteriorring(0x0100000000030000000100000000000010));
+select astext(st_centroid(0x0100000000030000000100000000000010));
--echo End of 5.5 tests
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index a90fcba77fc..4b7a475eb28 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -1322,6 +1322,80 @@ SELECT 1 FROM t1 GROUP BY SUBSTRING(SYSDATE() FROM 'K' FOR 'jxW<');
DROP TABLE t1;
SET SQL_BIG_TABLES=0;
+--echo #
+--echo # MDEV-641 LP:1002108 - Wrong result (or crash) from a query with duplicated field in the group list and a limit clause
+--echo # Bug#11761078: 53534: INCORRECT 'SELECT SQL_BIG_RESULT...'
+--echo # WITH GROUP BY ON DUPLICATED FIELDS
+--echo #
+
+CREATE TABLE t1(
+ col1 int,
+ UNIQUE INDEX idx (col1));
+
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),
+ (11),(12),(13),(14),(15),(16),(17),(18),(19),(20);
+
+let $query0=SELECT col1 AS field1, col1 AS field2
+ FROM t1 GROUP BY field1, field2;
+
+# Needs to be range to exercise bug
+--eval EXPLAIN $query0;
+FLUSH STATUS;
+--eval $query0;
+SHOW SESSION STATUS LIKE 'Sort_scan%';
+
+let $query=SELECT SQL_BIG_RESULT col1 AS field1, col1 AS field2
+ FROM t1 GROUP BY field1, field2;
+
+# Needs to be range to exercise bug
+--eval EXPLAIN $query;
+FLUSH STATUS;
+--eval $query;
+SHOW SESSION STATUS LIKE 'Sort_scan%';
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT SQL_BIG_RESULT col1 AS field1, col1 AS field2
+FROM v1
+GROUP BY field1, field2;
+
+SELECT SQL_BIG_RESULT tbl1.col1 AS field1, tbl2.col1 AS field2
+FROM t1 as tbl1, t1 as tbl2
+GROUP BY field1, field2
+LIMIT 3;
+
+explain
+select col1 f1, col1 f2 from t1 order by f2, f1;
+select col1 f1, col1 f2 from t1 order by f2, f1;
+
+explain
+select col1 f1, col1 f2 from t1 group by f2 order by f2, f1;
+select col1 f1, col1 f2 from t1 group by f2 order by f2, f1;
+
+explain
+select col1 f1, col1 f2 from t1 group by f1, f2 order by f2, f1;
+select col1 f1, col1 f2 from t1 group by f1, f2 order by f2, f1;
+
+CREATE TABLE t2(
+ col1 int,
+ col2 int,
+ UNIQUE INDEX idx (col1, col2));
+
+INSERT INTO t2(col1, col2) VALUES
+ (1,20),(2,19),(3,18),(4,17),(5,16),(6,15),(7,14),(8,13),(9,12),(10,11),
+ (11,10),(12,9),(13,8),(14,7),(15,6),(16,5),(17,4),(18,3),(19,2),(20,1);
+
+explain
+select col1 f1, col2 f2, col1 f3 from t2 group by f1, f2, f3;
+select col1 f1, col2 f2, col1 f3 from t2 group by f1, f2, f3;
+
+explain
+select col1 f1, col2 f2, col1 f3 from t2 order by f1, f2, f3;
+select col1 f1, col2 f2, col1 f3 from t2 order by f1, f2, f3;
+
+DROP VIEW v1;
+DROP TABLE t1, t2;
+
--echo # End of 5.1 tests
--echo #
diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
index 19f7cbe40a1..82097c53fe0 100644
--- a/mysql-test/t/group_min_max.test
+++ b/mysql-test/t/group_min_max.test
@@ -1204,6 +1204,64 @@ drop table t1;
--echo End of 5.1 tests
+--echo #
+--echo # MDEV-765 lp:825075 - Wrong result with GROUP BY + multipart key + MIN/MAX loose scan
+--echo #
+
+CREATE TABLE t1 (a varchar(1), b varchar(1), KEY (b,a));
+INSERT INTO t1 VALUES
+('0',NULL),('9',NULL),('8','c'),('4','d'),('7','d'),(NULL,'f'),
+('7','f'),('8','g'),(NULL,'j');
+
+explain
+SELECT max(a) , b FROM t1 WHERE a IS NULL OR b = 'z' GROUP BY b;
+SELECT max(a) , b FROM t1 WHERE a IS NULL OR b = 'z' GROUP BY b;
+
+explain
+SELECT b, min(a) FROM t1 WHERE a = '7' OR b = 'z' GROUP BY b;
+SELECT b, min(a) FROM t1 WHERE a = '7' OR b = 'z' GROUP BY b;
+
+explain
+SELECT b, min(a) FROM t1 WHERE (a = b OR b = 'd' OR b is NULL) GROUP BY b;
+SELECT b, min(a) FROM t1 WHERE (a = b OR b = 'd' OR b is NULL) GROUP BY b;
+
+explain
+SELECT b, min(a) FROM t1 WHERE a > ('0' = b) AND b = 'z' GROUP BY b;
+SELECT b, min(a) FROM t1 WHERE a > ('0' = b) AND b = 'z' GROUP BY b;
+
+explain
+SELECT b, min(a) FROM t1 WHERE a > '0' AND (b < (a = '7')) GROUP BY b;
+SELECT b, min(a) FROM t1 WHERE a > '0' AND (b < (a = '7')) GROUP BY b;
+
+explain
+SELECT b, min(a) FROM t1 WHERE (a > '0' AND (a > '1' OR b = 'd')) GROUP BY b;
+SELECT b, min(a) FROM t1 WHERE (a > '0' AND (a > '1' OR b = 'd')) GROUP BY b;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-4140 Wrong result with GROUP BY + multipart key + MIN/MAX loose scan and a subquery
+--echo #
+
+CREATE TABLE t1 (a int, b int, KEY (b, a)) ;
+INSERT INTO t1 VALUES (0,99),(9,99),(4,0),(7,0),(99,0),(7,0),(8,0),(99,0),(1,0);
+CREATE TABLE t2 (c int) ;
+INSERT INTO t2 VALUES (0),(1);
+
+EXPLAIN
+SELECT MIN(a), b FROM t1 WHERE a > 0 GROUP BY b;
+SELECT MIN(a), b FROM t1 WHERE a > 0 GROUP BY b;
+EXPLAIN
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT c FROM t2 WHERE c = 0 ) GROUP BY b;
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT c FROM t2 WHERE c = 0 ) GROUP BY b;
+# this test is for 5.5 to ensure that the subquery is expensive
+EXPLAIN
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT min(c) FROM t2, t1 t1a, t1 t1b WHERE c = 0 ) GROUP BY b;
+SELECT MIN(a), b FROM t1 WHERE a > ( SELECT min(c) FROM t2, t1 t1a, t1 t1b WHERE c = 0 ) GROUP BY b;
+
+drop table t1, t2;
+
+--echo End of 5.3 tests
--echo #
--echo # WL#3220 (Loose index scan for COUNT DISTINCT)
@@ -1342,4 +1400,3 @@ explain SELECT f1, COUNT(DISTINCT f2) FROM t1 GROUP BY f1;
drop table t1;
--echo # End of test#50539.
-
diff --git a/mysql-test/t/information_schema_all_engines-master.opt b/mysql-test/t/information_schema_all_engines-master.opt
index 085c81d34bb..0a9fa574e49 100644
--- a/mysql-test/t/information_schema_all_engines-master.opt
+++ b/mysql-test/t/information_schema_all_engines-master.opt
@@ -2,9 +2,10 @@
--loose-innodb-buffer-pool-pages
--loose-innodb-buffer-pool-pages-blob
--loose-innodb-buffer-pool-pages-index
+--loose-innodb-changed-pages
--loose-innodb-cmp
---loose-innodb-cmpmem-reset
--loose-innodb-cmp-reset
+--loose-innodb-cmpmem-reset
--loose-innodb-index-stats
--loose-innodb-lock-waits
--loose-innodb-rseg
diff --git a/mysql-test/t/innodb_ext_key.test b/mysql-test/t/innodb_ext_key.test
index 3e82403ddb5..31c6fca2b95 100644
--- a/mysql-test/t/innodb_ext_key.test
+++ b/mysql-test/t/innodb_ext_key.test
@@ -414,6 +414,7 @@ INSERT INTO t1 (a) VALUES (4), (6);
INSERT INTO t2 (b) VALUES (0), (8);
set @save_optimizer_switch=@@optimizer_switch;
+set @save_join_cache_level=@@join_cache_level;
SET join_cache_level=3;
SET optimizer_switch='join_cache_hashed=on';
@@ -424,6 +425,7 @@ EXPLAIN
SELECT * FROM t1, t2 WHERE b=a;
SELECT * FROM t1, t2 WHERE b=a;
+set join_cache_level=@save_join_cache_level;
set optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2;
@@ -466,6 +468,78 @@ set optimizer_switch=@save_optimizer_switch;
DROP TABLE t1;
+--echo #
+--echo # Bug mdev-4220: using ref instead of eq_ref
+--echo # with extended_keys=on
+--echo # (performance regression introduced in the patch for mdev-3851)
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+create table t1 (a int not null) engine=innodb;
+
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t2 (
+ pk int primary key, a int not null, b int, unique(a)
+)engine=innodb;
+
+insert into t2
+select
+ A.a + 10 * B.a, A.a + 10 * B.a, A.a + 10 * B.a
+from t1 A, t1 B;
+
+set optimizer_switch='extended_keys=off';
+explain
+select * from t1, t2 where t2.a=t1.a and t2.b < 2;
+flush status;
+select * from t1, t2 where t2.a=t1.a and t2.b < 2;
+show status like 'handler_read%';
+
+set optimizer_switch='extended_keys=on';
+explain
+select * from t1, t2 where t2.a=t1.a and t2.b < 2;
+flush status;
+select * from t1, t2 where t2.a=t1.a and t2.b < 2;
+show status like 'handler_read%';
+
+drop table t1,t2;
+
+# this test case did not demonstrate any regression
+# it is added for better testing
+
+create table t1(a int) engine=myisam;
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t2(a int) engine=myisam;
+insert into t2 select A.a + 10*B.a + 100*C.a from t1 A, t1 B, t1 C;
+
+create table t3 (
+ pk1 int not null, pk2 int not null, col1 int not null, col2 int not null)
+engine=innodb;
+insert into t3 select a,a,a,a from t2;
+alter table t3 add primary key (pk1, pk2);
+alter table t3 add key (col1, col2);
+
+set optimizer_switch='extended_keys=off';
+--replace_column 9 #
+explain
+select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a;
+--replace_column 9 #
+explain
+select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a;
+
+set optimizer_switch='extended_keys=on';
+--replace_column 9 #
+explain
+select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a;
+--replace_column 9 #
+explain
+select * from t1, t3 where t3.col1=t1.a and t3.col2=t1.a and t3.pk1=t1.a;
+
+drop table t1,t2,t3;
+
+set optimizer_switch=@save_optimizer_switch;
+
set optimizer_switch=@save_ext_key_optimizer_switch;
SET SESSION STORAGE_ENGINE=DEFAULT;
-
diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test
index 9b04c264faf..2d06c3e2a30 100644
--- a/mysql-test/t/join_cache.test
+++ b/mysql-test/t/join_cache.test
@@ -3594,7 +3594,7 @@ DROP TABLE t1,t2,t3;
CREATE TABLE t1 (
col269 decimal(31,10) unsigned DEFAULT NULL,
- col280 multipoint DEFAULT NULL,
+ col280 geometry DEFAULT NULL,
col281 tinyint(1) DEFAULT NULL,
col282 time NOT NULL,
col284 datetime DEFAULT NULL,
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
index 48735304aad..e0a35ca2bb9 100644
--- a/mysql-test/t/multi_update.test
+++ b/mysql-test/t/multi_update.test
@@ -696,6 +696,55 @@ DROP FUNCTION f1;
DROP TABLE t1;
--echo #
+--echo # MDEV-4123: Incorrect results after multi-table update or
+--echo # assertion `!table || (!table->read_set ||
+--echo # bitmap_is_set(table->read_set, field_index))' failure
+--echo #
+
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (
+ id int(10) unsigned NOT NULL,
+ level tinyint(3) unsigned NOT NULL,
+ PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES (2519583,1);
+
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t2 (
+ club_id int(11) NOT NULL DEFAULT '0',
+ profile_id int(11) NOT NULL DEFAULT '0',
+ member_level_id int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (profile_id,club_id)
+);
+INSERT INTO t2 VALUES (2,2519583,12);
+
+DROP TABLE IF EXISTS t3;
+CREATE TABLE t3 (
+ member_level_id int(11) unsigned NOT NULL DEFAULT '0',
+ map_level int(11) unsigned NOT NULL DEFAULT '0',
+ map_status int(11) unsigned NOT NULL DEFAULT '0',
+ PRIMARY KEY (member_level_id)
+);
+INSERT INTO t3 VALUES (12,12,1);
+
+CREATE
+ VIEW v1 AS
+ select club_id,profile_id,
+ map_level AS member_level_id,map_status AS member_status
+ from (t2 tc join t3 map
+ on(((tc.member_level_id = map.member_level_id) and
+ (club_id = 2))));
+
+select level, count(*) as cnt from t1 group by level;
+UPDATE t1 c LEFT JOIN v1 t ON (c.id = t.profile_id AND t.club_id = 2)
+ SET c.level = IF (t.member_status IS NULL, 1, IF (t.member_status = 1, 2,3));
+select level, count(*) as cnt from t1 group by level;
+drop view v1;
+drop table t1,t2,t3;
+
+--echo end of tests
+
+--echo #
--echo # BUG#57373: Multi update+InnoDB reports ER_KEY_NOT_FOUND if a
--echo # table is updated twice
--echo #
@@ -759,6 +808,5 @@ SELECT * FROM t2;
DROP TABLE t1,t2;
-
-
+--echo end of 5.5 tests
diff --git a/mysql-test/t/myisam-metadata.test b/mysql-test/t/myisam-metadata.test
new file mode 100644
index 00000000000..c5327aa3a71
--- /dev/null
+++ b/mysql-test/t/myisam-metadata.test
@@ -0,0 +1,49 @@
+#
+# Test bugs in MyISAM that may cause problems for metadata
+#
+
+--source include/big_test.inc
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+#
+# LP:989055 - Querying myisam table metadata may corrupt the table
+#
+
+CREATE TABLE t1 (
+ id INT PRIMARY KEY,
+ a VARCHAR(100),
+ INDEX(a)
+) ENGINE=MyISAM;
+ALTER TABLE t1 DISABLE KEYS;
+
+let $1=100000;
+--disable_query_log
+while ($1)
+{
+ eval insert into t1 values($1, "line number $1");
+ dec $1;
+}
+--enable_query_log
+
+--connect(con1,localhost,root,,)
+--send
+ ALTER TABLE t1 ENABLE KEYS;
+
+--connection default
+--let $wait_timeout=10
+--let $show_statement= SHOW PROCESSLIST
+--let $field= State
+--let $condition= = 'Repair by sorting'
+--source include/wait_show_condition.inc
+
+--replace_column 7 # 8 # 9 # 12 # 13 # 14 #
+SHOW TABLE STATUS LIKE 't1';
+
+--connection con1
+--reap
+--connection default
+--disconnect con1
+DROP TABLE t1;
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index 4199d98073c..8323890b028 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -1536,10 +1536,10 @@ drop table t1;
#
CREATE TABLE t1 (line LINESTRING NOT NULL) engine=myisam;
-INSERT INTO t1 VALUES (GeomFromText("POINT(0 0)"));
+INSERT INTO t1 VALUES (GeomFromText("LINESTRING(0 0)"));
checksum table t1;
CREATE TABLE t2 (line LINESTRING NOT NULL) engine=myisam;
-INSERT INTO t2 VALUES (GeomFromText("POINT(0 0)"));
+INSERT INTO t2 VALUES (GeomFromText("LINESTRING(0 0)"));
checksum table t2;
CREATE TABLE t3 select * from t1;
checksum table t3;
@@ -1582,22 +1582,6 @@ SELECT h+0, d + 0, e, g + 0 FROM t1;
DROP TABLE t1;
---echo #
---echo # Test of BUG#35570 CHECKSUM TABLE unreliable if LINESTRING field
---echo # (same content / differen checksum)
---echo #
-
-CREATE TABLE t1 (line LINESTRING NOT NULL) engine=myisam;
-INSERT INTO t1 VALUES (GeomFromText("POINT(0 0)"));
-checksum table t1;
-CREATE TABLE t2 (line LINESTRING NOT NULL) engine=myisam;
-INSERT INTO t2 VALUES (GeomFromText("POINT(0 0)"));
-checksum table t2;
-CREATE TABLE t3 select * from t1;
-checksum table t3;
-drop table t1,t2,t3;
-
-
#
# BUG#47073 - valgrind errs, corruption,failed repair of partition,
# low myisam_sort_buffer_size
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index 76d980dee30..cad5b67c363 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -593,6 +593,15 @@ create database `aa``bb````cc`;
--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/backticks.sql
drop database `aa``bb````cc`;
+#
+# MySQL Bug#13639125 DELIMITER STRIPS THE NEXT NEW LINE IN A SQL STATEMENT
+#
+--write_file $MYSQLTEST_VARDIR/tmp/13639125.sql
+select ">>
+delimiter
+<<" as a;
+EOF
+--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/13639125.sql
--echo
--echo End of tests
diff --git a/mysql-test/t/mysqlshow.test b/mysql-test/t/mysqlshow.test
index fc5d4d982e5..cf8661d090c 100644
--- a/mysql-test/t/mysqlshow.test
+++ b/mysql-test/t/mysqlshow.test
@@ -29,7 +29,7 @@ select "---- -v -v -t ------" as "";
DROP TABLE t1, t2;
-if (`select count(*) from information_schema.plugins where plugin_name='innodb' and plugin_auth_version > "1.1.8-29.3"`)
+if (`select count(*) from information_schema.plugins where plugin_name='innodb' and plugin_auth_version > "5.5.31"`)
{
# because of lp:1066512 this test shows xtradb I_S plugins, even when
# xtradb is supposed to be disabled
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 44eaf7130a7..af507b1f7ef 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -4460,5 +4460,24 @@ INSERT INTO t2 VALUES (3),(4);
SELECT * FROM t1, t2 WHERE a=3 AND a=b;
drop table t1,t2;
+--echo #
+--echo # Bug mdev-4250: wrong transformation of WHERE condition with OR
+--echo #
+
+CREATE TABLE t1 (pk int PRIMARY KEY, a int);
+INSERT INTO t1 VALUES (3,0), (2,0), (4,1), (5,0), (1,0);
+
+SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0;
+EXPLAIN EXTENDED
+SELECT * FROM t1 WHERE (1=2 OR t1.pk=2) AND t1.a <> 0;
+
+DROP TABLE t1;
+
+SELECT * FROM mysql.time_zone
+WHERE ( NOT (Use_leap_seconds <= Use_leap_seconds AND Time_zone_id != 1)
+ AND Time_zone_id = Time_zone_id
+ OR Time_zone_id <> Time_zone_id )
+ AND Use_leap_seconds <> 'N';
+
--echo End of 5.3 tests
diff --git a/mysql-test/t/subselect_sj2_mat.test b/mysql-test/t/subselect_sj2_mat.test
index 7c3b37b517a..61d9b09edff 100644
--- a/mysql-test/t/subselect_sj2_mat.test
+++ b/mysql-test/t/subselect_sj2_mat.test
@@ -36,4 +36,230 @@ WHERE a IN
DROP TABLE t1, t2;
set max_join_size= @tmp_906385;
+--echo #
+--echo # mdev-3995: Wrong result for semijoin with materialization
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+CREATE TABLE t1 (
+ cat_id int(10) unsigned NOT NULL,
+ PRIMARY KEY (cat_id)
+) ENGINE=MyISAM;
+
+INSERT INTO t1 VALUES
+(709411),(709412),(709413),(709414),(709416),(709417),(709418),(709419),(709421),(709422),
+(709424),(709425),(709427),(709428),(709429),(709431),(709432),(709433),(709434),(709435),
+(709438),(709439),(709441),(709442),(709443),(709444),(709445),(709446),(709447),(709450),
+(709451),(709454),(709455),(709456),(709457),(709459),(709460),(709461),(709462),(709463),
+(709464),(709465),(709467),(709469),(709470),(709471),(709472),(709473),(709474),(709475),
+(709476),(709477),(709478),(709479),(709480),(709481),(709483),(709484),(709485),(709487),
+(709490),(709491),(709492),(709493),(709494),(709495),(709496),(709497),(709498),(709499),
+(709500),(709501),(709502),(709503),(709504),(709505),(709506),(709507),(709509),(709510),
+(709511),(709512),(709513),(709514),(709515),(709516),(709517),(709518),(709519),(709520),
+(709521),(709522),(709523),(709524),(709525),(709526),(709527),(709528),(709529),(709530),
+(709531),(709532),(709533),(709534),(709535),(709536),(709537),(709538),(709539),(709540),
+(709541),(709542),(709543),(709544),(709545),(709546),(709548),(709549),(709551),(709552),
+(709553),(709555),(709556),(709557),(709558),(709559),(709560),(709561),(709562),(709563),
+(709564),(709565),(709566),(709567),(709568),(709569),(709570),(709571),(709572),(709573),
+(709574),(709575),(709576),(709577),(709578),(709579),(709580),(709581),(709582),(709583),
+(709584),(709585),(709586),(709587),(709588),(709590),(709591),(709592),(709593),(709594),
+(709595),(709596),(709597),(709598),(709600),(709601),(709602),(709603),(709604),(709605),
+(709606),(709608),(709609),(709610),(709611),(709612),(709613),(709614),(709615),(709616),
+(709617),(709618),(709619),(709620),(709621),(709622),(709623),(709624),(709625),(709626),
+(709627),(709628),(709629),(709630),(709631),(709632),(709633),(709634),(709635),(709637),
+(709638),(709639),(709640),(709641),(709642),(709643),(709644),(709645),(709646),(709649),
+(709650),(709651),(709652),(709653),(709654),(709655),(709656),(709657),(709658),(709659);
+
+CREATE TABLE t2 (
+ cat_id int(10) NOT NULL,
+ KEY cat_id (cat_id)
+) ENGINE=MyISAM;
+
+INSERT INTO t2 VALUES
+(708742),(708755),(708759),(708761),(708766),(708769),(708796),(708798),(708824),(708825),
+(708838),(708844),(708861),(708882),(708887),(708889),(708890),(709586),(709626);
+
+CREATE TABLE t3 (
+ sack_id int(10) unsigned NOT NULL,
+ kit_id tinyint(3) unsigned NOT NULL DEFAULT '0',
+ cat_id int(10) unsigned NOT NULL,
+ PRIMARY KEY (sack_id,kit_id,cat_id)
+) ENGINE=MyISAM;
+
+INSERT INTO t3 VALUES
+(33479,6,708523),(33479,6,708632),(33479,6,709085),(33479,6,709586),(33479,6,709626);
+
+CREATE TABLE t4 (
+ cat_id int(10) unsigned NOT NULL,
+ KEY cat_id (cat_id)
+) ENGINE=MyISAM;
+
+INSERT INTO t4 (cat_id) SELECT cat_id from t2;
+
+set optimizer_switch='materialization=off';
+
+EXPLAIN
+SELECT count(*) FROM t1, t3
+ WHERE t1.cat_id = t3.cat_id AND
+ t3.cat_id IN (SELECT cat_id FROM t2) AND
+ t3.sack_id = 33479 AND t3.kit_id = 6;
+
+SELECT count(*) FROM t1, t3
+ WHERE t1.cat_id = t3.cat_id AND
+ t3.cat_id IN (SELECT cat_id FROM t2) AND
+ t3.sack_id = 33479 AND t3.kit_id = 6;
+
+set optimizer_switch='materialization=on';
+
+EXPLAIN
+SELECT count(*) FROM t1, t3
+ WHERE t1.cat_id = t3.cat_id AND
+ t3.cat_id IN (SELECT cat_id FROM t4) AND
+ t3.sack_id = 33479 AND t3.kit_id = 6;
+
+SELECT count(*) FROM t1, t3
+ WHERE t1.cat_id = t3.cat_id AND
+ t3.cat_id IN (SELECT cat_id FROM t4) AND
+ t3.sack_id = 33479 AND t3.kit_id = 6;
+
+EXPLAIN
+SELECT count(*) FROM t1, t3
+ WHERE t1.cat_id = t3.cat_id AND
+ t3.cat_id IN (SELECT cat_id FROM t2) AND
+ t3.sack_id = 33479 AND t3.kit_id = 6;
+
+SELECT count(*) FROM t1, t3
+ WHERE t1.cat_id = t3.cat_id AND
+ t3.cat_id IN (SELECT cat_id FROM t2) AND
+ t3.sack_id = 33479 AND t3.kit_id = 6;
+
+
+DROP TABLE t1,t2,t3,t4;
+
+set optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # mdev-3913: LEFT JOIN with materialized multi-table IN subquery in WHERE
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+CREATE TABLE t1 (a1 char(1), b1 char(1), index idx(b1,a1));
+INSERT INTO t1 VALUES ('f','c'),('d','m'),('g','y');
+INSERT INTO t1 VALUES ('f','c'),('d','m'),('g','y');
+
+CREATE TABLE t2 (a2 char(1), b2 char(1));
+INSERT INTO t2 VALUES ('y','y'),('y','y'),('w','w');
+
+CREATE TABLE t3 (a3 int);
+INSERT INTO t3 VALUES (8),(6);
+
+CREATE TABLE t4 (a4 char(1), b4 char(1));
+INSERT INTO t4 VALUES ('y','y'),('y','y'),('w','w');
+
+set optimizer_switch='materialization=off';
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+ WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+ WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+
+set optimizer_switch='materialization=on';
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+ WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+SELECT * FROM t1 LEFT JOIN t2 ON ( b1 = a2 )
+ WHERE ( b1, b1 ) IN ( SELECT a4, b4 FROM t3, t4);
+
+DROP TABLE t1,t2,t3,t4;
+
+set optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # mdev-4172: LEFT JOIN with materialized multi-table IN subquery in WHERE
+--echo # and OR in ON condition
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+
+CREATE TABLE t1 (a1 int, c1 varchar(1));
+INSERT t1 VALUES (7,'v'), (3,'y');
+
+CREATE TABLE t2 (c2 varchar(1));
+INSERT INTO t2 VALUES ('y'), ('y');
+
+CREATE TABLE t3 (c3 varchar(1));
+INSERT INTO t3 VALUES
+ ('j'), ('v'), ('c'), ('m'), ('d'),
+ ('d'), ('y'), ('t'), ('d'), ('s');
+
+CREATE TABLE t4 (a4 int, c4 varchar(1));
+INSERT INTO t4 SELECT * FROM t1;
+
+set optimizer_switch='materialization=off';
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+ WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+ WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+
+set optimizer_switch='materialization=on';
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+ WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+SELECT * FROM t1 LEFT JOIN t2 ON (c2 = c1 OR c1 > 'z')
+ WHERE c1 IN ( SELECT c4 FROM t3,t4 WHERE c3 = c4);
+
+DROP TABLE t1,t2,t3,t4;
+
+set optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # mdev-4177: materialization of a subquery whose WHERE condition is OR
+--echo # formula with two disjucts such that the second one is always false
+--echo #
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @save_join_cache_level=@@join_cache_level;
+
+CREATE TABLE t1 (i1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1), (7), (4), (8), (4);
+
+CREATE TABLE t2 (i2 int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (7), (5);
+
+CREATE TABLE t3 (i3 int) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (7), (2), (9);
+
+set join_cache_level=3;
+
+set optimizer_switch='materialization=off,semijoin=off';
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+
+set optimizer_switch='materialization=on,semijoin=on';
+
+EXPLAIN EXTENDED
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+SELECT * FROM t1 WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 = i2 OR 1=2);
+
+EXPLAIN EXTENDED
+SELECT * FROM t1
+ WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 0 AND i3 = i2 OR 1=2);
+SELECT * FROM t1
+ WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 0 AND i3 = i2 OR 1=2);
+SELECT * FROM t1
+ WHERE i1 IN (SELECT i3 FROM t2, t3 WHERE i3 > 7 AND i3 = i2 OR 1=2);
+
+DROP TABLE t1,t2,t3;
+
+set join_cache_level= @save_join_cache_level;
+set optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test
index 2043342e2c8..5b0b70631a5 100644
--- a/mysql-test/t/type_enum.test
+++ b/mysql-test/t/type_enum.test
@@ -221,3 +221,18 @@ SELECT a FROM t1 WHERE a=0;
DROP TABLE t1;
--echo End of 5.1 tests
+
+--echo #
+--echo # MDEV-4241: Assertion failure: scale >= 0 && precision > 0 &&
+--echo # scale <= precision in decimal_bin_size
+--echo #
+CREATE TABLE t1 (
+ f1 enum('1','2','3','4','5')
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+--enable_metadata
+SELECT AVG(f1) FROM t1;
+--disable_metadata
+drop table t1;
+
+--echo End of 5.3 tests
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index c6c4e4d9d2f..9b6714a1bbb 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -364,7 +364,7 @@ SELECT (@v:=a) <> (@v:=1) FROM t1;
DROP TABLE t1;
#
-# LP BUG#1001506 Crash on a query with GROUP BY and user variables
+# lp:1001506 Crash on a query with GROUP BY and user variables
# MySQL Bug #11764372 57197: EVEN MORE USER VARIABLE CRASHING FUN
#
@@ -374,15 +374,49 @@ SELECT DISTINCT @a:=MIN(t1.a) FROM t1, t1 AS t2
GROUP BY @b:=(SELECT COUNT(*) > t2.a);
DROP TABLE t1;
+#
+#
+# Bug #12408412: GROUP_CONCAT + ORDER BY + INPUT/OUTPUT
+# SAME USER VARIABLE = CRASH
+#
+SET @bug12408412=1;
+SELECT GROUP_CONCAT(@bug12408412 ORDER BY 1) INTO @bug12408412;
+
--echo End of 5.1 tests
#
-# Bug#50511: Sometimes wrong handling of user variables containing NULL.
+# MDEV-616 lp:1002126
+# Bug #11764371 57196: MORE FUN WITH ASSERTION: !TABLE->FILE ||
+# TABLE->FILE->INITED == HANDLER::
#
---disable_warnings
-DROP TABLE IF EXISTS t1;
---enable_warnings
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0);
+SELECT DISTINCT POW(COUNT(*), @a:=(SELECT 1 FROM t1 LEFT JOIN t1 AS t2 ON @a))
+AS b FROM t1 GROUP BY a;
+SELECT @a;
+DROP TABLE t1;
+CREATE TABLE t1(f1 INT, f2 INT);
+INSERT INTO t1 VALUES (1,2),(2,3),(3,1);
+CREATE TABLE t2(a INT);
+INSERT INTO t2 VALUES (1);
+SET @var=NULL;
+SELECT @var:=(SELECT f2 FROM t2 WHERE @var) FROM t1 GROUP BY f1 ORDER BY f2 DESC
+LIMIT 1;
+SELECT @var;
+DROP TABLE t1, t2;
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0),(1),(3);
+SELECT DISTINCT POW(COUNT(distinct a), @a:=(SELECT 1 FROM t1 LEFT JOIN t1 AS t2 ON @a limit 1)) AS b FROM t1 GROUP BY a;
+SELECT @a;
+DROP TABLE t1;
+
+--echo End of 5.2 tests
+
+#
+# Bug#50511: Sometimes wrong handling of user variables containing NULL.
+#
CREATE TABLE t1(f1 INT AUTO_INCREMENT, PRIMARY KEY(f1));
@@ -415,41 +449,4 @@ SELECT f1, f2 FROM t1 ORDER BY f2;
DROP TRIGGER trg1;
DROP TABLE t1;
-
---echo #
---echo # Bug #12408412: GROUP_CONCAT + ORDER BY + INPUT/OUTPUT
---echo # SAME USER VARIABLE = CRASH
---echo #
-
-SET @bug12408412=1;
-SELECT GROUP_CONCAT(@bug12408412 ORDER BY 1) INTO @bug12408412;
-
-#
-# MDEV-616 LP BUG#1002126
-# Bug #11764371 57196: MORE FUN WITH ASSERTION: !TABLE->FILE ||
-# TABLE->FILE->INITED == HANDLER::
-#
-
-CREATE TABLE t1(a INT);
-INSERT INTO t1 VALUES (0);
-SELECT DISTINCT POW(COUNT(*), @a:=(SELECT 1 FROM t1 LEFT JOIN t1 AS t2 ON @a))
-AS b FROM t1 GROUP BY a;
-SELECT @a;
-DROP TABLE t1;
-CREATE TABLE t1(f1 INT, f2 INT);
-INSERT INTO t1 VALUES (1,2),(2,3),(3,1);
-CREATE TABLE t2(a INT);
-INSERT INTO t2 VALUES (1);
-SET @var=NULL;
-SELECT @var:=(SELECT f2 FROM t2 WHERE @var) FROM t1 GROUP BY f1 ORDER BY f2 DESC
-LIMIT 1;
-SELECT @var;
-DROP TABLE t1, t2;
-
-CREATE TABLE t1(a INT);
-INSERT INTO t1 VALUES (0),(1),(3);
-SELECT DISTINCT POW(COUNT(distinct a), @a:=(SELECT 1 FROM t1 LEFT JOIN t1 AS t2 ON @a limit 1)) AS b FROM t1 GROUP BY a;
-SELECT @a;
-DROP TABLE t1;
-
--echo End of 5.5 tests
diff --git a/mysys/errors.c b/mysys/errors.c
index bf7299ce4c6..1063cae8856 100644
--- a/mysys/errors.c
+++ b/mysys/errors.c
@@ -53,7 +53,7 @@ const char *globerrs[GLOBERRS]=
"File '%s' (fileno: %d) was not closed",
"Can't change ownership of the file '%s' (Errcode: %d)",
"Can't change permissions of the file '%s' (Errcode: %d)",
- "Can't seek in file '%s' (Errcode: %d)"
+ "Can't seek in file '%s' (Errcode: %d)",
"Can't change mode for file '%s' to 0x%lx (Error: %d)",
"Warning: Can't copy ownership for file '%s' (Error: %d)"
};
@@ -107,12 +107,12 @@ void init_glob_errs()
void wait_for_free_space(const char *filename, int errors)
{
if (errors == 0)
- my_error(EE_DISK_FULL,MYF(ME_BELL | ME_NOREFRESH),
+ my_error(EE_DISK_FULL,MYF(ME_BELL | ME_NOREFRESH | ME_JUST_WARNING),
filename,my_errno,MY_WAIT_FOR_USER_TO_FIX_PANIC);
if (!(errors % MY_WAIT_GIVE_USER_A_MESSAGE))
my_printf_error(EE_DISK_FULL,
"Retry in %d secs. Message reprinted in %d secs",
- MYF(ME_BELL | ME_NOREFRESH),
+ MYF(ME_BELL | ME_NOREFRESH | ME_JUST_WARNING),
MY_WAIT_FOR_USER_TO_FIX_PANIC,
MY_WAIT_GIVE_USER_A_MESSAGE * MY_WAIT_FOR_USER_TO_FIX_PANIC );
(void) sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC);
diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c
index a51d94f8e73..d684be238e6 100644
--- a/mysys/mf_pack.c
+++ b/mysys/mf_pack.c
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2012, Monty Program Ab
+/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
+ Copyright (c) 2012, 2013, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -12,7 +12,8 @@
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 */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
#include "mysys_priv.h"
#include <m_string.h>
@@ -452,10 +453,10 @@ char *intern_filename(char *to, const char *from)
char buff[FN_REFLEN + 1];
if (from == to)
{ /* Dirname may destroy from */
- strmov(buff,from);
+ (void) strnmov(buff, from, FN_REFLEN);
from=buff;
}
length= dirname_part(to, from, &to_length); /* Copy dirname & fix chars */
- (void) strmov(to + to_length,from+length);
+ (void) strnmov(to + to_length, from + length, FN_REFLEN - to_length);
return (to);
} /* intern_filename */
diff --git a/mysys/my_lib.c b/mysys/my_lib.c
index b42a3d55d93..71969f23d85 100644
--- a/mysys/my_lib.c
+++ b/mysys/my_lib.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
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
@@ -11,7 +11,8 @@
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
/* TODO: check for overun of memory for names. */
@@ -96,7 +97,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags)
MEM_ROOT *names_storage;
DIR *dirp;
struct dirent *dp;
- char tmp_path[FN_REFLEN+1],*tmp_file;
+ char tmp_path[FN_REFLEN + 2], *tmp_file;
char dirent_tmp[sizeof(struct dirent)+_POSIX_PATH_MAX+1];
DBUG_ENTER("my_dir");
@@ -197,10 +198,11 @@ char * directory_file_name (char * dst, const char *src)
{
/* Process as Unix format: just remove test the final slash. */
char *end;
+ DBUG_ASSERT(strlen(src) < (FN_REFLEN + 1));
if (src[0] == 0)
src= (char*) "."; /* Use empty as current */
- end=strmov(dst, src);
+ end= strnmov(dst, src, FN_REFLEN + 1);
if (end[-1] != FN_LIBCHAR)
{
end[0]=FN_LIBCHAR; /* Add last '/' */
diff --git a/mysys/my_write.c b/mysys/my_write.c
index c4cba7a927d..4997a4a804a 100644
--- a/mysys/my_write.c
+++ b/mysys/my_write.c
@@ -47,11 +47,17 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
#else
writtenbytes= write(Filedes, Buffer, Count);
#endif
- DBUG_EXECUTE_IF("simulate_file_write_error",
- {
- errno= ENOSPC;
- writtenbytes= (size_t) -1;
- });
+
+ /**
+ To simulate the write error set the errno = error code
+ and the number pf written bytes to -1.
+ */
+ DBUG_EXECUTE_IF ("simulate_file_write_error",
+ if (!errors) {
+ errno= ENOSPC;
+ writtenbytes= (size_t) -1;
+ });
+
if (writtenbytes == Count)
break;
if (writtenbytes != (size_t) -1)
diff --git a/mysys/thr_rwlock.c b/mysys/thr_rwlock.c
index 17fafecd8fd..dd6c625a286 100644
--- a/mysys/thr_rwlock.c
+++ b/mysys/thr_rwlock.c
@@ -24,7 +24,7 @@
static BOOL have_srwlock= FALSE;
/* Prototypes and function pointers for windows functions */
typedef VOID (WINAPI* srw_func) (PSRWLOCK SRWLock);
-typedef BOOL (WINAPI* srw_bool_func) (PSRWLOCK SRWLock);
+typedef BOOLEAN (WINAPI* srw_bool_func) (PSRWLOCK SRWLock);
static srw_func my_InitializeSRWLock;
static srw_func my_AcquireSRWLockExclusive;
diff --git a/packaging/WiX/custom_ui.wxs b/packaging/WiX/custom_ui.wxs
index 568053f4cf5..6e243832e12 100644
--- a/packaging/WiX/custom_ui.wxs
+++ b/packaging/WiX/custom_ui.wxs
@@ -2,7 +2,7 @@
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<!--
- Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
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
@@ -30,7 +30,7 @@
<Control Id="Back" Type="PushButton" X="156" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" Disabled="yes" />
<Control Id="Description" Type="Text" X="135" Y="80" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeDlgDescription)" />
<Control Id="Title" Type="Text" X="135" Y="20" Width="220" Height="60" Transparent="yes" NoPrefix="yes" Text="!(loc.WelcomeDlgTitle)" />
- <Control Id="CopyrightText" Type="Text" X="135" Y="200" Width="220" Height="40" Transparent="yes" Text="Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved." />
+ <Control Id="CopyrightText" Type="Text" X="135" Y="200" Width="220" Height="40" Transparent="yes" Text="Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved." />
<Control Id="Bitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="234" TabSkip="no" Text="!(loc.WelcomeDlgBitmap)" />
<Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
</Dialog>
diff --git a/packaging/rpm-uln/mysql.spec.sh b/packaging/rpm-uln/mysql.spec.sh
index 8b25b160be1..3e2c5c3f11c 100644
--- a/packaging/rpm-uln/mysql.spec.sh
+++ b/packaging/rpm-uln/mysql.spec.sh
@@ -508,21 +508,28 @@ mkdir release
# TODO / FIXME: Do we need "scriptstub"?
gcc $CFLAGS $LDFLAGS -o scriptstub "-DLIBDIR=\"%{_libdir}/mysql\"" %{SOURCE4}
-# TODO / FIXME: "libmysqld.so" should have been produced above - WORK in PROGRESS
+# TODO / FIXME: "libmysqld.so" should have been produced above
# regular build will make libmysqld.a but not libmysqld.so :-(
cd release
mkdir libmysqld/work
cd libmysqld/work
-ar -x ../libmysqld.a
-rm rpl_utility.cc.o sql_binlog.cc.o # Try-and-Error: These modules cause unresolved references
-gcc $CFLAGS $LDFLAGS -shared -Wl,-soname,libmysqld.so.0 -o libmysqld.so.0.0.1 \
- *.o \
+# "libmysqld" provides the same ABI as "libmysqlclient", but it implements the server:
+# The shared object is identified by the full version,
+# for linkage selection the first two levels are sufficient so that upgrades are possible
+# (see "man ld", option "-soname").
+SO_FULL='%{mysql_version}'
+SO_USE=`echo $SO_FULL | sed -e 's/\([0-9]\.[0-9]\)\.[0-9]*/\1/'`
+# These two modules should pull everything else which is needed:
+ar -x ../libmysqld.a client.c.o signal_handler.cc.o
+gcc $CFLAGS $LDFLAGS -shared -Wl,-soname,libmysqld.so.$SO_USE -o libmysqld.so.$SO_FULL \
+ *.o ../libmysqld.a \
-lpthread -lcrypt -laio -lnsl -lssl -lcrypto -lz -lrt -lstdc++ -lm -lc
# this is to check that we built a complete library
cp %{SOURCE9} .
-ln -s libmysqld.so.0.0.1 libmysqld.so.0
-gcc -I../../include -I../../../%{src_dir}/include $CFLAGS mysql-embedded-check.c libmysqld.so.0
-LD_LIBRARY_PATH=. ldd ./a.out
+PROGNAME=`basename %{SOURCE9} .c`
+ln -s libmysqld.so.$SO_FULL libmysqld.so.$SO_USE
+gcc -I../../include -I../../../%{src_dir}/include $CFLAGS -o $PROGNAME %{SOURCE9} libmysqld.so.$SO_USE
+LD_LIBRARY_PATH=. ldd $PROGNAME
cd ../..
cd ..
@@ -618,9 +625,11 @@ mv ${RPM_BUILD_ROOT}%{_bindir}/mysql_config ${RPM_BUILD_ROOT}%{_libdir}/mysql/my
install -m 0755 scriptstub ${RPM_BUILD_ROOT}%{_bindir}/mysql_config
rm -f ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.a
-install -m 0755 release/libmysqld/work/libmysqld.so.0.0.1 ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so.0.0.1
-ln -s libmysqld.so.0.0.1 ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so.0
-ln -s libmysqld.so.0 ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so
+SO_FULL='%{mysql_version}'
+SO_USE=`echo $SO_FULL | sed -e 's/\([0-9]\.[0-9]\)\.[0-9]*/\1/'`
+install -m 0755 release/libmysqld/work/libmysqld.so.$SO_FULL ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so.$SO_FULL
+ln -s libmysqld.so.$SO_FULL ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so.$SO_USE
+ln -s libmysqld.so.$SO_USE ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so
rm -f ${RPM_BUILD_ROOT}%{_bindir}/comp_err
rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/comp_err.1*
@@ -964,6 +973,12 @@ fi
%{_mandir}/man1/mysql_client_test.1*
%changelog
+* Thu Dec 7 2012 Joerg Bruehe <joerg.bruehe@oracle.com>
+- Change the way in which "libmysqld.so" is created: Using all object modules
+ was wrong, gcc / ld can resolve the dependencies from "libmysqld.a".
+ Also, identify the ".so" version from the MySQL version, "0.0.1" was wrong.
+ Bug#15972480
+
* Tue Sep 18 2012 Joerg Bruehe <joerg.bruehe@oracle.com>
- Restrict the vendor check to Oracle: There is no history here
which we have to allow for.
diff --git a/plugin/auth_socket/CMakeLists.txt b/plugin/auth_socket/CMakeLists.txt
index 731f7d01f9a..ae7dbffe2ae 100644
--- a/plugin/auth_socket/CMakeLists.txt
+++ b/plugin/auth_socket/CMakeLists.txt
@@ -21,7 +21,19 @@ int main() {
struct ucred cred;
getsockopt(0, SOL_SOCKET, SO_PEERCRED, &cred, 0);
}" HAVE_PEERCRED)
+
+IF (NOT HAVE_PEERCRED)
+ # Hi, OpenBSD!
+ CHECK_CXX_SOURCE_COMPILES(
+ "#include <sys/types.h>
+ #include <sys/socket.h>
+ int main() {
+ struct sockpeercred cred;
+ getsockopt(0, SOL_SOCKET, SO_PEERCRED, &cred, 0);
+ }" HAVE_SOCKPEERCRED)
+ ADD_DEFINITIONS(-Ducred=sockpeercred)
+ENDIF()
-IF(HAVE_PEERCRED)
+IF(HAVE_PEERCRED OR HAVE_SOCKPEERCRED)
MYSQL_ADD_PLUGIN(auth_socket auth_socket.c MODULE_ONLY)
ENDIF()
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index b28e8a3ba1c..241cb84a399 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -257,7 +257,7 @@ fi
# Now we can get arguments from the groups [mysqld] and [mysql_install_db]
# in the my.cfg file, then re-run to merge with command line arguments.
-parse_arguments `"$print_defaults" $defaults mysqld mariadb mysql_install_db client-server`
+parse_arguments `"$print_defaults" $defaults --mysqld mysql_install_db`
parse_arguments PICK-ARGS-FROM-ARGV "$@"
# Configure paths to support files
diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh
index 41d02596cf7..52135071ac5 100644
--- a/scripts/mysqld_multi.sh
+++ b/scripts/mysqld_multi.sh
@@ -241,7 +241,7 @@ sub defaults_for_group
sub init_log
{
- foreach my $opt (defaults_for_group('mysqld mariadb'))
+ foreach my $opt (defaults_for_group('--mysqld'))
{
if ($opt =~ m/^--datadir=(.*)/ && -d "$1" && -w "$1")
{
diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
index bbe12db35f3..09524fedcc0 100644
--- a/scripts/mysqld_safe.sh
+++ b/scripts/mysqld_safe.sh
@@ -71,6 +71,7 @@ Usage: $0 [OPTIONS]
--defaults-extra-file=FILE Also use defaults from the specified file
--ledir=DIRECTORY Look for mysqld in the specified directory
--open-files-limit=LIMIT Limit the number of open files
+ --crash-script=FILE Script to call when mysqld crashes
--timezone=TZ Set the system timezone
--malloc-lib=LIB Preload shared library LIB if available
--mysqld=FILE Use the specified file as mysqld
@@ -269,6 +270,7 @@ parse_arguments() {
optname_subst=`echo "$optname" | sed 's/_/-/g'`
arg=`echo $arg | sed "s/^$optname/$optname_subst/"`
case "$arg" in
+ --crash-script=*) CRASH_SCRIPT="$val" ;;
# these get passed explicitly to mysqld
--basedir=*) MY_BASEDIR_VERSION="$val" ;;
--datadir=*|--data=*) DATADIR="$val" ;;
@@ -574,7 +576,7 @@ append_arg_to_args () {
args=
SET_USER=2
-parse_arguments `$print_defaults $defaults --loose-verbose mysqld mariadb server client-server`
+parse_arguments `$print_defaults $defaults --loose-verbose --mysqld`
if test $SET_USER -eq 2
then
SET_USER=0
@@ -658,7 +660,7 @@ then
log_notice "Logging to '$err_log'."
logging=file
- if [ ! -e "$err_log" ]; then # if error log already exists,
+ if [ ! -f "$err_log" ]; then # if error log already exists,
touch "$err_log" # we just append. otherwise,
chmod "$fmode" "$err_log" # fix the permissions here!
fi
@@ -879,7 +881,7 @@ max_wsrep_restarts=0
while true
do
- rm -f $safe_mysql_unix_port "$pid_file" # Some extra safety
+ rm -f "$pid_file" # Some extra safety
start_time=`date +%M%S`
@@ -897,7 +899,7 @@ do
eval_log_error "$cmd $wsrep_start_position_opt --wsrep_cluster_address=$url $nohup_redir"
fi
- if [ $want_syslog -eq 0 -a ! -e "$err_log" ]; then
+ if [ $want_syslog -eq 0 -a ! -f "$err_log" ]; then
touch "$err_log" # hypothetical: log was renamed but not
chown $user "$err_log" # flushed yet. we'd recreate it with
chmod "$fmode" "$err_log" # wrong owner next time we log, so set
@@ -980,6 +982,11 @@ do
fi
log_notice "mysqld restarted"
+ if test -n "$CRASH_SCRIPT"
+ then
+ crash_script_output=`$CRASH_SCRIPT 2>&1`
+ log_error "$crash_script_output"
+ fi
done
log_notice "mysqld from pid file $pid_file ended"
diff --git a/scripts/mysqldumpslow.sh b/scripts/mysqldumpslow.sh
index 0de4fe159f0..c04ffad7457 100644
--- a/scripts/mysqldumpslow.sh
+++ b/scripts/mysqldumpslow.sh
@@ -53,7 +53,7 @@ GetOptions(\%opt,
$opt{'help'} and usage();
unless (@ARGV) {
- my $defaults = `my_print_defaults mysqld mariadb`;
+ my $defaults = `my_print_defaults --mysqld`;
my $datadir = ($defaults =~ m/--datadir=(.*)/g)[-1];
if (!$datadir or $opt{i}) {
diff --git a/sql/field.cc b/sql/field.cc
index 4667702c145..7da46d6b383 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -204,7 +204,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]=
//MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP
MYSQL_TYPE_LONG, MYSQL_TYPE_VARCHAR,
//MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24
- MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24,
+ MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONG,
//MYSQL_TYPE_DATE MYSQL_TYPE_TIME
MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR,
//MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR
@@ -235,7 +235,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]=
//MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP
MYSQL_TYPE_FLOAT, MYSQL_TYPE_VARCHAR,
//MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24
- MYSQL_TYPE_FLOAT, MYSQL_TYPE_INT24,
+ MYSQL_TYPE_FLOAT, MYSQL_TYPE_FLOAT,
//MYSQL_TYPE_DATE MYSQL_TYPE_TIME
MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR,
//MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR
@@ -266,7 +266,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]=
//MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP
MYSQL_TYPE_DOUBLE, MYSQL_TYPE_VARCHAR,
//MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24
- MYSQL_TYPE_DOUBLE, MYSQL_TYPE_INT24,
+ MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE,
//MYSQL_TYPE_DATE MYSQL_TYPE_TIME
MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR,
//MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR
@@ -297,7 +297,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]=
//MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP
MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP,
//MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24
- MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24,
+ MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG,
//MYSQL_TYPE_DATE MYSQL_TYPE_TIME
MYSQL_TYPE_NEWDATE, MYSQL_TYPE_TIME,
//MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR
@@ -7580,6 +7580,19 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
if (wkb_type < (uint32) Geometry::wkb_point ||
wkb_type > (uint32) Geometry::wkb_last)
goto err;
+
+ if (geom_type != Field::GEOM_GEOMETRY &&
+ geom_type != Field::GEOM_GEOMETRYCOLLECTION &&
+ (uint32) geom_type != wkb_type)
+ {
+ my_printf_error(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
+ ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), MYF(0),
+ Geometry::ci_collection[geom_type]->m_name.str,
+ Geometry::ci_collection[wkb_type]->m_name.str, field_name,
+ (ulong) table->in_use->warning_info->current_row_for_warning());
+ goto err_exit;
+ }
+
Field_blob::store_length(length);
if (table->copy_blobs || length <= MAX_FIELD_WIDTH)
{ // Must make a copy
@@ -7591,9 +7604,10 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
return 0;
err:
- bzero(ptr, Field_blob::pack_length());
my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
+err_exit:
+ bzero(ptr, Field_blob::pack_length());
return -1;
}
diff --git a/sql/field.h b/sql/field.h
index a6382026d97..8df1c6572f4 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1999,6 +1999,7 @@ public:
bool has_charset(void) const { return TRUE; }
/* enum and set are sorted as integers */
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
+ uint decimals() const { return 0; }
virtual uchar *pack(uchar *to, const uchar *from, uint max_length);
virtual const uchar *unpack(uchar *to, const uchar *from,
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 4cf66daf315..b10de0362f2 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -3826,6 +3826,7 @@ int ha_partition::truncate_partition(Alter_info *alter_info, bool *binlog_stmt)
part, sub_elem->partition_name));
if ((error= m_file[part]->ha_truncate()))
break;
+ sub_elem->part_state= PART_NORMAL;
} while (++j < num_subparts);
}
else
@@ -4423,6 +4424,7 @@ bool ha_partition::init_record_priority_queue()
{
if (bitmap_is_set(&m_part_info->used_partitions, i))
{
+ DBUG_PRINT("info", ("init rec-buf for part %u", i));
int2store(ptr, i);
ptr+= m_rec_length + PARTITION_BYTES_IN_POS;
}
@@ -5317,11 +5319,27 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
m_top_entry= NO_CURRENT_PART_ID;
queue_remove_all(&m_queue);
- DBUG_PRINT("info", ("m_part_spec.start_part %d", m_part_spec.start_part));
- for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++)
+ /*
+ Position part_rec_buf_ptr to point to the first used partition >=
+ start_part. There may be partitions marked by used_partitions,
+ but is before start_part. These partitions has allocated record buffers
+ but is dynamically pruned, so those buffers must be skipped.
+ */
+ uint first_used_part= bitmap_get_first_set(&m_part_info->used_partitions);
+ for (; first_used_part < m_part_spec.start_part; first_used_part++)
+ {
+ if (bitmap_is_set(&(m_part_info->used_partitions), first_used_part))
+ part_rec_buf_ptr+= m_rec_length + PARTITION_BYTES_IN_POS;
+ }
+ DBUG_PRINT("info", ("m_part_spec.start_part %u first_used_part %u",
+ m_part_spec.start_part, first_used_part));
+ for (i= first_used_part; i <= m_part_spec.end_part; i++)
{
if (!(bitmap_is_set(&(m_part_info->used_partitions), i)))
continue;
+ DBUG_PRINT("info", ("reading from part %u (scan_type: %u)",
+ i, m_index_scan_type));
+ DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr));
uchar *rec_buf_ptr= part_rec_buf_ptr + PARTITION_BYTES_IN_POS;
int error;
handler *file= m_file[i];
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 3e64e3969e4..9a0ed877bf1 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -241,15 +241,15 @@ static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE)
items[i]->cmp_type() == ROW_RESULT) &&
cmp_row_type(items[0], items[i]))
return 0;
- found_types|= 1<< (uint)item_cmp_type(left_result,
- items[i]->cmp_type());
+ found_types|= 1U << (uint)item_cmp_type(left_result,
+ items[i]->cmp_type());
}
/*
Even if all right-hand items are NULLs and we are skipping them all, we need
at least one type bit in the found_type bitmask.
*/
if (skip_nulls && !found_types)
- found_types= 1 << (uint)left_result;
+ found_types= 1U << (uint)left_result;
return found_types;
}
@@ -2824,12 +2824,12 @@ Item *Item_func_case::find_item(String *str)
cmp_type= item_cmp_type(left_result_type, args[i]->cmp_type());
DBUG_ASSERT(cmp_type != ROW_RESULT);
DBUG_ASSERT(cmp_items[(uint)cmp_type]);
- if (!(value_added_map & (1<<(uint)cmp_type)))
+ if (!(value_added_map & (1U << (uint)cmp_type)))
{
cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]);
if ((null_value=args[first_expr_num]->null_value))
return else_expr_num != -1 ? args[else_expr_num] : 0;
- value_added_map|= 1<<(uint)cmp_type;
+ value_added_map|= 1U << (uint)cmp_type;
}
if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value)
return args[i + 1];
@@ -3036,10 +3036,10 @@ void Item_func_case::fix_length_and_dec()
return;
Item *date_arg= 0;
- if (found_types & (1 << TIME_RESULT))
+ if (found_types & (1U << TIME_RESULT))
date_arg= find_date_time_item(args, arg_count, 0);
- if (found_types & (1 << STRING_RESULT))
+ if (found_types & (1U << STRING_RESULT))
{
/*
If we'll do string comparison, we also need to aggregate
@@ -3080,7 +3080,7 @@ void Item_func_case::fix_length_and_dec()
for (i= 0; i <= (uint)TIME_RESULT; i++)
{
- if (found_types & (1 << i) && !cmp_items[i])
+ if (found_types & (1U << i) && !cmp_items[i])
{
DBUG_ASSERT((Item_result)i != ROW_RESULT);
@@ -3936,7 +3936,7 @@ void Item_func_in::fix_length_and_dec()
}
for (i= 0; i <= (uint)TIME_RESULT; i++)
{
- if (found_types & 1 << i)
+ if (found_types & (1U << i))
{
(type_cnt)++;
cmp_type= (Item_result) i;
@@ -4063,14 +4063,14 @@ void Item_func_in::fix_length_and_dec()
}
else
{
- if (found_types & (1 << TIME_RESULT))
+ if (found_types & (1U << TIME_RESULT))
date_arg= find_date_time_item(args, arg_count, 0);
- if (found_types & (1 << STRING_RESULT) &&
+ if (found_types & (1U << STRING_RESULT) &&
agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
return;
for (i= 0; i <= (uint) TIME_RESULT; i++)
{
- if (found_types & (1 << i) && !cmp_items[i])
+ if (found_types & (1U << i) && !cmp_items[i])
{
if (!cmp_items[i] && !(cmp_items[i]=
cmp_item::get_comparator((Item_result)i, date_arg,
@@ -4156,12 +4156,12 @@ longlong Item_func_in::val_int()
Item_result cmp_type= item_cmp_type(left_result_type, args[i]->cmp_type());
in_item= cmp_items[(uint)cmp_type];
DBUG_ASSERT(in_item);
- if (!(value_added_map & (1 << (uint)cmp_type)))
+ if (!(value_added_map & (1U << (uint)cmp_type)))
{
in_item->store_value(args[0]);
if ((null_value= args[0]->null_value))
return 0;
- value_added_map|= 1 << (uint)cmp_type;
+ value_added_map|= 1U << (uint)cmp_type;
}
if (!in_item->cmp(args[i]) && !args[i]->null_value)
return (longlong) (!negated);
@@ -5533,6 +5533,7 @@ Item_equal::Item_equal(Item *f1, Item *f2, bool with_const_item)
equal_items.push_back(f1);
equal_items.push_back(f2);
compare_as_dates= with_const_item && f2->cmp_type() == TIME_RESULT;
+ upper_levels= NULL;
}
@@ -5561,10 +5562,11 @@ Item_equal::Item_equal(Item_equal *item_equal)
with_const= item_equal->with_const;
compare_as_dates= item_equal->compare_as_dates;
cond_false= item_equal->cond_false;
+ upper_levels= item_equal->upper_levels;
}
-/*
+/**
@brief
Add a constant item to the Item_equal object
@@ -5618,6 +5620,7 @@ void Item_equal::add_const(Item *c, Item *f)
const_item_cache= 1;
}
+
/**
@brief
Check whether a field is referred to in the multiple equality
@@ -5686,6 +5689,87 @@ void Item_equal::merge(Item_equal *item)
/**
@brief
+ Merge members of another Item_equal object into this one
+
+ @param item multiple equality whose members are to be merged
+
+ @details
+ If the Item_equal 'item' happened to have some elements of the list
+ of equal items belonging to 'this' object then the function merges
+ the equal items from 'item' into this list.
+ If both lists contains constants and they are different then
+ the value of the cond_false flag is set to TRUE.
+
+ @retval
+ 1 the lists of equal items in 'item' and 'this' contain common elements
+ @retval
+ 0 otherwise
+
+ @notes
+ The method 'merge' just joins the list of equal items belonging to 'item'
+ to the list of equal items belonging to this object assuming that the lists
+ are disjoint. It would be more correct to call the method 'join'.
+ The method 'merge_with_check' really merges two lists of equal items if they
+ have common members.
+*/
+
+bool Item_equal::merge_with_check(Item_equal *item)
+{
+ bool intersected= FALSE;
+ Item_equal_fields_iterator_slow fi(*this);
+ while (fi++)
+ {
+ if (item->contains(fi.get_curr_field()))
+ {
+ fi.remove();
+ intersected= TRUE;
+ }
+ }
+ if (intersected)
+ item->merge(this);
+ return intersected;
+}
+
+
+/**
+ @brief
+ Merge this object into a list of Item_equal objects
+
+ @param list the list of Item_equal objects to merge into
+
+ @details
+ If the list of equal items from 'this' object contains common members
+ with the lists of equal items belonging to Item_equal objects from 'list'
+ then all involved Item_equal objects e1,...,ek are merged into one
+ Item equal that replaces e1,...,ek in the 'list'. Otherwise this
+ Item_equal is joined to the 'list'.
+*/
+
+void Item_equal::merge_into_list(List<Item_equal> *list)
+{
+ Item_equal *item;
+ List_iterator<Item_equal> it(*list);
+ Item_equal *merge_into= NULL;
+ while((item= it++))
+ {
+ if (!merge_into)
+ {
+ if (merge_with_check(item))
+ merge_into= item;
+ }
+ else
+ {
+ if (item->merge_with_check(merge_into))
+ it.remove();
+ }
+ }
+ if (!merge_into)
+ list->push_back(this);
+}
+
+
+/**
+ @brief
Order equal items of the multiple equality according to a sorting criteria
@param compare function to compare items from the equal_items list
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index eed9028a630..1f490d3b5fc 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1575,6 +1575,11 @@ public:
DBUG_ASSERT(nlist->elements);
list.prepand(nlist);
}
+ void add_at_end(List<Item> *nlist)
+ {
+ DBUG_ASSERT(nlist->elements);
+ list.concat(nlist);
+ }
bool fix_fields(THD *, Item **ref);
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
@@ -1600,6 +1605,7 @@ public:
bool eval_not_null_tables(uchar *opt_arg);
};
+template <template<class> class LI, class T> class Item_equal_iterator;
/*
The class Item_equal is used to represent conjunctions of equality
@@ -1727,7 +1733,11 @@ class Item_equal: public Item_bool_func
used in the original equality.
*/
Item_field *context_field;
+
public:
+
+ COND_EQUAL *upper_levels; /* multiple equalities of upper and levels */
+
inline Item_equal()
: Item_bool_func(), with_const(FALSE), eval_item(0), cond_false(0),
context_field(NULL)
@@ -1744,6 +1754,8 @@ public:
/** Get number of field items / references to field items in this object */
uint n_field_items() { return equal_items.elements-test(with_const); }
void merge(Item_equal *item);
+ bool merge_with_check(Item_equal *equal_item);
+ void merge_into_list(List<Item_equal> *list);
void update_const();
enum Functype functype() const { return MULT_EQUAL_FUNC; }
longlong val_int();
@@ -1759,7 +1771,8 @@ public:
CHARSET_INFO *compare_collation();
void set_context_field(Item_field *ctx_field) { context_field= ctx_field; }
- friend class Item_equal_fields_iterator;
+ friend class Item_equal_iterator<List_iterator_fast,Item>;
+ friend class Item_equal_iterator<List_iterator,Item>;
friend Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
Item_equal *item_equal);
friend bool setup_sj_materialization_part1(struct st_join_table *tab);
@@ -1778,43 +1791,55 @@ public:
{
upper_levels= 0;
}
+ void copy(COND_EQUAL &cond_equal)
+ {
+ max_members= cond_equal.max_members;
+ upper_levels= cond_equal.upper_levels;
+ if (cond_equal.current_level.is_empty())
+ current_level.empty();
+ else
+ current_level= cond_equal.current_level;
+ }
};
/*
- The class Item_equal_fields_iterator is used to iterate over references
- to table/view columns from a list of equal items.
+ The template Item_equal_iterator is used to define classes
+ Item_equal_fields_iterator and Item_equal_fields_iterator_slow.
+ These are helper classes for the class Item equal
+ Both classes are used to iterate over references to table/view columns
+ from the list of equal items that included in an Item_equal object.
+ The second class supports the operation of removal of the current member
+ from the list when performing an iteration.
*/
-class Item_equal_fields_iterator : public List_iterator_fast<Item>
+template <template<class> class LI, typename T> class Item_equal_iterator
+ : public LI<T>
{
+protected:
Item_equal *item_equal;
Item *curr_item;
public:
- Item_equal_fields_iterator(Item_equal &item_eq)
- :List_iterator_fast<Item> (item_eq.equal_items)
+ Item_equal_iterator<LI,T>(Item_equal &item_eq)
+ :LI<T> (item_eq.equal_items)
{
curr_item= NULL;
item_equal= &item_eq;
if (item_eq.with_const)
{
- List_iterator_fast<Item> *list_it= this;
+ LI<T> *list_it= this;
curr_item= (*list_it)++;
}
}
Item* operator++(int)
{
- List_iterator_fast<Item> *list_it= this;
+ LI<T> *list_it= this;
curr_item= (*list_it)++;
return curr_item;
}
- Item ** ref()
- {
- return List_iterator_fast<Item>::ref();
- }
void rewind(void)
{
- List_iterator_fast<Item> *list_it= this;
+ LI<T> *list_it= this;
list_it->rewind();
if (item_equal->with_const)
curr_item= (*list_it)++;
@@ -1826,6 +1851,36 @@ public:
}
};
+typedef Item_equal_iterator<List_iterator_fast,Item > Item_equal_iterator_fast;
+
+class Item_equal_fields_iterator
+ :public Item_equal_iterator_fast
+{
+public:
+ Item_equal_fields_iterator(Item_equal &item_eq)
+ :Item_equal_iterator_fast(item_eq)
+ { }
+ Item ** ref()
+ {
+ return List_iterator_fast<Item>::ref();
+ }
+};
+
+typedef Item_equal_iterator<List_iterator,Item > Item_equal_iterator_iterator_slow;
+
+class Item_equal_fields_iterator_slow
+ :public Item_equal_iterator_iterator_slow
+{
+public:
+ Item_equal_fields_iterator_slow(Item_equal &item_eq)
+ :Item_equal_iterator_iterator_slow(item_eq)
+ { }
+ void remove()
+ {
+ List_iterator<Item>::remove();
+ }
+};
+
class Item_cond_and :public Item_cond
{
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 8a697fc35f7..c7c8901af79 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -4796,7 +4796,7 @@ void Item_func_set_user_var::save_item_result(Item *item)
{
DBUG_ENTER("Item_func_set_user_var::save_item_result");
- switch (cached_result_type) {
+ switch (args[0]->result_type()) {
case REAL_RESULT:
save_result.vreal= item->val_result();
break;
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index dbc4f9818d5..152b50da616 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1852,7 +1852,8 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
print_where(item, "rewrite with MIN/MAX", QT_ORDINARY););
save_allow_sum_func= thd->lex->allow_sum_func;
- thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
+ thd->lex->allow_sum_func|=
+ (nesting_map)1 << thd->lex->current_select->nest_level;
/*
Item_sum_(max|min) can't substitute other item => we can use 0 as
reference, also Item_sum_(max|min) can't be fixed after creation, so
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 04358ac8c45..72e0e637d38 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -152,9 +152,10 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
If it is there under a construct where it is not allowed
we report an error.
*/
- invalid= !(allow_sum_func & (1 << max_arg_level));
+ invalid= !(allow_sum_func & ((nesting_map)1 << max_arg_level));
}
- else if (max_arg_level >= 0 || !(allow_sum_func & (1 << nest_level)))
+ else if (max_arg_level >= 0 ||
+ !(allow_sum_func & ((nesting_map)1 << nest_level)))
{
/*
The set function can be aggregated only in outer subqueries.
@@ -163,7 +164,8 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref)
*/
if (register_sum_func(thd, ref))
return TRUE;
- invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level));
+ invalid= aggr_level < 0 &&
+ !(allow_sum_func & ((nesting_map)1 << nest_level));
if (!invalid && thd->variables.sql_mode & MODE_ANSI)
invalid= aggr_level < 0 && max_arg_level < nest_level;
}
@@ -311,14 +313,15 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
sl && sl->nest_level > max_arg_level;
sl= sl->master_unit()->outer_select() )
{
- if (aggr_level < 0 && (allow_sum_func & (1 << sl->nest_level)))
+ if (aggr_level < 0 &&
+ (allow_sum_func & ((nesting_map)1 << sl->nest_level)))
{
/* Found the most nested subquery where the function can be aggregated */
aggr_level= sl->nest_level;
aggr_sel= sl;
}
}
- if (sl && (allow_sum_func & (1 << sl->nest_level)))
+ if (sl && (allow_sum_func & ((nesting_map)1 << sl->nest_level)))
{
/*
We reached the subquery of level max_arg_level and checked
@@ -559,7 +562,7 @@ void Item_sum::update_used_tables ()
used_tables_cache&= PSEUDO_TABLE_BITS;
// the aggregate function is aggregated into its local context
- used_tables_cache |= (1 << aggr_sel->join->table_count) - 1;
+ used_tables_cache|= ((table_map)1 << aggr_sel->join->tables) - 1;
} because if we do it, table elimination will assume that
- constructs like "COUNT(*)" use columns from all tables
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index 5a824e48b7b..723429f107a 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -2704,8 +2704,12 @@ int xml_enter(MY_XML_PARSER *st,const char *attr, size_t len)
node.parent= data->parent; // Set parent for the new node to old parent
data->parent= numnodes; // Remember current node as new parent
+ DBUG_ASSERT(data->level <= MAX_LEVEL);
data->pos[data->level]= numnodes;
- node.level= data->level++;
+ if (data->level < MAX_LEVEL)
+ node.level= data->level++;
+ else
+ return MY_XML_ERROR;
node.type= st->current_node_type; // TAG or ATTR
node.beg= attr;
node.end= attr + len;
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 21c1f56a4ae..e9f79bc1354 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -4718,10 +4718,21 @@ do_server_version_split(char* version,
for (uint i= 0; i<=2; i++)
{
number= strtoul(p, &r, 10);
- split_versions->ver[i]= (uchar) number;
- DBUG_ASSERT(number < 256); // fit in uchar
+ /*
+ It is an invalid version if any version number greater than 255 or
+ first number is not followed by '.'.
+ */
+ if (number < 256 && (*r == '.' || i != 0))
+ split_versions->ver[i]= (uchar) number;
+ else
+ {
+ split_versions->ver[0]= 0;
+ split_versions->ver[1]= 0;
+ split_versions->ver[2]= 0;
+ break;
+ }
+
p= r;
- DBUG_ASSERT(!((i == 0) && (*r != '.'))); // should be true in practice
if (*r == '.')
p++; // skip the dot
}
@@ -4739,7 +4750,6 @@ do_server_version_split(char* version,
into 'server_version_split':
X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
X.Yabc -> {X,Y,0}
- Xabc -> {X,0,0}
'server_version_split' is then used for lookups to find if the server which
created this event has some known bug.
*/
diff --git a/sql/log_event.h b/sql/log_event.h
index 2c2e1dcd8b9..99c9a0fb1d7 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -1081,7 +1081,7 @@ public:
return thd ? thd->db : 0;
}
#else
- Log_event() : temp_buf(0) {}
+ Log_event() : temp_buf(0), flags(0) {}
/* avoid having to link mysqlbinlog against libpthread */
static Log_event* read_log_event(IO_CACHE* file,
const Format_description_log_event
@@ -2417,12 +2417,26 @@ public:
#ifdef MYSQL_SERVER
bool write(IO_CACHE* file);
#endif
- bool is_valid() const
+ bool header_is_valid() const
{
return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN :
LOG_EVENT_MINIMAL_HEADER_LEN)) &&
(post_header_len != NULL));
}
+
+ bool version_is_valid() const
+ {
+ /* It is invalid only when all version numbers are 0 */
+ return !(server_version_split.ver[0] == 0 &&
+ server_version_split.ver[1] == 0 &&
+ server_version_split.ver[2] == 0);
+ }
+
+ bool is_valid() const
+ {
+ return header_is_valid() && version_is_valid();
+ }
+
int get_data_size()
{
/*
diff --git a/sql/mdl.h b/sql/mdl.h
index 0f99b759c0e..a951ef40d83 100644
--- a/sql/mdl.h
+++ b/sql/mdl.h
@@ -242,8 +242,14 @@ public:
const char *db, const char *name)
{
m_ptr[0]= (char) mdl_namespace;
- m_db_name_length= (uint16) (strmov(m_ptr + 1, db) - m_ptr - 1);
- m_length= (uint16) (strmov(m_ptr + m_db_name_length + 2, name) - m_ptr + 1);
+ /*
+ It is responsibility of caller to ensure that db and object names
+ are not longer than NAME_LEN. Still we play safe and try to avoid
+ buffer overruns.
+ */
+ m_db_name_length= (uint16) (strmake(m_ptr + 1, db, NAME_LEN) - m_ptr - 1);
+ m_length= (uint16) (strmake(m_ptr + m_db_name_length + 2, name, NAME_LEN) -
+ m_ptr + 1);
}
void mdl_key_init(const MDL_key *rhs)
{
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 0d4b1168bf6..ce8431fbcbd 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1354,6 +1354,7 @@ static void clean_up(bool print_message);
static int test_if_case_insensitive(const char *dir_name);
#ifndef EMBEDDED_LIBRARY
+static bool pid_file_created= false;
static void usage(void);
static void start_signal_handler(void);
static void close_server_sock();
@@ -1362,6 +1363,7 @@ static void wait_for_signal_thread_to_end(void);
static void create_pid_file();
static void mysqld_exit(int exit_code) __attribute__((noreturn));
#endif
+static void delete_pid_file(myf flags);
static void end_ssl();
@@ -1919,7 +1921,6 @@ void clean_up(bool print_message)
item_user_lock_free();
lex_free(); /* Free some memory */
item_create_cleanup();
- free_charsets();
if (!opt_noacl)
{
#ifdef HAVE_DLOPEN
@@ -1966,10 +1967,8 @@ void clean_up(bool print_message)
debug_sync_end();
#endif /* defined(ENABLED_DEBUG_SYNC) */
-#if !defined(EMBEDDED_LIBRARY)
- if (!opt_bootstrap)
- mysql_file_delete(key_file_pid, pidfile_name, MYF(0)); // This may not always exist
-#endif
+ delete_pid_file(MYF(0));
+
if (print_message && my_default_lc_messages && server_start_time)
sql_print_information(ER_DEFAULT(ER_SHUTDOWN_COMPLETE),my_progname);
cleanup_errmsgs();
@@ -1983,6 +1982,7 @@ void clean_up(bool print_message)
sys_var_end();
my_atomic_rwlock_destroy(&global_query_id_lock);
my_atomic_rwlock_destroy(&thread_running_lock);
+ free_charsets();
mysql_mutex_lock(&LOCK_thread_count);
DBUG_PRINT("quit", ("got thread count lock"));
ready_to_exit=1;
@@ -3337,14 +3337,7 @@ pthread_handler_t handle_shutdown(void *arg)
}
#endif
-const char *load_default_groups[]= {
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-"mysql_cluster",
-#endif
-"mysqld", "server", MYSQL_BASE_VERSION,
-"mariadb", MARIADB_BASE_VERSION,
-"client-server",
-0, 0};
+#include <mysqld_default_groups.h>
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
static const int load_default_groups_sz=
@@ -5612,9 +5605,7 @@ int mysqld_main(int argc, char **argv)
(void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
-
- if (!opt_bootstrap)
- mysql_file_delete(key_file_pid, pidfile_name, MYF(MY_WME)); // Not needed anymore
+ delete_pid_file(MYF(MY_WME));
if (unix_sock != INVALID_SOCKET)
unlink(mysqld_unix_port);
@@ -8090,7 +8081,7 @@ static int mysql_init_variables(void)
log_error_file_ptr= log_error_file;
protocol_version= PROTOCOL_VERSION;
what_to_log= ~ (1L << (uint) COM_TIME);
- refresh_version= 1L; /* Increments on each reload */
+ refresh_version= 2L; /* Increments on each reload. 0 and 1 are reserved */
executed_events= 0;
global_query_id= thread_id= 1L;
my_atomic_rwlock_init(&global_query_id_lock);
@@ -9098,13 +9089,14 @@ static void create_pid_file()
if ((file= mysql_file_create(key_file_pid, pidfile_name, 0664,
O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
{
- char buff[21], *end;
+ char buff[MAX_BIGINT_WIDTH + 1], *end;
end= int10_to_str((long) getpid(), buff, 10);
*end++= '\n';
if (!mysql_file_write(file, (uchar*) buff, (uint) (end-buff),
MYF(MY_WME | MY_NABP)))
{
mysql_file_close(file, MYF(0));
+ pid_file_created= true;
return;
}
mysql_file_close(file, MYF(0));
@@ -9114,6 +9106,26 @@ static void create_pid_file()
}
#endif /* EMBEDDED_LIBRARY */
+
+/**
+ Remove the process' pid file.
+
+ @param flags file operation flags
+*/
+
+static void delete_pid_file(myf flags)
+{
+#ifndef EMBEDDED_LIBRARY
+ if (pid_file_created)
+ {
+ mysql_file_delete(key_file_pid, pidfile_name, flags);
+ pid_file_created= false;
+ }
+#endif /* EMBEDDED_LIBRARY */
+ return;
+}
+
+
/** Clear most status variables. */
void refresh_status(THD *thd)
{
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index cb25ca7760e..36da59fd6ef 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -11685,7 +11685,8 @@ static bool get_constant_key_infix(KEY *index_info, SEL_ARG *index_range_tree,
KEY_PART_INFO **first_non_infix_part);
static bool
check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
- Field::imagetype image_type);
+ Field::imagetype image_type,
+ bool *has_min_max_fld, bool *has_other_fld);
static void
cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts,
@@ -12025,6 +12026,13 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
else
goto next_index;
}
+ /*
+ This function is called on the precondition that the index is covering.
+ Therefore if the GROUP BY list contains more elements than the index,
+ these are duplicates. The GROUP BY list cannot be a prefix of the index.
+ */
+ if (cur_part == end_part && tmp_group)
+ goto next_index;
}
/*
Check (GA2) if this is a DISTINCT query.
@@ -12078,7 +12086,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
cur_parts have bits set for only used keyparts.
*/
ulonglong all_parts, cur_parts;
- all_parts= (1<<max_key_part) - 1;
+ all_parts= (1ULL << max_key_part) - 1;
cur_parts= used_key_parts_map.to_ulonglong() >> 1;
if (all_parts != cur_parts)
goto next_index;
@@ -12235,10 +12243,12 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
DBUG_RETURN(NULL);
/* Check (SA3) for the where clause. */
+ bool has_min_max_fld= false, has_other_fld= false;
if (join->conds && min_max_arg_item &&
!check_group_min_max_predicates(join->conds, min_max_arg_item,
(index_info->flags & HA_SPATIAL) ?
- Field::itMBR : Field::itRAW))
+ Field::itMBR : Field::itRAW,
+ &has_min_max_fld, &has_other_fld))
DBUG_RETURN(NULL);
/*
@@ -12286,16 +12296,24 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
SYNOPSIS
check_group_min_max_predicates()
- cond tree (or subtree) describing all or part of the WHERE
- clause being analyzed
- min_max_arg_item the field referenced by the MIN/MAX function(s)
- min_max_arg_part the keypart of the MIN/MAX argument if any
+ cond [in] the expression tree being analyzed
+ min_max_arg [in] the field referenced by the MIN/MAX function(s)
+ image_type [in]
+ has_min_max_arg [out] true if the subtree being analyzed references min_max_arg
+ has_other_arg [out] true if the subtree being analyzed references a column
+ other min_max_arg
DESCRIPTION
The function walks recursively over the cond tree representing a WHERE
clause, and checks condition (SA3) - if a field is referenced by a MIN/MAX
aggregate function, it is referenced only by one of the following
- predicates: {=, !=, <, <=, >, >=, between, is null, is not null}.
+ predicates $FUNC$:
+ {=, !=, <, <=, >, >=, between, is [not] null, multiple equal}.
+ In addition the function checks that the WHERE condition is equivalent to
+ "cond1 AND cond2" where :
+ cond1 - does not use min_max_column at all.
+ cond2 - is an AND/OR tree with leaves in form
+ "$FUNC$(min_max_column[, const])".
RETURN
TRUE if cond passes the test
@@ -12304,7 +12322,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
static bool
check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
- Field::imagetype image_type)
+ Field::imagetype image_type,
+ bool *has_min_max_arg, bool *has_other_arg)
{
DBUG_ENTER("check_group_min_max_predicates");
DBUG_ASSERT(cond && min_max_arg_item);
@@ -12316,12 +12335,24 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
DBUG_PRINT("info", ("Analyzing: %s", ((Item_func*) cond)->func_name()));
List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
Item *and_or_arg;
+ Item_func::Functype func_type= ((Item_cond*) cond)->functype();
+ bool has_min_max= false, has_other= false;
while ((and_or_arg= li++))
{
- if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item,
- image_type))
+ /*
+ The WHERE clause doesn't pass the condition if:
+ (1) any subtree doesn't pass the condition or
+ (2) the subtree passes the test, but it is an OR and it references both
+ the min/max argument and other columns.
+ */
+ if (!check_group_min_max_predicates(and_or_arg, min_max_arg_item, //1
+ image_type,
+ &has_min_max, &has_other) ||
+ (func_type == Item_func::COND_OR_FUNC && has_min_max && has_other))//2
DBUG_RETURN(FALSE);
}
+ *has_min_max_arg= has_min_max || *has_min_max_arg;
+ *has_other_arg= has_other || *has_other_arg;
DBUG_RETURN(TRUE);
}
@@ -12355,6 +12386,10 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
if (cond_type == Item::FIELD_ITEM)
{
DBUG_PRINT("info", ("Analyzing: %s", cond->full_name()));
+ if (min_max_arg_item->eq((Item_field*)cond, 1))
+ *has_min_max_arg= true;
+ else
+ *has_other_arg= true;
DBUG_RETURN(TRUE);
}
@@ -12363,9 +12398,33 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
/* Test if cond references only group-by or non-group fields. */
Item_func *pred= (Item_func*) cond;
+ Item_func::Functype pred_type= pred->functype();
+ DBUG_PRINT("info", ("Analyzing: %s", pred->func_name()));
+ if (pred_type == Item_func::MULT_EQUAL_FUNC)
+ {
+ /*
+ Check that each field in a multiple equality is either a constant or
+ it is a reference to the min/max argument, or it doesn't contain the
+ min/max argument at all.
+ */
+ Item_equal_fields_iterator eq_it(*((Item_equal*)pred));
+ Item *eq_item;
+ bool has_min_max= false, has_other= false;
+ while ((eq_item= eq_it++))
+ {
+ if (min_max_arg_item->eq(eq_item->real_item(), 1))
+ has_min_max= true;
+ else
+ has_other= true;
+ }
+ *has_min_max_arg= has_min_max || *has_min_max_arg;
+ *has_other_arg= has_other || *has_other_arg;
+ DBUG_RETURN(!(has_min_max && has_other));
+ }
+
Item **arguments= pred->arguments();
Item *cur_arg;
- DBUG_PRINT("info", ("Analyzing: %s", pred->func_name()));
+ bool has_min_max= false, has_other= false;
for (uint arg_idx= 0; arg_idx < pred->argument_count (); arg_idx++)
{
cur_arg= arguments[arg_idx]->real_item();
@@ -12374,11 +12433,11 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
{
if (min_max_arg_item->eq(cur_arg, 1))
{
- /*
- If pred references the MIN/MAX argument, check whether pred is a range
- condition that compares the MIN/MAX argument with a constant.
- */
- Item_func::Functype pred_type= pred->functype();
+ has_min_max= true;
+ /*
+ If pred references the MIN/MAX argument, check whether pred is a range
+ condition that compares the MIN/MAX argument with a constant.
+ */
if (pred_type != Item_func::EQUAL_FUNC &&
pred_type != Item_func::LT_FUNC &&
pred_type != Item_func::LE_FUNC &&
@@ -12418,14 +12477,16 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
min_max_arg_item->field->cmp_type() != args[1]->result_type())))
DBUG_RETURN(FALSE);
}
+ else
+ has_other= true;
}
else if (cur_arg->type() == Item::FUNC_ITEM)
{
- if (!check_group_min_max_predicates(cur_arg, min_max_arg_item,
- image_type))
+ if (!check_group_min_max_predicates(cur_arg, min_max_arg_item, image_type,
+ &has_min_max, &has_other))
DBUG_RETURN(FALSE);
}
- else if (cur_arg->const_item())
+ else if (cur_arg->const_item() && !cur_arg->is_expensive())
{
/*
For predicates of the form "const OP expr" we also have to check 'expr'
@@ -12435,7 +12496,11 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
}
else
DBUG_RETURN(FALSE);
+ if(has_min_max && has_other)
+ DBUG_RETURN(FALSE);
}
+ *has_min_max_arg= has_min_max || *has_min_max_arg;
+ *has_other_arg= has_other || *has_other_arg;
DBUG_RETURN(TRUE);
}
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 753722fac08..dfe2ece76d9 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -2542,6 +2542,10 @@ void advance_sj_state(JOIN *join, table_map remaining_tables, uint idx,
/* Mark strategy as used */
(*strategy)->mark_used();
pos->sj_strategy= sj_strategy;
+ if (sj_strategy == SJ_OPT_MATERIALIZE)
+ join->sjm_lookup_tables |= handled_fanout;
+ else
+ join->sjm_lookup_tables &= ~handled_fanout;
*current_read_time= read_time;
*current_record_count= rec_count;
join->cur_dups_producing_tables &= ~handled_fanout;
@@ -3066,6 +3070,13 @@ void restore_prev_sj_state(const table_map remaining_tables,
const JOIN_TAB *tab, uint idx)
{
TABLE_LIST *emb_sj_nest;
+
+ if (tab->emb_sj_nest)
+ {
+ table_map subq_tables= tab->emb_sj_nest->sj_inner_tables;
+ tab->join->sjm_lookup_tables &= ~subq_tables;
+ }
+
if ((emb_sj_nest= tab->emb_sj_nest))
{
/* If we're removing the last SJ-inner table, remove the sj-nest */
@@ -3243,6 +3254,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
uint tablenr;
table_map remaining_tables= 0;
table_map handled_tabs= 0;
+ join->sjm_lookup_tables= 0;
for (tablenr= table_count - 1 ; tablenr != join->const_tables - 1; tablenr--)
{
POSITION *pos= join->best_positions + tablenr;
@@ -3268,6 +3280,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
first= tablenr - sjm->tables + 1;
join->best_positions[first].n_sj_tables= sjm->tables;
join->best_positions[first].sj_strategy= SJ_OPT_MATERIALIZE;
+ join->sjm_lookup_tables|= s->table->map;
}
else if (pos->sj_strategy == SJ_OPT_MATERIALIZE_SCAN)
{
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc
index 069fac1c3ec..c83e52fe26b 100644
--- a/sql/rpl_utility.cc
+++ b/sql/rpl_utility.cc
@@ -878,8 +878,13 @@ TABLE *table_def::create_conversion_table(THD *thd, Relay_log_info *rli, TABLE *
DBUG_ENTER("table_def::create_conversion_table");
List<Create_field> field_list;
-
- for (uint col= 0 ; col < size() ; ++col)
+ /*
+ At slave, columns may differ. So we should create
+ min(columns@master, columns@slave) columns in the
+ conversion table.
+ */
+ uint const cols_to_create= min(target_table->s->fields, size());
+ for (uint col= 0 ; col < cols_to_create; ++col)
{
Create_field *field_def=
(Create_field*) alloc_root(thd->mem_root, sizeof(Create_field));
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index d3b7e651b62..656402f1d04 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -4989,13 +4989,13 @@ ER_WRONG_NAME_FOR_CATALOG 42000
spa "Nombre de catalog incorrecto '%-.100s'"
swe "Felaktigt katalog namn '%-.100s'"
ER_WARN_QC_RESIZE
- eng "Query cache failed to set size %lu; new query cache size is %lu"
- ger "Änderung der Query-Cache-Größe auf %lu fehlgeschlagen; neue Query-Cache-Größe ist %lu"
- por "Falha em Query cache para configurar tamanho %lu, novo tamanho de query cache é %lu"
- rus "Кеш запроÑов не может уÑтановить размер %lu, новый размер кеша зпроÑов - %lu"
- spa "Query cache fallada para configurar tamaño %lu, nuevo tamaño de query cache es %lu"
- swe "Storleken av "Query cache" kunde inte sättas till %lu, ny storlek är %lu"
- ukr "Кеш запитів неÑпроможен вÑтановити розмір %lu, новий розмір кеша запитів - %lu"
+ eng "Query cache failed to set size %llu; new query cache size is %lu"
+ ger "Änderung der Query-Cache-Größe auf %llu fehlgeschlagen; neue Query-Cache-Größe ist %lu"
+ por "Falha em Query cache para configurar tamanho %llu, novo tamanho de query cache é %lu"
+ rus "Кеш запроÑов не может уÑтановить размер %llu, новый размер кеша зпроÑов - %lu"
+ spa "Query cache fallada para configurar tamaño %llu, nuevo tamaño de query cache es %lu"
+ swe "Storleken av "Query cache" kunde inte sättas till %llu, ny storlek är %lu"
+ ukr "Кеш запитів неÑпроможен вÑтановити розмір %llu, новий розмір кеша запитів - %lu"
ER_BAD_FT_COLUMN
eng "Column '%-.192s' cannot be part of FULLTEXT index"
ger "Feld '%-.192s' kann nicht Teil eines FULLTEXT-Index sein"
diff --git a/sql/slave.cc b/sql/slave.cc
index 7e082971d6c..89a325efb53 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1337,6 +1337,7 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
unavailable (very old master not supporting UNIX_TIMESTAMP()?).
*/
+#ifdef ENABLED_DEBUG_SYNC
DBUG_EXECUTE_IF("dbug.before_get_UNIX_TIMESTAMP",
{
const char act[]=
@@ -1346,6 +1347,7 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
DBUG_ASSERT(!debug_sync_set_action(current_thd,
STRING_WITH_LEN(act)));
};);
+#endif
master_res= NULL;
if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT UNIX_TIMESTAMP()")) &&
@@ -1387,6 +1389,7 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
Note: we could have put a @@SERVER_ID in the previous SELECT
UNIX_TIMESTAMP() instead, but this would not have worked on 3.23 masters.
*/
+#ifdef ENABLED_DEBUG_SYNC
DBUG_EXECUTE_IF("dbug.before_get_SERVER_ID",
{
const char act[]=
@@ -1396,6 +1399,7 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi)
DBUG_ASSERT(!debug_sync_set_action(current_thd,
STRING_WITH_LEN(act)));
};);
+#endif
master_res= NULL;
master_row= NULL;
if (!mysql_real_query(mysql,
@@ -3101,6 +3105,7 @@ pthread_handler_t handle_slave_io(void *arg)
connected:
+#ifdef ENABLED_DEBUG_SYNC
DBUG_EXECUTE_IF("dbug.before_get_running_status_yes",
{
const char act[]=
@@ -3110,6 +3115,7 @@ connected:
DBUG_ASSERT(!debug_sync_set_action(thd,
STRING_WITH_LEN(act)));
};);
+#endif
// TODO: the assignment below should be under mutex (5.0)
mi->slave_running= MYSQL_SLAVE_RUN_CONNECT;
diff --git a/sql/spatial.cc b/sql/spatial.cc
index de0b563eaf4..267e038c5b8 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -631,7 +631,7 @@ bool Gis_line_string::get_data_as_wkt(String *txt, const char **end) const
n_points= uint4korr(data);
data += 4;
- if (n_points < 1 ||
+ if (n_points < 1 || n_points > max_n_points ||
no_data(data, POINT_DATA_SIZE * n_points) ||
txt->reserve(((MAX_DIGITS_IN_DOUBLE + 1)*2 + 1) * n_points))
return 1;
@@ -669,7 +669,8 @@ int Gis_line_string::geom_length(double *len, const char **end) const
return 1;
n_points= uint4korr(data);
data+= 4;
- if (n_points < 1 || no_data(data, POINT_DATA_SIZE * n_points))
+ if (n_points < 1 || n_points > max_n_points ||
+ no_data(data, POINT_DATA_SIZE * n_points))
return 1;
get_point(&prev_x, &prev_y, data);
@@ -717,7 +718,7 @@ int Gis_line_string::is_closed(int *closed) const
return 0;
}
data+= 4;
- if (n_points == 0 ||
+ if (n_points == 0 || n_points > max_n_points ||
no_data(data, POINT_DATA_SIZE * n_points))
return 1;
@@ -782,7 +783,8 @@ int Gis_line_string::store_shapes(Gcalc_shape_transporter *trn) const
return 1;
n_points= uint4korr(data);
data+= 4;
- if (n_points < 1 || no_data(data, POINT_DATA_SIZE * n_points))
+ if (n_points < 1 || n_points > max_n_points ||
+ no_data(data, POINT_DATA_SIZE * n_points))
return 1;
trn->start_line();
@@ -966,7 +968,7 @@ bool Gis_polygon::get_data_as_wkt(String *txt, const char **end) const
return 1;
n_points= uint4korr(data);
data+= 4;
- if (no_data(data, POINT_DATA_SIZE * n_points) ||
+ if (n_points > max_n_points || no_data(data, POINT_DATA_SIZE * n_points) ||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1;
txt->qs_append('(');
@@ -1020,7 +1022,7 @@ int Gis_polygon::area(double *ar, const char **end_of_data) const
if (no_data(data, 4))
return 1;
n_points= uint4korr(data);
- if (no_data(data, POINT_DATA_SIZE * n_points))
+ if (n_points > max_n_points || no_data(data, POINT_DATA_SIZE * n_points))
return 1;
get_point(&prev_x, &prev_y, data+4);
data+= (4+POINT_DATA_SIZE);
@@ -1056,7 +1058,8 @@ int Gis_polygon::exterior_ring(String *result) const
n_points= uint4korr(data);
data+= 4;
length= n_points * POINT_DATA_SIZE;
- if (no_data(data, length) || result->reserve(1 + 4 + 4 + length))
+ if (n_points > max_n_points ||
+ no_data(data, length) || result->reserve(1 + 4 + 4 + length))
return 1;
result->q_append((char) wkb_ndr);
@@ -1102,7 +1105,8 @@ int Gis_polygon::interior_ring_n(uint32 num, String *result) const
n_points= uint4korr(data);
points_size= n_points * POINT_DATA_SIZE;
data+= 4;
- if (no_data(data, points_size) || result->reserve(1 + 4 + 4 + points_size))
+ if (n_points > max_n_points ||
+ no_data(data, points_size) || result->reserve(1 + 4 + 4 + points_size))
return 1;
result->q_append((char) wkb_ndr);
@@ -1141,7 +1145,7 @@ int Gis_polygon::centroid_xy(double *x, double *y) const
return 1;
org_n_points= n_points= uint4korr(data);
data+= 4;
- if (no_data(data, POINT_DATA_SIZE * n_points))
+ if (n_points > max_n_points || no_data(data, POINT_DATA_SIZE * n_points))
return 1;
get_point(&prev_x, &prev_y, data);
data+= POINT_DATA_SIZE;
@@ -1215,7 +1219,8 @@ int Gis_polygon::store_shapes(Gcalc_shape_transporter *trn) const
return 1;
n_points= uint4korr(data);
data+= 4;
- if (!n_points || no_data(data, POINT_DATA_SIZE * n_points))
+ if (!n_points || n_points > max_n_points ||
+ no_data(data, POINT_DATA_SIZE * n_points))
return 1;
trn->start_ring();
@@ -1583,7 +1588,7 @@ bool Gis_multi_line_string::get_data_as_wkt(String *txt,
return 1;
n_points= uint4korr(data + WKB_HEADER_SIZE);
data+= WKB_HEADER_SIZE + 4;
- if (no_data(data, n_points * POINT_DATA_SIZE) ||
+ if (n_points > max_n_points || no_data(data, n_points * POINT_DATA_SIZE) ||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points))
return 1;
txt->qs_append('(');
@@ -1905,7 +1910,8 @@ bool Gis_multi_polygon::get_data_as_wkt(String *txt, const char **end) const
return 1;
uint32 n_points= uint4korr(data);
data+= 4;
- if (no_data(data, POINT_DATA_SIZE * n_points) ||
+ if (n_points > max_n_points ||
+ no_data(data, POINT_DATA_SIZE * n_points) ||
txt->reserve(2 + ((MAX_DIGITS_IN_DOUBLE + 1) * 2 + 1) * n_points,
512))
return 1;
@@ -1988,6 +1994,8 @@ int Gis_multi_polygon::geometry_n(uint32 num, String *result) const
if (no_data(data, 4))
return 1;
n_points= uint4korr(data);
+ if (n_points > max_n_points)
+ return 1;
data+= 4 + POINT_DATA_SIZE * n_points;
}
} while (--num);
diff --git a/sql/spatial.h b/sql/spatial.h
index 1277e7bc01c..f55d1ccba8e 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -210,6 +210,11 @@ struct Geometry_buffer;
class Geometry
{
public:
+ // Maximum number of points in feature that can fit into String
+ static const uint32 max_n_points=
+ (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) /
+ POINT_DATA_SIZE;
+
Geometry() {} /* Remove gcc warning */
virtual ~Geometry() {} /* Remove gcc warning */
static void *operator new(size_t size, void *buffer)
@@ -391,10 +396,6 @@ public:
class Gis_line_string: public Geometry
{
- // Maximum number of points in LineString that can fit into String
- static const uint32 max_n_points=
- (uint32) (UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) /
- POINT_DATA_SIZE;
public:
Gis_line_string() {} /* Remove gcc warning */
virtual ~Gis_line_string() {} /* Remove gcc warning */
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index c65e56edbe0..4414a077df8 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -87,6 +87,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
const char **ext;
MY_STAT stat_info;
Open_table_context ot_ctx(thd, (MYSQL_OPEN_IGNORE_FLUSH |
+ MYSQL_OPEN_FOR_REPAIR |
MYSQL_OPEN_HAS_MDL_LOCK |
MYSQL_LOCK_IGNORE_TIMEOUT));
DBUG_ENTER("prepare_for_repair");
@@ -197,7 +198,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
*/
pos_in_locked_tables= table->pos_in_locked_tables;
if (wait_while_table_is_used(thd, table,
- HA_EXTRA_PREPARE_FOR_FORCED_CLOSE))
+ HA_EXTRA_PREPARE_FOR_FORCED_CLOSE,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
goto end;
/* Close table but don't remove from locked list */
close_all_tables_for_name(thd, table_list->table->s,
@@ -589,8 +591,10 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
*/
if (lock_type == TL_WRITE && !table->table->s->tmp_table)
{
+ table->table->s->protect_against_usage();
if (wait_while_table_is_used(thd, table->table,
- HA_EXTRA_PREPARE_FOR_RENAME))
+ HA_EXTRA_PREPARE_FOR_RENAME,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
goto err;
DEBUG_SYNC(thd, "after_admin_flush");
/* Flush entries in the query cache involving this table. */
@@ -739,6 +743,11 @@ send_result_message:
case HA_ADMIN_TRY_ALTER:
{
+ uint save_flags;
+ Alter_info *alter_info= &lex->alter_info;
+
+ /* Store the original value of alter_info->flags */
+ save_flags= alter_info->flags;
/*
This is currently used only by InnoDB. ha_innobase::optimize() answers
"try with alter", so here we close the table, do an ALTER TABLE,
@@ -746,10 +755,19 @@ send_result_message:
We have to end the row, so analyze could return more rows.
*/
protocol->store(STRING_WITH_LEN("note"), system_charset_info);
- protocol->store(STRING_WITH_LEN(
- "Table does not support optimize, doing recreate + analyze instead"),
- system_charset_info);
- if (protocol->write())
+ if(alter_info->flags & ALTER_ADMIN_PARTITION)
+ {
+ protocol->store(STRING_WITH_LEN(
+ "Table does not support optimize on partitions. All partitions "
+ "will be rebuilt and analyzed."),system_charset_info);
+ }
+ else
+ {
+ protocol->store(STRING_WITH_LEN(
+ "Table does not support optimize, doing recreate + analyze instead"),
+ system_charset_info);
+ }
+ if (protocol->write())
goto err;
DBUG_PRINT("info", ("HA_ADMIN_TRY_ALTER, trying analyze..."));
TABLE_LIST *save_next_local= table->next_local,
@@ -768,6 +786,11 @@ send_result_message:
table->mdl_request.ticket= NULL;
DEBUG_SYNC(thd, "ha_admin_open_ltable");
table->mdl_request.set_type(MDL_SHARED_WRITE);
+ /*
+ Reset the ALTER_ADMIN_PARTITION bit in alter_info->flags
+ to force analyze on all partitions.
+ */
+ alter_info->flags &= ~(ALTER_ADMIN_PARTITION);
if ((table->table= open_ltable(thd, table, lock_type, 0)))
{
result_code= table->table->file->ha_analyze(thd, check_opt);
@@ -778,6 +801,7 @@ send_result_message:
}
else
result_code= -1; // open failed
+ alter_info->flags= save_flags;
}
/* Start a new row for the final status row */
protocol->prepare_for_resend();
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index f2e2c31aefd..6483ab283ea 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -330,12 +330,9 @@ uint create_table_def_key(THD *thd, char *key,
const TABLE_LIST *table_list,
bool tmp_table)
{
- char *db_end= strnmov(key, table_list->db, MAX_DBKEY_LENGTH - 2);
- *db_end++= '\0';
- char *table_end= strnmov(db_end, table_list->table_name,
- key + MAX_DBKEY_LENGTH - 1 - db_end);
- *table_end++= '\0';
- uint key_length= (uint) (table_end-key);
+ uint key_length= create_table_def_key(key, table_list->db,
+ table_list->table_name);
+
if (tmp_table)
{
int4store(key + key_length, thd->server_id);
@@ -836,13 +833,10 @@ void release_table_share(TABLE_SHARE *share)
TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name)
{
char key[SAFE_NAME_LEN*2+2];
- TABLE_LIST table_list;
uint key_length;
mysql_mutex_assert_owner(&LOCK_open);
- table_list.db= (char*) db;
- table_list.table_name= (char*) table_name;
- key_length= create_table_def_key((THD*) 0, key, &table_list, 0);
+ key_length= create_table_def_key(key, db, table_name);
return (TABLE_SHARE*) my_hash_search(&table_def_cache,
(uchar*) key, key_length);
}
@@ -1078,7 +1072,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables,
if (share)
{
kill_delayed_threads_for_table(share);
- /* tdc_remove_table() also sets TABLE_SHARE::version to 0. */
+ /* tdc_remove_table() calls share->remove_from_cache_at_close() */
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, table->db,
table->table_name, TRUE);
found=1;
@@ -2337,7 +2331,8 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *db,
*/
bool wait_while_table_is_used(THD *thd, TABLE *table,
- enum ha_extra_function function)
+ enum ha_extra_function function,
+ enum_tdc_remove_table_type remove_type)
{
DBUG_ENTER("wait_while_table_is_used");
DBUG_PRINT("enter", ("table: '%s' share: 0x%lx db_stat: %u version: %lu",
@@ -2348,7 +2343,7 @@ bool wait_while_table_is_used(THD *thd, TABLE *table,
table->mdl_ticket, thd->variables.lock_wait_timeout))
DBUG_RETURN(TRUE);
- tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN,
+ tdc_remove_table(thd, remove_type,
table->s->db.str, table->s->table_name.str,
FALSE);
/* extra() call must come only after all instances above are closed */
@@ -3094,7 +3089,9 @@ retry_share:
goto err_unlock;
}
- if (!(flags & MYSQL_OPEN_IGNORE_FLUSH))
+ if (!(flags & MYSQL_OPEN_IGNORE_FLUSH) ||
+ (share->protected_against_usage() &&
+ !(flags & MYSQL_OPEN_FOR_REPAIR)))
{
if (share->has_old_version())
{
@@ -3241,7 +3238,7 @@ err_unlock:
TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name)
{
char key[MAX_DBKEY_LENGTH];
- uint key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
+ uint key_length= create_table_def_key(key, db, table_name);
for (TABLE *table= list; table ; table=table->next)
{
@@ -6156,17 +6153,27 @@ TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
}
-bool rm_temporary_table(handlerton *base, char *path)
+/**
+ Delete a temporary table.
+
+ @param base Handlerton for table to be deleted.
+ @param path Path to the table to be deleted (i.e. path
+ to its .frm without an extension).
+
+ @retval false - success.
+ @retval true - failure.
+*/
+
+bool rm_temporary_table(handlerton *base, const char *path)
{
bool error=0;
handler *file;
- char *ext;
+ char frm_path[FN_REFLEN + 1];
DBUG_ENTER("rm_temporary_table");
- strmov(ext= strend(path), reg_ext);
- if (mysql_file_delete(key_file_frm, path, MYF(0)))
+ strxnmov(frm_path, sizeof(frm_path) - 1, path, reg_ext, NullS);
+ if (mysql_file_delete(key_file_frm, frm_path, MYF(0)))
error=1; /* purecov: inspected */
- *ext= 0; // remove extension
file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base);
if (file && file->ha_delete_table(path))
{
@@ -8112,7 +8119,8 @@ bool setup_fields(THD *thd, Item **ref_pointer_array,
thd->mark_used_columns= mark_used_columns;
DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
if (allow_sum_func)
- thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
+ thd->lex->allow_sum_func|=
+ (nesting_map)1 << thd->lex->current_select->nest_level;
thd->where= THD::DEFAULT_WHERE;
save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup;
thd->lex->current_select->is_item_list_lookup= 0;
@@ -9417,6 +9425,7 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
TABLE *table;
TABLE_SHARE *share;
DBUG_ENTER("tdc_remove_table");
+ DBUG_PRINT("enter",("name: %s remove_type: %d", table_name, remove_type));
if (! has_lock)
mysql_mutex_lock(&LOCK_open);
@@ -9429,7 +9438,7 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, table_name,
MDL_EXCLUSIVE));
- key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
+ key_length= create_table_def_key(key, db, table_name);
if ((share= (TABLE_SHARE*) my_hash_search(&table_def_cache,(uchar*) key,
key_length)))
@@ -9442,7 +9451,8 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
{
DBUG_ASSERT(share->used_tables.is_empty());
}
- else if (remove_type == TDC_RT_REMOVE_NOT_OWN)
+ else if (remove_type == TDC_RT_REMOVE_NOT_OWN ||
+ remove_type == TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE)
{
I_P_List_iterator<TABLE, TABLE_share> it2(share->used_tables);
while ((table= it2++))
@@ -9453,8 +9463,8 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
}
#endif
/*
- Set share's version to zero in order to ensure that it gets
- automatically deleted once it is no longer referenced.
+ Mark share to ensure that it gets automatically deleted once
+ it is no longer referenced.
Note that code in TABLE_SHARE::wait_for_old_version() assumes
that marking share as old and removal of its unused tables
@@ -9463,7 +9473,13 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
TDC does not contain old shares which don't have any tables
used.
*/
- share->version= 0;
+ if (remove_type == TDC_RT_REMOVE_NOT_OWN)
+ share->remove_from_cache_at_close();
+ else
+ {
+ /* Ensure that no can open the table while it's used */
+ share->protect_against_usage();
+ }
while ((table= it++))
free_cache_entry(table);
@@ -9543,12 +9559,14 @@ open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias,
{
LEX_STRING pathstr;
File_parser *parser;
- char path[FN_REFLEN];
+ char path[FN_REFLEN+1];
DBUG_ENTER("open_new_frm");
/* Create path with extension */
- pathstr.length= (uint) (strxmov(path, share->normalized_path.str, reg_ext,
- NullS)- path);
+ pathstr.length= (uint) (strxnmov(path, sizeof(path) - 1,
+ share->normalized_path.str,
+ reg_ext,
+ NullS) - path);
pathstr.str= path;
if ((parser= sql_parse_prepare(&pathstr, mem_root, 1)))
diff --git a/sql/sql_base.h b/sql/sql_base.h
index 45d41777fea..110f2abbd1d 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -60,7 +60,8 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
IGNORE_EXCEPT_NON_UNIQUE};
enum enum_tdc_remove_table_type {TDC_RT_REMOVE_ALL, TDC_RT_REMOVE_NOT_OWN,
- TDC_RT_REMOVE_UNUSED};
+ TDC_RT_REMOVE_UNUSED,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE};
/* bits for last argument to remove_table_from_cache() */
#define RTFC_NO_FLAG 0x0000
@@ -81,6 +82,31 @@ uint cached_table_definitions(void);
uint create_table_def_key(THD *thd, char *key,
const TABLE_LIST *table_list,
bool tmp_table);
+
+/**
+ Create a table cache key for non-temporary table.
+
+ @param key Buffer for key (must be at least NAME_LEN*2+2 bytes).
+ @param db Database name.
+ @param table_name Table name.
+
+ @return Length of key.
+
+ @sa create_table_def_key(thd, char *, table_list, bool)
+*/
+
+inline uint
+create_table_def_key(char *key, const char *db, const char *table_name)
+{
+ /*
+ In theory caller should ensure that both db and table_name are
+ not longer than NAME_LEN bytes. In practice we play safe to avoid
+ buffer overruns.
+ */
+ return (uint)(strmake(strmake(key, db, NAME_LEN) + 1, table_name,
+ NAME_LEN) - key + 1);
+}
+
TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key,
uint key_length, uint db_flags, int *error,
my_hash_value_type hash_value);
@@ -128,6 +154,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
*/
#define MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK 0x1000
#define MYSQL_LOCK_NOT_TEMPORARY 0x2000
+#define MYSQL_OPEN_FOR_REPAIR 0x4000
/** Please refer to the internals manual. */
#define MYSQL_OPEN_REOPEN (MYSQL_OPEN_IGNORE_FLUSH |\
@@ -158,7 +185,7 @@ thr_lock_type read_lock_type_for_table(THD *thd,
TABLE_LIST *table_list);
my_bool mysql_rm_tmp_tables(void);
-bool rm_temporary_table(handlerton *base, char *path);
+bool rm_temporary_table(handlerton *base, const char *path);
void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
const MDL_savepoint &start_of_statement_svp);
TABLE_LIST *find_table_in_list(TABLE_LIST *table,
@@ -229,7 +256,9 @@ bool setup_tables_and_check_access(THD *thd,
ulong want_access,
bool full_table_list);
bool wait_while_table_is_used(THD *thd, TABLE *table,
- enum ha_extra_function function);
+ enum ha_extra_function function,
+ enum_tdc_remove_table_type remove_type=
+ TDC_RT_REMOVE_NOT_OWN);
void drop_open_table(THD *thd, TABLE *table, const char *db_name,
const char *table_name);
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 191cc4e01c8..016973ab51a 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -3123,8 +3123,8 @@ void Query_cache::invalidate_table(THD *thd, TABLE_LIST *table_list)
char key[MAX_DBKEY_LENGTH];
uint key_length;
- key_length=(uint) (strmov(strmov(key,table_list->db)+1,
- table_list->table_name) -key)+ 1;
+ key_length= create_table_def_key(key, table_list->db,
+ table_list->table_name);
// We don't store temporary tables => no key_length+=4 ...
invalidate_table(thd, (uchar *)key, key_length);
@@ -3242,8 +3242,8 @@ Query_cache::register_tables_from_list(THD *thd, TABLE_LIST *tables_used,
DBUG_PRINT("qcache", ("view: %s db: %s",
tables_used->view_name.str,
tables_used->view_db.str));
- key_length= (uint) (strmov(strmov(key, tables_used->view_db.str) + 1,
- tables_used->view_name.str) - key) + 1;
+ key_length= create_table_def_key(key, tables_used->view_db.str,
+ tables_used->view_name.str);
/*
There are not callback function for for VIEWs
*/
@@ -4288,14 +4288,13 @@ my_bool Query_cache::move_by_type(uchar **border,
case Query_cache_block::RESULT:
{
DBUG_PRINT("qcache", ("block 0x%lx RES* (%d)", (ulong) block,
- (int) block->type));
+ (int) block->type));
if (*border == 0)
break;
- Query_cache_block *query_block = block->result()->parent(),
- *next = block->next,
- *prev = block->prev;
- Query_cache_block::block_type type = block->type;
+ Query_cache_block *query_block= block->result()->parent();
BLOCK_LOCK_WR(query_block);
+ Query_cache_block *next= block->next, *prev= block->prev;
+ Query_cache_block::block_type type= block->type;
ulong len = block->length, used = block->used;
Query_cache_block *pprev = block->pprev,
*pnext = block->pnext,
@@ -4457,8 +4456,9 @@ uint Query_cache::filename_2_table_key (char *key, const char *path,
*db_length= (filename - dbname) - 1;
DBUG_PRINT("qcache", ("table '%-.*s.%s'", *db_length, dbname, filename));
- DBUG_RETURN((uint) (strmov(strmake(key, dbname, *db_length) + 1,
- filename) -key) + 1);
+ DBUG_RETURN((uint) (strmake(strmake(key, dbname,
+ min(*db_length, NAME_LEN)) + 1,
+ filename, NAME_LEN) - key) + 1);
}
/****************************************************************************
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 319f8b15ae1..898787fa953 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1600,11 +1600,12 @@ void THD::cleanup(void)
#error xid_state in the cache should be replaced by the allocated value
}
#endif
- {
- transaction.xid_state.xa_state= XA_NOTR;
- trans_rollback(this);
- xid_cache_delete(&transaction.xid_state);
- }
+
+ close_temporary_tables(this);
+
+ transaction.xid_state.xa_state= XA_NOTR;
+ trans_rollback(this);
+ xid_cache_delete(&transaction.xid_state);
locked_tables_list.unlock_locked_tables(this);
mysql_ha_cleanup(this);
@@ -1638,7 +1639,6 @@ void THD::cleanup(void)
delete_dynamic(&user_var_events);
my_hash_free(&user_vars);
- close_temporary_tables(this);
sp_cache_clear(&sp_proc_cache);
sp_cache_clear(&sp_func_cache);
@@ -2077,6 +2077,19 @@ void THD::cleanup_after_query()
stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
auto_inc_intervals_in_cur_stmt_for_binlog.empty();
rand_used= 0;
+#ifndef EMBEDDED_LIBRARY
+ /*
+ Clean possible unused INSERT_ID events by current statement.
+ is_update_query() is needed to ignore SET statements:
+ Statements that don't update anything directly and don't
+ used stored functions. This is mostly necessary to ignore
+ statements in binlog between SET INSERT_ID and DML statement
+ which is intended to consume its event (there can be other
+ SET statements between them).
+ */
+ if ((rli_slave || rli_fake) && is_update_query(lex->sql_command))
+ auto_inc_intervals_forced.empty();
+#endif
}
if (first_successful_insert_id_in_cur_stmt > 0)
{
@@ -3338,42 +3351,13 @@ int select_exists_subselect::send_data(List<Item> &items)
int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
{
unit= u;
- List_iterator_fast<my_var> var_li(var_list);
- List_iterator_fast<Item> it(list);
- Item *item;
- my_var *mv;
- Item_func_set_user_var **suv;
if (var_list.elements != list.elements)
{
my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
ER(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT), MYF(0));
return 1;
- }
-
- /*
- Iterate over the destination variables and mark them as being
- updated in this query.
- We need to do this at JOIN::prepare time to ensure proper
- const detection of Item_func_get_user_var that is determined
- by the presence of Item_func_set_user_vars
- */
-
- suv= set_var_items= (Item_func_set_user_var **)
- sql_alloc(sizeof(Item_func_set_user_var *) * list.elements);
-
- while ((mv= var_li++) && (item= it++))
- {
- if (!mv->local)
- {
- *suv= new Item_func_set_user_var(mv->s, item);
- (*suv)->fix_fields(thd, 0);
- }
- else
- *suv= NULL;
- suv++;
- }
-
+ }
return 0;
}
@@ -3693,7 +3677,6 @@ int select_dumpvar::send_data(List<Item> &items)
List_iterator<Item> it(items);
Item *item;
my_var *mv;
- Item_func_set_user_var **suv;
DBUG_ENTER("select_dumpvar::send_data");
if (unit->offset_limit_cnt)
@@ -3706,19 +3689,20 @@ int select_dumpvar::send_data(List<Item> &items)
my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0));
DBUG_RETURN(1);
}
- for (suv= set_var_items; ((mv= var_li++) && (item= it++)); suv++)
+ while ((mv= var_li++) && (item= it++))
{
if (mv->local)
{
- DBUG_ASSERT(!*suv);
if (thd->spcont->set_variable(thd, mv->offset, &item))
DBUG_RETURN(1);
}
else
{
- DBUG_ASSERT(*suv);
- (*suv)->save_item_result(item);
- if ((*suv)->update())
+ Item_func_set_user_var *suv= new Item_func_set_user_var(mv->s, item);
+ suv->save_item_result(item);
+ if (suv->fix_fields(thd, 0))
+ DBUG_RETURN (1);
+ if (suv->update())
DBUG_RETURN (1);
}
}
@@ -4713,9 +4697,14 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state)
bool xid_cache_insert(XID_STATE *xid_state)
{
mysql_mutex_lock(&LOCK_xid_cache);
- DBUG_ASSERT(my_hash_search(&xid_cache, xid_state->xid.key(),
- xid_state->xid.key_length())==0);
- my_bool res=my_hash_insert(&xid_cache, (uchar*)xid_state);
+ if (my_hash_search(&xid_cache, xid_state->xid.key(),
+ xid_state->xid.key_length()))
+ {
+ mysql_mutex_unlock(&LOCK_xid_cache);
+ my_error(ER_XAER_DUPID, MYF(0));
+ return true;
+ }
+ bool res= my_hash_insert(&xid_cache, (uchar*)xid_state);
mysql_mutex_unlock(&LOCK_xid_cache);
return res;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index fc3d3087f2c..d2ed282bf45 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -588,6 +588,9 @@ typedef struct system_variables
ulong wsrep_retry_autocommit;
#endif
double long_query_time_double;
+
+ my_bool pseudo_slave_mode;
+
} SV;
/**
@@ -3320,6 +3323,7 @@ public:
#else
void begin_dataset() {}
#endif
+ virtual void update_used_tables() {}
};
@@ -4059,6 +4063,7 @@ public:
return updated;
}
virtual void abort_result_set();
+ void update_used_tables();
};
class my_var : public Sql_alloc {
@@ -4082,7 +4087,6 @@ public:
class select_dumpvar :public select_result_interceptor {
ha_rows row_count;
- Item_func_set_user_var **set_var_items;
public:
List<my_var> var_list;
select_dumpvar() { var_list.empty(); row_count= 0;}
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
index 8424dd00d93..e97f0e185c6 100644
--- a/sql/sql_join_cache.cc
+++ b/sql/sql_join_cache.cc
@@ -775,7 +775,7 @@ ulong JOIN_CACHE::get_min_join_buffer_size()
tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
{
len+= tab->get_max_used_fieldlength();
- len_last=+ tab->get_used_fieldlength();
+ len_last+= tab->get_used_fieldlength();
}
size_t len_addon= get_record_max_affix_length() +
get_max_key_addon_space_per_record();
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 5d29f9ff5f2..659cf36ff43 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -3867,7 +3867,8 @@ void SELECT_LEX::update_used_tables()
{
for (ORDER *order= order_list.first; order; order= order->next)
(*order->item)->update_used_tables();
- }
+ }
+ join->result->update_used_tables();
}
diff --git a/sql/sql_list.h b/sql/sql_list.h
index b4e0ab84aab..aef2f8d5f25 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -287,13 +287,15 @@ public:
if (node == &end_of_list)
return;
}
- *prev= *last;
+ *prev= &end_of_list;
last= prev;
}
inline void prepand(base_list *list)
{
if (!list->is_empty())
{
+ if (is_empty())
+ last= list->last;
*list->last= first;
first= list->first;
elements+= list->elements;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 117f23afb99..52ca997bef5 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3250,6 +3250,7 @@ end_with_restore_list:
thd->first_successful_insert_id_in_cur_stmt=
thd->first_successful_insert_id_in_prev_stmt;
+#ifdef ENABLED_DEBUG_SYNC
DBUG_EXECUTE_IF("after_mysql_insert",
{
const char act1[]=
@@ -3265,6 +3266,7 @@ end_with_restore_list:
STRING_WITH_LEN(act2)));
};);
DEBUG_SYNC(thd, "after_mysql_insert");
+#endif
break;
}
case SQLCOM_REPLACE_SELECT:
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 7e4fd6bb420..1f5f63c87b5 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -897,6 +897,7 @@ impossible position";
event_type=
(Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET+ev_offset]);
+#ifdef ENABLED_DEBUG_SYNC
DBUG_EXECUTE_IF("dump_thread_wait_before_send_xid",
{
if (event_type == XID_EVENT)
@@ -915,6 +916,7 @@ impossible position";
STRING_WITH_LEN(act2)));
}
});
+#endif
if (event_type == FORMAT_DESCRIPTION_EVENT)
{
current_checksum_alg= get_checksum_alg(packet->ptr() + ev_offset,
@@ -1262,6 +1264,8 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
if (thd->lex->mi.pos)
{
+ if (thd->lex->mi.relay_log_pos)
+ slave_errno=ER_BAD_SLAVE_UNTIL_COND;
mi->rli.until_condition= Relay_log_info::UNTIL_MASTER_POS;
mi->rli.until_log_pos= thd->lex->mi.pos;
/*
@@ -1273,6 +1277,8 @@ int start_slave(THD* thd , Master_info* mi, bool net_report)
}
else if (thd->lex->mi.relay_log_pos)
{
+ if (thd->lex->mi.pos)
+ slave_errno=ER_BAD_SLAVE_UNTIL_COND;
mi->rli.until_condition= Relay_log_info::UNTIL_RELAY_POS;
mi->rli.until_log_pos= thd->lex->mi.relay_log_pos;
strmake(mi->rli.until_log_name, thd->lex->mi.relay_log_name,
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 4fb05fe71c8..e1397b05bff 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2012 Oracle and/or its affiliates.
+/* Copyright (c) 2000, 2013 Oracle and/or its affiliates.
Copyright (c) 2009, 2013 Monty Program Ab.
This program is free software; you can redistribute it and/or modify
@@ -129,9 +129,10 @@ static int return_zero_rows(JOIN *join, select_result *res,
List<Item> &fields, bool send_row,
ulonglong select_options, const char *info,
Item *having, List<Item> &all_fields);
-static COND *build_equal_items(THD *thd, COND *cond,
+static COND *build_equal_items(JOIN *join, COND *cond,
COND_EQUAL *inherited,
List<TABLE_LIST> *join_list,
+ bool ignore_on_conds,
COND_EQUAL **cond_equal_ref);
static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab,
COND *cond,
@@ -147,7 +148,8 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
static COND *optimize_cond(JOIN *join, COND *conds,
List<TABLE_LIST> *join_list,
- Item::cond_result *cond_value,
+ bool ignore_on_conds,
+ Item::cond_result *cond_value,
COND_EQUAL **cond_equal);
bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool create_internal_tmp_table_from_heap2(THD *, TABLE *,
@@ -553,25 +555,25 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array,
ORDER *group, bool *hidden_group_fields)
{
int res;
- nesting_map save_allow_sum_func=thd->lex->allow_sum_func ;
+ st_select_lex *const select= thd->lex->current_select;
+ nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
/*
Need to save the value, so we can turn off only any new non_agg_field_used
additions coming from the WHERE
*/
- const bool saved_non_agg_field_used=
- thd->lex->current_select->non_agg_field_used();
+ const bool saved_non_agg_field_used= select->non_agg_field_used();
DBUG_ENTER("setup_without_group");
- thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
+ thd->lex->allow_sum_func&= ~((nesting_map)1 << select->nest_level);
res= setup_conds(thd, tables, leaves, conds);
/* it's not wrong to have non-aggregated columns in a WHERE */
- thd->lex->current_select->set_non_agg_field_used(saved_non_agg_field_used);
+ select->set_non_agg_field_used(saved_non_agg_field_used);
- thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
+ thd->lex->allow_sum_func|= (nesting_map)1 << select->nest_level;
res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
order);
- thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
+ thd->lex->allow_sum_func&= ~((nesting_map)1 << select->nest_level);
res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
group, hidden_group_fields);
thd->lex->allow_sum_func= save_allow_sum_func;
@@ -720,7 +722,7 @@ JOIN::prepare(Item ***rref_pointer_array,
{
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
thd->where="having clause";
- thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
+ thd->lex->allow_sum_func|= (nesting_map)1 << select_lex_arg->nest_level;
select_lex->having_fix_field= 1;
/*
Wrap alone field in HAVING clause in case it will be outer field of subquery
@@ -1064,7 +1066,8 @@ JOIN::optimize()
if (setup_jtbm_semi_joins(this, join_list, &conds))
DBUG_RETURN(1);
- conds= optimize_cond(this, conds, join_list, &cond_value, &cond_equal);
+ conds= optimize_cond(this, conds, join_list, FALSE,
+ &cond_value, &cond_equal);
if (thd->is_error())
{
@@ -1074,7 +1077,9 @@ JOIN::optimize()
}
{
- having= optimize_cond(this, having, join_list, &having_value, &having_equal);
+ having= optimize_cond(this, having, join_list, TRUE,
+ &having_value, &having_equal);
+
if (thd->is_error())
{
error= 1;
@@ -2187,6 +2192,7 @@ JOIN::exec()
{
List<Item> *columns_list= &fields_list;
int tmp_error;
+
DBUG_ENTER("JOIN::exec");
thd_proc_info(thd, "executing");
@@ -4016,7 +4022,7 @@ add_key_field(JOIN *join,
!(field->table->pos_in_table_list->is_materialized_derived() &&
field->table->created)) ||
(field->table->pos_in_table_list->is_materialized_derived() &&
- !field->table->created)))
+ !field->table->created && !(field->flags & BLOB_FLAG))))
{
optimize= KEY_OPTIMIZE_EQ;
}
@@ -4992,6 +4998,7 @@ static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
}
+
/**
Check for the presence of AGGFN(DISTINCT a) queries that may be subject
to loose index scan.
@@ -5318,6 +5325,8 @@ best_access_path(JOIN *join,
2. we won't get two ref-or-null's
*/
if (!(remaining_tables & keyuse->used_tables) &&
+ s->access_from_tables_is_allowed(keyuse->used_tables,
+ join->sjm_lookup_tables) &&
!(ref_or_null_part && (keyuse->optimize &
KEY_OPTIMIZE_REF_OR_NULL)))
{
@@ -5438,7 +5447,8 @@ best_access_path(JOIN *join,
in ReuseRangeEstimateForRef-3.
*/
if (table->quick_keys.is_set(key) &&
- (const_part & ((1 << table->quick_key_parts[key])-1)) ==
+ (const_part &
+ (((key_part_map)1 << table->quick_key_parts[key])-1)) ==
(((key_part_map)1 << table->quick_key_parts[key])-1) &&
table->quick_n_ranges[key] == 1 &&
records > (double) table->quick_rows[key])
@@ -5602,7 +5612,8 @@ best_access_path(JOIN *join,
*/
if (table->quick_keys.is_set(key) &&
table->quick_key_parts[key] <= max_key_part &&
- const_part & (1 << table->quick_key_parts[key]) &&
+ const_part &
+ ((key_part_map)1 << table->quick_key_parts[key]) &&
table->quick_n_ranges[key] == 1 + test(ref_or_null_part &
const_part) &&
records > (double) table->quick_rows[key])
@@ -7853,7 +7864,9 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
*/
do
{
- if (!(~used_tables & keyuse->used_tables))
+ if (!(~used_tables & keyuse->used_tables) &&
+ j->access_from_tables_is_allowed(keyuse->used_tables,
+ join->sjm_lookup_tables))
{
if (are_tables_local(j, keyuse->val->used_tables()))
{
@@ -7921,7 +7934,9 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
uint i;
for (i=0 ; i < keyparts ; keyuse++,i++)
{
- while (((~used_tables) & keyuse->used_tables) ||
+ while (((~used_tables) & keyuse->used_tables) ||
+ !j->access_from_tables_is_allowed(keyuse->used_tables,
+ join->sjm_lookup_tables) ||
keyuse->keypart == NO_KEYPART ||
(keyuse->keypart !=
(is_hash_join_key_no(key) ?
@@ -7933,7 +7948,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
j->ref.items[i]=keyuse->val; // Save for cond removal
j->ref.cond_guards[i]= keyuse->cond_guard;
if (keyuse->null_rejecting)
- j->ref.null_rejecting |= 1 << i;
+ j->ref.null_rejecting|= (key_part_map)1 << i;
keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables;
if (!keyuse->val->used_tables() && !thd->lex->describe)
{ // Compare against constant
@@ -7972,20 +7987,17 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
ulong key_flags= j->table->actual_key_flags(keyinfo);
if (j->type == JT_CONST)
j->table->const_table= 1;
- else if (((key_flags & (HA_NOSAME | HA_NULL_PART_KEY))!= HA_NOSAME) ||
- keyparts != j->table->actual_n_key_parts(keyinfo) ||
- null_ref_key)
- {
- if (test(key_flags & HA_EXT_NOSAME) && keyparts == keyinfo->ext_key_parts &&
- !null_ref_key)
- j->type= JT_EQ_REF;
- else
- {
- /* Must read with repeat */
- j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF;
- j->ref.null_ref_key= null_ref_key;
- j->ref.null_ref_part= null_ref_part;
- }
+ else if (!((keyparts == keyinfo->key_parts &&
+ ((key_flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)) ||
+ (keyparts > keyinfo->key_parts && // true only for extended keys
+ test(key_flags & HA_EXT_NOSAME) &&
+ keyparts == keyinfo->ext_key_parts)) ||
+ null_ref_key)
+ {
+ /* Must read with repeat */
+ j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF;
+ j->ref.null_ref_key= null_ref_key;
+ j->ref.null_ref_part= null_ref_part;
}
else if (keyuse_uses_no_tables)
{
@@ -8135,9 +8147,9 @@ inline void add_cond_and_fix(THD *thd, Item **e1, Item *e2)
Item *res;
if ((res= new Item_cond_and(*e1, e2)))
{
- *e1= res;
res->fix_fields(thd, 0);
res->update_used_tables();
+ *e1= res;
}
}
else
@@ -8209,7 +8221,7 @@ static void add_not_null_conds(JOIN *join)
{
for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++)
{
- if (tab->ref.null_rejecting & (1 << keypart))
+ if (tab->ref.null_rejecting & ((key_part_map)1 << keypart))
{
Item *item= tab->ref.items[keypart];
Item *notnull;
@@ -10390,7 +10402,6 @@ bool JOIN_TAB::preread_init()
}
-
/**
Build a TABLE_REF structure for index lookup in the temporary table
@@ -11648,7 +11659,9 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
item_equal->n_field_items());
}
- ((Item_cond_and*)cond)->cond_equal= cond_equal;
+ ((Item_cond_and*)cond)->cond_equal.copy(cond_equal);
+ cond_equal.current_level=
+ ((Item_cond_and*)cond)->cond_equal.current_level;
inherited= &(((Item_cond_and*)cond)->cond_equal);
}
/*
@@ -11703,6 +11716,7 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
item_equal->update_used_tables();
set_if_bigger(thd->lex->current_select->max_equal_elems,
item_equal->n_field_items());
+ item_equal->upper_levels= inherited;
return item_equal;
}
@@ -11725,7 +11739,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
set_if_bigger(thd->lex->current_select->max_equal_elems,
item_equal->n_field_items());
}
- and_cond->cond_equal= cond_equal;
+ and_cond->cond_equal.copy(cond_equal);
+ cond_equal.current_level= and_cond->cond_equal.current_level;
args->concat((List<Item> *)&cond_equal.current_level);
return and_cond;
@@ -11807,6 +11822,8 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
@param inherited path to all inherited multiple equality items
@param join_list list of join tables to which the condition
refers to
+ @ignore_on_conds TRUE <-> do not build multiple equalities
+ for on expressions
@param[out] cond_equal_ref pointer to the structure to place built
equalities in
@@ -11814,10 +11831,13 @@ static COND *build_equal_items_for_cond(THD *thd, COND *cond,
pointer to the transformed condition containing multiple equalities
*/
-static COND *build_equal_items(THD *thd, COND *cond, COND_EQUAL *inherited,
+static COND *build_equal_items(JOIN *join, COND *cond,
+ COND_EQUAL *inherited,
List<TABLE_LIST> *join_list,
+ bool ignore_on_conds,
COND_EQUAL **cond_equal_ref)
{
+ THD *thd= join->thd;
COND_EQUAL *cond_equal= 0;
if (cond)
@@ -11842,7 +11862,7 @@ static COND *build_equal_items(THD *thd, COND *cond, COND_EQUAL *inherited,
}
*cond_equal_ref= cond_equal;
- if (join_list)
+ if (join_list && !ignore_on_conds)
{
TABLE_LIST *table;
List_iterator<TABLE_LIST> li(*join_list);
@@ -11857,8 +11877,8 @@ static COND *build_equal_items(THD *thd, COND *cond, COND_EQUAL *inherited,
We can modify table->on_expr because its old value will
be restored before re-execution of PS/SP.
*/
- table->on_expr= build_equal_items(thd, table->on_expr, inherited,
- nested_join_list,
+ table->on_expr= build_equal_items(join, table->on_expr, inherited,
+ nested_join_list, ignore_on_conds,
&table->cond_equal);
}
}
@@ -12055,11 +12075,16 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
Item *item_const= item_equal->get_const();
Item_equal_fields_iterator it(*item_equal);
Item *head;
- DBUG_ASSERT(!cond || cond->type() == Item::COND_ITEM);
-
TABLE_LIST *current_sjm= NULL;
Item *current_sjm_head= NULL;
+ DBUG_ASSERT(!cond ||
+ cond->type() == Item::INT_ITEM ||
+ (cond->type() == Item::FUNC_ITEM &&
+ ((Item_func *) cond)->functype() == Item_func::EQ_FUNC) ||
+ (cond->type() == Item::COND_ITEM &&
+ ((Item_func *) cond)->functype() == Item_func::COND_AND_FUNC));
+
/*
Pick the "head" item: the constant one or the first in the join order
(if the first in the join order happends to be inside an SJM nest, that's
@@ -12134,8 +12159,8 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
if (produce_equality)
{
- if (eq_item)
- eq_list.push_back(eq_item);
+ if (eq_item && eq_list.push_back(eq_item))
+ return 0;
/*
If we're inside an SJM-nest (current_sjm!=NULL), and the multi-equality
@@ -12159,31 +12184,61 @@ Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
current_sjm= field_sjm;
}
- if (!cond)
+ /*
+ We have produced zero, one, or more pair-wise equalities eq_i. We want to
+ return an expression in form:
+
+ cond AND eq_1 AND eq_2 AND eq_3 AND ...
+
+ 'cond' is a parameter for this function, which may be NULL, an Item_int(1),
+ or an Item_func_eq or an Item_cond_and.
+
+ We want to return a well-formed condition: no nested Item_cond_and objects,
+ or Item_cond_and with a single child:
+ - if 'cond' is an Item_cond_and, we add eq_i as its tail
+ - if 'cond' is Item_int(1), we return eq_i
+ - otherwise, we create our own Item_cond_and and put 'cond' at the front of
+ it.
+ - if we have only one condition to return, we don't create an Item_cond_and
+ */
+
+ if (eq_item && eq_list.push_back(eq_item))
+ return 0;
+ COND *res= 0;
+ switch (eq_list.elements)
{
- if (eq_list.is_empty())
+ case 0:
+ res= cond ? cond : new Item_int((longlong) 1, 1);
+ break;
+ case 1:
+ if (!cond || cond->type() == Item::INT_ITEM)
+ res= eq_item;
+ break;
+ default:
+ break;
+ }
+ if (!res)
+ {
+ if (cond)
{
- if (eq_item)
- return eq_item;
- return new Item_int((longlong) 1, 1);
+ if (cond->type() == Item::COND_ITEM)
+ {
+ res= cond;
+ ((Item_cond *) res)->add_at_end(&eq_list);
+ }
+ else if (eq_list.push_front(cond))
+ return 0;
}
- /* eq_item is always set if list is not empty */
- DBUG_ASSERT(eq_item);
- eq_list.push_back(eq_item);
- if (!(cond= new Item_cond_and(eq_list)))
- return 0; // Error
- }
- else
+ }
+ if (!res)
+ res= new Item_cond_and(eq_list);
+ if (res)
{
- if (eq_item)
- eq_list.push_back(eq_item);
- if (!eq_list.is_empty())
- ((Item_cond *) cond)->add_at_head(&eq_list);
+ res->quick_fix_field();
+ res->update_used_tables();
}
- cond->quick_fix_field();
- cond->update_used_tables();
-
- return cond;
+
+ return res;
}
@@ -12286,31 +12341,68 @@ static COND* substitute_for_best_equal_field(JOIN_TAB *context_tab,
if (and_level)
{
+ COND *eq_cond= 0;
List_iterator_fast<Item_equal> it(cond_equal->current_level);
+ bool false_eq_cond= FALSE;
while ((item_equal= it++))
{
- cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
- // This occurs when eliminate_item_equal() founds that cond is
- // always false and substitutes it with Item_int 0.
- // Due to this, value of item_equal will be 0, so just return it.
- if (!cond)
- return org_cond; // Error
- if (cond->type() != Item::COND_ITEM)
+ eq_cond= eliminate_item_equal(eq_cond, cond_equal->upper_levels,
+ item_equal);
+ if (!eq_cond)
+ {
+ eq_cond= 0;
break;
+ }
+ else if (eq_cond->type() == Item::INT_ITEM && !eq_cond->val_bool())
+ {
+ /*
+ This occurs when eliminate_item_equal() founds that cond is
+ always false and substitutes it with Item_int 0.
+ Due to this, value of item_equal will be 0, so just return it.
+ */
+ cond= eq_cond;
+ false_eq_cond= TRUE;
+ break;
+ }
}
- }
- if (cond->type() == Item::COND_ITEM &&
- !((Item_cond*)cond)->argument_list()->elements)
- cond= new Item_int((int32)cond->val_bool());
-
+ if (eq_cond && !false_eq_cond)
+ {
+ /* Insert the generated equalities before all other conditions */
+ if (eq_cond->type() == Item::COND_ITEM)
+ ((Item_cond *) cond)->add_at_head(
+ ((Item_cond *) eq_cond)->argument_list());
+ else
+ {
+ if (cond_list->is_empty())
+ cond= eq_cond;
+ else
+ {
+ /* Do not add an equality condition if it's always true */
+ if (eq_cond->type() != Item::INT_ITEM &&
+ cond_list->push_front(eq_cond))
+ eq_cond= 0;
+ }
+ }
+ }
+ if (!eq_cond)
+ {
+ /*
+ We are out of memory doing the transformation.
+ This is a fatal error now. However we bail out by returning the
+ original condition that we had before we started the transformation.
+ */
+ cond_list->concat((List<Item> *) &cond_equal->current_level);
+ }
+ }
}
else if (cond->type() == Item::FUNC_ITEM &&
((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
{
item_equal= (Item_equal *) cond;
item_equal->sort(&compare_fields_by_table_order, table_join_idx);
+ cond_equal= item_equal->upper_levels;
if (cond_equal && cond_equal->current_level.head() == item_equal)
- cond_equal= 0;
+ cond_equal= cond_equal->upper_levels;
cond= eliminate_item_equal(0, cond_equal, item_equal);
return cond ? cond : org_cond;
}
@@ -13269,7 +13361,8 @@ void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab,
static COND *
-optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
+optimize_cond(JOIN *join, COND *conds,
+ List<TABLE_LIST> *join_list, bool ignore_on_conds,
Item::cond_result *cond_value, COND_EQUAL **cond_equal)
{
THD *thd= join->thd;
@@ -13278,7 +13371,9 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
if (!conds)
{
*cond_value= Item::COND_TRUE;
- build_equal_items(join->thd, NULL, NULL, join_list, cond_equal);
+ if (!ignore_on_conds)
+ build_equal_items(join, NULL, NULL, join_list, ignore_on_conds,
+ cond_equal);
}
else
{
@@ -13291,7 +13386,8 @@ optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
multiple equality contains a constant.
*/
DBUG_EXECUTE("where", print_where(conds, "original", QT_ORDINARY););
- conds= build_equal_items(join->thd, conds, NULL, join_list, cond_equal);
+ conds= build_equal_items(join, conds, NULL, join_list, ignore_on_conds,
+ cond_equal);
DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY););
/* change field = field to field = const for each found field = const */
@@ -13347,7 +13443,61 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
li.remove();
else if (item != new_item)
{
- (void) li.replace(new_item);
+ if (and_level)
+ {
+ /*
+ Take a special care of multiple equality predicates
+ that may be part of 'cond' and 'new_item'.
+ Those multiple equalities that have common members
+ must be merged.
+ */
+ Item_cond_and *cond_and= (Item_cond_and *) cond;
+ List<Item_equal> *cond_equal_items=
+ &cond_and->cond_equal.current_level;
+ List<Item> *cond_and_list= cond_and->argument_list();
+
+ if (new_item->type() == Item::COND_ITEM &&
+ ((Item_cond*) new_item)->functype() == Item_func::COND_AND_FUNC)
+ {
+ Item_cond_and *new_item_and= (Item_cond_and *) new_item;
+ List<Item_equal> *new_item_equal_items=
+ &new_item_and->cond_equal.current_level;
+ List<Item> *new_item_and_list= new_item_and->argument_list();
+ cond_and_list->disjoin((List<Item>*) cond_equal_items);
+ new_item_and_list->disjoin((List<Item>*) new_item_equal_items);
+ Item_equal *equal_item;
+ List_iterator<Item_equal> it(*new_item_equal_items);
+ while ((equal_item= it++))
+ {
+ equal_item->merge_into_list(cond_equal_items);
+ }
+ if (new_item_and_list->is_empty())
+ li.remove();
+ else
+ li.replace(*new_item_and_list);
+ cond_and_list->concat((List<Item>*) cond_equal_items);
+ }
+ else if (new_item->type() == Item::FUNC_ITEM &&
+ ((Item_cond*) new_item)->functype() ==
+ Item_func::MULT_EQUAL_FUNC)
+ {
+ cond_and_list->disjoin((List<Item>*) cond_equal_items);
+ ((Item_equal *) new_item)->merge_into_list(cond_equal_items);
+ li.remove();
+ cond_and_list->concat((List<Item>*) cond_equal_items);
+ }
+ else
+ li.replace(new_item);
+ }
+ else
+ {
+ if (new_item->type() == Item::COND_ITEM &&
+ ((Item_cond*) new_item)->functype() ==
+ ((Item_cond*) cond)->functype())
+ li.replace(*((Item_cond*) new_item)->argument_list());
+ else
+ li.replace(new_item);
+ }
should_fix_fields=1;
}
if (*cond_value == Item::COND_UNDEF)
@@ -14604,11 +14754,11 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
}
else
{
- recinfo->null_bit= 1 << (null_count & 7);
+ recinfo->null_bit= (uint8)1 << (null_count & 7);
recinfo->null_pos= null_count/8;
}
field->move_field(pos,null_flags+null_count/8,
- 1 << (null_count & 7));
+ (uint8)1 << (null_count & 7));
null_count++;
}
else
@@ -15056,7 +15206,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
{
cur_field->move_field(field_pos, (uchar*) null_pos, null_bit);
null_bit<<= 1;
- if (null_bit == (1 << 8))
+ if (null_bit == (uint)1 << 8)
{
++null_pos;
null_bit= 1;
@@ -19103,17 +19253,29 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
if (!keep_quick)
{
select->cleanup();
- /*
- The select object should now be ready for the next use. If it
- is re-used then there exists a backup copy of this join tab
- which has the pointer to it. The join tab will be restored in
- JOIN::reset(). So here we just delete the pointer to it.
- */
- tab->select= NULL;
- // If we deleted the quick select object we need to clear quick_keys
+
+ // If we deleted the quick object we need to clear quick_keys
table->quick_keys.clear_all();
table->intersect_keys.clear_all();
}
+ else
+ {
+ // Need to close the index scan in order to re-use the handler
+ tab->select->quick->range_end();
+ }
+
+ /*
+ The select object is now ready for the next use. To avoid that
+ the select object is used when reading the records in sorted
+ order we set the pointer to it to NULL. The select pointer will
+ be restored from the saved_select pointer when this select
+ operation is completed (@see JOIN::exec). This ensures that it
+ will be re-used when filesort is used by subqueries that are
+ executed multiple times.
+ */
+ tab->saved_select= tab->select;
+ tab->select= NULL;
+
// Restore the output resultset
table->sort.io_cache= tablesort_result_cache;
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index bac29b96c5a..a278899e185 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1,8 +1,8 @@
#ifndef SQL_SELECT_INCLUDED
#define SQL_SELECT_INCLUDED
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2008-2011 Monty Program Ab
+/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
+ Copyright (c) 2008, 2013, Monty Program Ab.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -516,6 +516,16 @@ typedef struct st_join_table {
bool preread_init();
bool is_sjm_nest() { return test(bush_children); }
+
+ bool access_from_tables_is_allowed(table_map used_tables,
+ table_map sjm_lookup_tables)
+ {
+ table_map used_sjm_lookup_tables= used_tables & sjm_lookup_tables;
+ return !used_sjm_lookup_tables ||
+ (emb_sj_nest &&
+ !(used_sjm_lookup_tables & ~emb_sj_nest->sj_inner_tables));
+ }
+
} JOIN_TAB;
@@ -966,6 +976,11 @@ public:
bool hash_join;
bool do_send_rows;
table_map const_table_map;
+ /**
+ Bitmap of semijoin tables that the current partial plan decided
+ to materialize and access by lookups
+ */
+ table_map sjm_lookup_tables;
/*
Constant tables for which we have found a row (as opposed to those for
which we didn't).
@@ -1290,8 +1305,9 @@ public:
outer_ref_cond= pseudo_bits_cond= NULL;
in_to_exists_where= NULL;
in_to_exists_having= NULL;
-
pre_sort_join_tab= NULL;
+ emb_sjm_nest= NULL;
+ sjm_lookup_tables= 0;
}
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 75029a03790..4aba2ee51c5 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -843,7 +843,7 @@ copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
uint32 length= min(to_length, from_length), length2= length;
-#if defined(__i386__)
+#if defined(__i386__) || defined(__x86_64__)
/*
Special loop for i386, it allows to refer to a
non-aligned memory block as UINT32, which makes
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index dfe93cfcc1b..8aac364265d 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2012, Oracle and/or its affiliates.
- Copyright (c) 2010, 2011, Monty Program Ab
+ Copyright (c) 2010, 2013, Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -648,13 +648,6 @@ uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
struct st_global_ddl_log
{
- /*
- We need to adjust buffer size to be able to handle downgrades/upgrades
- where IO_SIZE has changed. We'll set the buffer size such that we can
- handle that the buffer size was upto 4 times bigger in the version
- that wrote the DDL log.
- */
- char file_entry_buf[4*IO_SIZE];
char file_name_str[FN_REFLEN];
char *file_name;
DDL_LOG_MEMORY_ENTRY *first_free;
@@ -682,51 +675,60 @@ mysql_mutex_t LOCK_gdl;
#define DDL_LOG_NUM_ENTRY_POS 0
#define DDL_LOG_NAME_LEN_POS 4
#define DDL_LOG_IO_SIZE_POS 8
+#define DDL_LOG_HEADER_SIZE 12
-/*
- Read one entry from ddl log file
- SYNOPSIS
- read_ddl_log_file_entry()
- entry_no Entry number to read
- RETURN VALUES
- TRUE Error
- FALSE Success
+/**
+ Read one entry from ddl log file.
+ @param[out] file_entry_buf Buffer to read into
+ @param entry_no Entry number to read
+ @param size Number of bytes of the entry to read
+
+ @return Operation status
+ @retval true Error
+ @retval false Success
*/
-static bool read_ddl_log_file_entry(uint entry_no)
+static bool read_ddl_log_file_entry(uchar *file_entry_buf,
+ uint entry_no,
+ uint size)
{
bool error= FALSE;
File file_id= global_ddl_log.file_id;
- uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf;
uint io_size= global_ddl_log.io_size;
DBUG_ENTER("read_ddl_log_file_entry");
+ DBUG_ASSERT(io_size >= size);
- if (mysql_file_pread(file_id, file_entry_buf, io_size, io_size * entry_no,
- MYF(MY_WME)) != io_size)
+ if (mysql_file_pread(file_id, file_entry_buf, size, io_size * entry_no,
+ MYF(MY_WME)) != size)
error= TRUE;
DBUG_RETURN(error);
}
-/*
- Write one entry from ddl log file
- SYNOPSIS
- write_ddl_log_file_entry()
- entry_no Entry number to write
- RETURN VALUES
- TRUE Error
- FALSE Success
+/**
+ Write one entry to ddl log file.
+
+ @param file_entry_buf Buffer to write
+ @param entry_no Entry number to write
+ @param size Number of bytes of the entry to write
+
+ @return Operation status
+ @retval true Error
+ @retval false Success
*/
-static bool write_ddl_log_file_entry(uint entry_no)
+static bool write_ddl_log_file_entry(uchar *file_entry_buf,
+ uint entry_no,
+ uint size)
{
bool error= FALSE;
File file_id= global_ddl_log.file_id;
- char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
+ uint io_size= global_ddl_log.io_size;
DBUG_ENTER("write_ddl_log_file_entry");
+ DBUG_ASSERT(io_size >= size);
- if (mysql_file_pwrite(file_id, (uchar*)file_entry_buf,
- IO_SIZE, IO_SIZE * entry_no, MYF(MY_WME)) != IO_SIZE)
+ if (mysql_file_pwrite(file_id, file_entry_buf, size,
+ io_size * entry_no, MYF(MY_WME)) != size)
error= TRUE;
DBUG_RETURN(error);
}
@@ -745,17 +747,20 @@ static bool write_ddl_log_header()
{
uint16 const_var;
bool error= FALSE;
+ uchar file_entry_buf[DDL_LOG_HEADER_SIZE];
DBUG_ENTER("write_ddl_log_header");
+ DBUG_ASSERT((DDL_LOG_NAME_POS + 3 * global_ddl_log.name_len)
+ <= global_ddl_log.io_size);
- int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NUM_ENTRY_POS],
+ int4store(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS],
global_ddl_log.num_entries);
- const_var= FN_LEN;
- int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_LEN_POS],
+ const_var= global_ddl_log.name_len;
+ int4store(&file_entry_buf[DDL_LOG_NAME_LEN_POS],
(ulong) const_var);
- const_var= IO_SIZE;
- int4store(&global_ddl_log.file_entry_buf[DDL_LOG_IO_SIZE_POS],
+ const_var= global_ddl_log.io_size;
+ int4store(&file_entry_buf[DDL_LOG_IO_SIZE_POS],
(ulong) const_var);
- if (write_ddl_log_file_entry(0UL))
+ if (write_ddl_log_file_entry(file_entry_buf, 0UL, DDL_LOG_HEADER_SIZE))
{
sql_print_error("Error writing ddl log header");
DBUG_RETURN(TRUE);
@@ -795,18 +800,20 @@ static inline void create_ddl_log_file_name(char *file_name)
static uint read_ddl_log_header()
{
- char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
+ char file_entry_buf[DDL_LOG_HEADER_SIZE];
char file_name[FN_REFLEN];
uint entry_no;
bool successful_open= FALSE;
DBUG_ENTER("read_ddl_log_header");
+ DBUG_ASSERT(global_ddl_log.io_size <= IO_SIZE);
create_ddl_log_file_name(file_name);
if ((global_ddl_log.file_id= mysql_file_open(key_file_global_ddl_log,
file_name,
O_RDWR | O_BINARY, MYF(0))) >= 0)
{
- if (read_ddl_log_file_entry(0UL))
+ if (read_ddl_log_file_entry((uchar *) file_entry_buf, 0UL,
+ DDL_LOG_HEADER_SIZE))
{
/* Write message into error log */
sql_print_error("Failed to read ddl log file in recovery");
@@ -819,8 +826,6 @@ static uint read_ddl_log_header()
entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]);
global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]);
global_ddl_log.io_size= uint4korr(&file_entry_buf[DDL_LOG_IO_SIZE_POS]);
- DBUG_ASSERT(global_ddl_log.io_size <=
- sizeof(global_ddl_log.file_entry_buf));
}
else
{
@@ -835,30 +840,22 @@ static uint read_ddl_log_header()
}
-/*
- Read a ddl log entry
- SYNOPSIS
- read_ddl_log_entry()
- read_entry Number of entry to read
- out:entry_info Information from entry
- RETURN VALUES
- TRUE Error
- FALSE Success
- DESCRIPTION
- Read a specified entry in the ddl log
+/**
+ Set ddl log entry struct from buffer
+ @param read_entry Entry number
+ @param file_entry_buf Buffer to use
+ @param ddl_log_entry Entry to be set
+
+ @note Pointers in ddl_log_entry will point into file_entry_buf!
*/
-bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry)
+static void set_ddl_log_entry_from_buf(uint read_entry,
+ uchar *file_entry_buf,
+ DDL_LOG_ENTRY *ddl_log_entry)
{
- char *file_entry_buf= (char*)&global_ddl_log.file_entry_buf;
uint inx;
uchar single_char;
- DBUG_ENTER("read_ddl_log_entry");
-
- if (read_ddl_log_file_entry(read_entry))
- {
- DBUG_RETURN(TRUE);
- }
+ DBUG_ENTER("set_ddl_log_entry_from_buf");
ddl_log_entry->entry_pos= read_entry;
single_char= file_entry_buf[DDL_LOG_ENTRY_TYPE_POS];
ddl_log_entry->entry_type= (enum ddl_log_entry_code)single_char;
@@ -866,14 +863,14 @@ bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry)
ddl_log_entry->action_type= (enum ddl_log_action_code)single_char;
ddl_log_entry->phase= file_entry_buf[DDL_LOG_PHASE_POS];
ddl_log_entry->next_entry= uint4korr(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS]);
- ddl_log_entry->name= &file_entry_buf[DDL_LOG_NAME_POS];
+ ddl_log_entry->name= (char*) &file_entry_buf[DDL_LOG_NAME_POS];
inx= DDL_LOG_NAME_POS + global_ddl_log.name_len;
- ddl_log_entry->from_name= &file_entry_buf[inx];
+ ddl_log_entry->from_name= (char*) &file_entry_buf[inx];
inx+= global_ddl_log.name_len;
- ddl_log_entry->handler_name= &file_entry_buf[inx];
- DBUG_RETURN(FALSE);
+ ddl_log_entry->handler_name= (char*) &file_entry_buf[inx];
+ DBUG_VOID_RETURN;
}
-
+
/*
Initialise ddl log
@@ -1076,6 +1073,7 @@ static bool get_free_ddl_log_entry(DDL_LOG_MEMORY_ENTRY **active_entry,
DDL_LOG_MEMORY_ENTRY *first_used= global_ddl_log.first_used;
DBUG_ENTER("get_free_ddl_log_entry");
+ mysql_mutex_assert_owner(&LOCK_gdl);
if (global_ddl_log.first_free == NULL)
{
if (!(used_entry= (DDL_LOG_MEMORY_ENTRY*)my_malloc(
@@ -1133,34 +1131,36 @@ bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry,
DDL_LOG_MEMORY_ENTRY **active_entry)
{
bool error, write_header;
+ char file_entry_buf[IO_SIZE];
DBUG_ENTER("write_ddl_log_entry");
if (init_ddl_log())
{
DBUG_RETURN(TRUE);
}
- global_ddl_log.file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]=
+ memset(file_entry_buf, 0, sizeof(file_entry_buf));
+ file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]=
(char)DDL_LOG_ENTRY_CODE;
- global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS]=
+ file_entry_buf[DDL_LOG_ACTION_TYPE_POS]=
(char)ddl_log_entry->action_type;
- global_ddl_log.file_entry_buf[DDL_LOG_PHASE_POS]= 0;
- int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NEXT_ENTRY_POS],
+ file_entry_buf[DDL_LOG_PHASE_POS]= 0;
+ int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS],
ddl_log_entry->next_entry);
- DBUG_ASSERT(strlen(ddl_log_entry->name) < FN_LEN);
- strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
- ddl_log_entry->name, FN_LEN - 1);
+ DBUG_ASSERT(strlen(ddl_log_entry->name) < global_ddl_log.name_len);
+ strmake(&file_entry_buf[DDL_LOG_NAME_POS], ddl_log_entry->name,
+ global_ddl_log.name_len - 1);
if (ddl_log_entry->action_type == DDL_LOG_RENAME_ACTION ||
ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION)
{
- DBUG_ASSERT(strlen(ddl_log_entry->from_name) < FN_LEN);
- strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN],
- ddl_log_entry->from_name, FN_LEN - 1);
+ DBUG_ASSERT(strlen(ddl_log_entry->from_name) < global_ddl_log.name_len);
+ strmake(&file_entry_buf[DDL_LOG_NAME_POS + global_ddl_log.name_len],
+ ddl_log_entry->from_name, global_ddl_log.name_len - 1);
}
else
- global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
- DBUG_ASSERT(strlen(ddl_log_entry->handler_name) < FN_LEN);
- strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (2*FN_LEN)],
- ddl_log_entry->handler_name, FN_LEN - 1);
+ file_entry_buf[DDL_LOG_NAME_POS + global_ddl_log.name_len]= 0;
+ DBUG_ASSERT(strlen(ddl_log_entry->handler_name) < global_ddl_log.name_len);
+ strmake(&file_entry_buf[DDL_LOG_NAME_POS + (2*global_ddl_log.name_len)],
+ ddl_log_entry->handler_name, global_ddl_log.name_len - 1);
if (get_free_ddl_log_entry(active_entry, &write_header))
{
DBUG_RETURN(TRUE);
@@ -1168,14 +1168,15 @@ bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry,
error= FALSE;
DBUG_PRINT("ddl_log",
("write type %c next %u name '%s' from_name '%s' handler '%s'",
- (char) global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS],
+ (char) file_entry_buf[DDL_LOG_ACTION_TYPE_POS],
ddl_log_entry->next_entry,
- (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
- (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS
- + FN_LEN],
- (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS
- + (2*FN_LEN)]));
- if (write_ddl_log_file_entry((*active_entry)->entry_pos))
+ (char*) &file_entry_buf[DDL_LOG_NAME_POS],
+ (char*) &file_entry_buf[DDL_LOG_NAME_POS +
+ global_ddl_log.name_len],
+ (char*) &file_entry_buf[DDL_LOG_NAME_POS +
+ (2*global_ddl_log.name_len)]));
+ if (write_ddl_log_file_entry((uchar*) file_entry_buf,
+ (*active_entry)->entry_pos, IO_SIZE))
{
error= TRUE;
sql_print_error("Failed to write entry_no = %u",
@@ -1225,13 +1226,14 @@ bool write_execute_ddl_log_entry(uint first_entry,
DDL_LOG_MEMORY_ENTRY **active_entry)
{
bool write_header= FALSE;
- char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
+ char file_entry_buf[IO_SIZE];
DBUG_ENTER("write_execute_ddl_log_entry");
if (init_ddl_log())
{
DBUG_RETURN(TRUE);
}
+ memset(file_entry_buf, 0, sizeof(file_entry_buf));
if (!complete)
{
/*
@@ -1245,12 +1247,7 @@ bool write_execute_ddl_log_entry(uint first_entry,
}
else
file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_IGNORE_LOG_ENTRY_CODE;
- file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= 0; /* Ignored for execute entries */
- file_entry_buf[DDL_LOG_PHASE_POS]= 0;
int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], first_entry);
- file_entry_buf[DDL_LOG_NAME_POS]= 0;
- file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
- file_entry_buf[DDL_LOG_NAME_POS + 2*FN_LEN]= 0;
if (!(*active_entry))
{
if (get_free_ddl_log_entry(active_entry, &write_header))
@@ -1258,7 +1255,9 @@ bool write_execute_ddl_log_entry(uint first_entry,
DBUG_RETURN(TRUE);
}
}
- if (write_ddl_log_file_entry((*active_entry)->entry_pos))
+ if (write_ddl_log_file_entry((uchar*) file_entry_buf,
+ (*active_entry)->entry_pos,
+ IO_SIZE))
{
sql_print_error("Error writing execute entry in ddl log");
release_ddl_log_memory_entry(*active_entry);
@@ -1303,10 +1302,16 @@ bool write_execute_ddl_log_entry(uint first_entry,
bool deactivate_ddl_log_entry(uint entry_no)
{
- char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
+ uchar file_entry_buf[DDL_LOG_NAME_POS];
DBUG_ENTER("deactivate_ddl_log_entry");
- if (!read_ddl_log_file_entry(entry_no))
+
+ /*
+ Only need to read and write the first bytes of the entry, where
+ ENTRY_TYPE, ACTION_TYPE and PHASE reside. Using DDL_LOG_NAME_POS
+ to include all info except for the names.
+ */
+ if (!read_ddl_log_file_entry(file_entry_buf, entry_no, DDL_LOG_NAME_POS))
{
if (file_entry_buf[DDL_LOG_ENTRY_TYPE_POS] == DDL_LOG_ENTRY_CODE)
{
@@ -1324,7 +1329,7 @@ bool deactivate_ddl_log_entry(uint entry_no)
{
DBUG_ASSERT(0);
}
- if (write_ddl_log_file_entry(entry_no))
+ if (write_ddl_log_file_entry(file_entry_buf, entry_no, DDL_LOG_NAME_POS))
{
sql_print_error("Error in deactivating log entry. Position = %u",
entry_no);
@@ -1385,6 +1390,7 @@ void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry)
DDL_LOG_MEMORY_ENTRY *next_log_entry= log_entry->next_log_entry;
DDL_LOG_MEMORY_ENTRY *prev_log_entry= log_entry->prev_log_entry;
DBUG_ENTER("release_ddl_log_memory_entry");
+ mysql_mutex_assert_owner(&LOCK_gdl);
global_ddl_log.first_free= log_entry;
log_entry->next_log_entry= first_free;
@@ -1414,24 +1420,26 @@ bool execute_ddl_log_entry(THD *thd, uint first_entry)
{
DDL_LOG_ENTRY ddl_log_entry;
uint read_entry= first_entry;
+ uchar file_entry_buf[IO_SIZE];
DBUG_ENTER("execute_ddl_log_entry");
mysql_mutex_lock(&LOCK_gdl);
do
{
- if (read_ddl_log_entry(read_entry, &ddl_log_entry))
+ if (read_ddl_log_file_entry(file_entry_buf, read_entry, IO_SIZE))
{
- /* Write to error log and continue with next log entry */
+ /* Print the error to the log and continue with next log entry */
sql_print_error("Failed to read entry = %u from ddl log",
read_entry);
break;
}
+ set_ddl_log_entry_from_buf(read_entry, file_entry_buf, &ddl_log_entry);
DBUG_ASSERT(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE ||
ddl_log_entry.entry_type == DDL_IGNORE_LOG_ENTRY_CODE);
if (execute_ddl_log_action(thd, &ddl_log_entry))
{
- /* Write to error log and continue with next log entry */
+ /* Print the error to the log and continue with next log entry */
sql_print_error("Failed to execute action for entry = %u from ddl log",
read_entry);
break;
@@ -1476,13 +1484,14 @@ void execute_ddl_log_recovery()
uint num_entries, i;
THD *thd;
DDL_LOG_ENTRY ddl_log_entry;
+ uchar *file_entry_buf;
+ uint io_size;
char file_name[FN_REFLEN];
DBUG_ENTER("execute_ddl_log_recovery");
/*
Initialise global_ddl_log struct
*/
- bzero(global_ddl_log.file_entry_buf, sizeof(global_ddl_log.file_entry_buf));
global_ddl_log.inited= FALSE;
global_ddl_log.recovery_phase= TRUE;
global_ddl_log.io_size= IO_SIZE;
@@ -1497,14 +1506,23 @@ void execute_ddl_log_recovery()
thd->store_globals();
num_entries= read_ddl_log_header();
+ io_size= global_ddl_log.io_size;
+ file_entry_buf= (uchar*) my_malloc(io_size, MYF(0));
+ if (!file_entry_buf)
+ {
+ sql_print_error("Failed to allocate buffer for recover ddl log");
+ DBUG_VOID_RETURN;
+ }
for (i= 1; i < num_entries + 1; i++)
{
- if (read_ddl_log_entry(i, &ddl_log_entry))
+ if (read_ddl_log_file_entry(file_entry_buf, i, io_size))
{
sql_print_error("Failed to read entry no = %u from ddl log",
i);
continue;
}
+
+ set_ddl_log_entry_from_buf(i, file_entry_buf, &ddl_log_entry);
if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE)
{
if (execute_ddl_log_entry(thd, ddl_log_entry.next_entry))
@@ -1519,6 +1537,7 @@ void execute_ddl_log_recovery()
(void) mysql_file_delete(key_file_global_ddl_log, file_name, MYF(0));
global_ddl_log.recovery_phase= FALSE;
delete thd;
+ my_free(file_entry_buf);
/* Remember that we don't have a THD */
my_pthread_setspecific_ptr(THR_THD, 0);
DBUG_VOID_RETURN;
@@ -1535,14 +1554,16 @@ void execute_ddl_log_recovery()
void release_ddl_log()
{
- DDL_LOG_MEMORY_ENTRY *free_list= global_ddl_log.first_free;
- DDL_LOG_MEMORY_ENTRY *used_list= global_ddl_log.first_used;
+ DDL_LOG_MEMORY_ENTRY *free_list;
+ DDL_LOG_MEMORY_ENTRY *used_list;
DBUG_ENTER("release_ddl_log");
if (!global_ddl_log.do_release)
DBUG_VOID_RETURN;
mysql_mutex_lock(&LOCK_gdl);
+ free_list= global_ddl_log.first_free;
+ used_list= global_ddl_log.first_used;
while (used_list)
{
DDL_LOG_MEMORY_ENTRY *tmp= used_list->next_log_entry;
@@ -2190,7 +2211,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
if (thd->locked_tables_mode)
{
- if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED))
+ if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
{
error= -1;
goto err;
@@ -6237,15 +6259,19 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
case LEAVE_AS_IS:
break;
case ENABLE:
- if (wait_while_table_is_used(thd, table, extra_func))
+ if (wait_while_table_is_used(thd, table, extra_func,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
goto err;
DEBUG_SYNC(thd,"alter_table_enable_indexes");
error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
+ table->s->allow_access_to_protected_table();
break;
case DISABLE:
- if (wait_while_table_is_used(thd, table, extra_func))
+ if (wait_while_table_is_used(thd, table, extra_func,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
goto err;
error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
+ table->s->allow_access_to_protected_table();
break;
default:
DBUG_ASSERT(FALSE);
@@ -6277,7 +6303,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
simple rename did nothing and therefore we can safely return
without additional clean-up.
*/
- if (wait_while_table_is_used(thd, table, extra_func))
+ if (wait_while_table_is_used(thd, table, extra_func,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
goto err;
close_all_tables_for_name(thd, table->s, HA_EXTRA_PREPARE_FOR_RENAME);
/*
@@ -6713,6 +6740,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (table->s->tmp_table)
{
Open_table_context ot_ctx(thd, (MYSQL_OPEN_IGNORE_FLUSH |
+ MYSQL_OPEN_FOR_REPAIR |
MYSQL_LOCK_IGNORE_TIMEOUT));
TABLE_LIST tbl;
bzero((void*) &tbl, sizeof(tbl));
@@ -6785,7 +6813,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
table->file->indexes_are_disabled())
need_lock_for_indexes= true;
if (!table->s->tmp_table && need_lock_for_indexes &&
- wait_while_table_is_used(thd, table, extra_func))
+ wait_while_table_is_used(thd, table, extra_func,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
goto err_new_table_cleanup;
thd_proc_info(thd, "manage keys");
DEBUG_SYNC(thd, "alter_table_manage_keys");
@@ -6794,6 +6823,11 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
error= trans_commit_stmt(thd);
if (trans_commit_implicit(thd))
error= 1;
+ /*
+ If the table was locked, allow one to still run SHOW commands against it
+ */
+ if (table->s->protected_against_usage())
+ table->s->allow_access_to_protected_table();
}
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
@@ -7005,7 +7039,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (lower_case_table_names)
my_casedn_str(files_charset_info, old_name);
- if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME))
+ if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
{
if (pending_inplace_add_index)
{
diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc
index a95e560c652..22b5b676420 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -367,7 +367,8 @@ bool Truncate_statement::lock_table(THD *thd, TABLE_LIST *table_ref,
{
DEBUG_SYNC(thd, "upgrade_lock_for_truncate");
/* To remove the table from the cache we need an exclusive lock. */
- if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DROP))
+ if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DROP,
+ TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
DBUG_RETURN(TRUE);
m_ticket_downgrade= table->mdl_ticket;
/* Close if table is going to be recreated. */
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index e24513532e1..5b6278ad4f0 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1595,6 +1595,15 @@ int multi_update::prepare(List<Item> &not_used_values,
DBUG_RETURN(thd->is_fatal_error != 0);
}
+void multi_update::update_used_tables()
+{
+ Item *item;
+ List_iterator_fast<Item> it(*values);
+ while ((item= it++))
+ {
+ item->update_used_tables();
+ }
+}
/*
Check if table is safe to update on fly
diff --git a/sql/strfunc.cc b/sql/strfunc.cc
index 0c0742b3805..f39901a6ca5 100644
--- a/sql/strfunc.cc
+++ b/sql/strfunc.cc
@@ -85,7 +85,7 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs,
*set_warning= 1;
}
else
- found|= ((longlong) 1 << (find - 1));
+ found|= 1ULL << (find - 1);
if (pos >= end)
break;
start= pos + mblen;
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 81ad091cca6..da971516141 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -4043,9 +4043,67 @@ static Sys_var_ulong Sys_debug_binlog_fsync_sleep(
CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1));
#endif
+
static Sys_var_harows Sys_expensive_subquery_limit(
"expensive_subquery_limit",
"The maximum number of rows a subquery may examine in order to be "
"executed during optimization and used for constant optimization",
SESSION_VAR(expensive_subquery_limit), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, HA_POS_ERROR), DEFAULT(100), BLOCK_SIZE(1));
+
+static bool check_pseudo_slave_mode(sys_var *self, THD *thd, set_var *var)
+{
+ longlong previous_val= thd->variables.pseudo_slave_mode;
+ longlong val= (longlong) var->save_result.ulonglong_value;
+ bool rli_fake= false;
+
+#ifndef EMBEDDED_LIBRARY
+ rli_fake= thd->rli_fake ? true : false;
+#endif
+
+ if (rli_fake)
+ {
+ if (!val)
+ {
+#ifndef EMBEDDED_LIBRARY
+ delete thd->rli_fake;
+ thd->rli_fake= NULL;
+#endif
+ }
+ else if (previous_val && val)
+ goto ineffective;
+ else if (!previous_val && val)
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_VALUE_FOR_VAR,
+ "'pseudo_slave_mode' is already ON.");
+ }
+ else
+ {
+ if (!previous_val && !val)
+ goto ineffective;
+ else if (previous_val && !val)
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_VALUE_FOR_VAR,
+ "Slave applier execution mode not active, "
+ "statement ineffective.");
+ }
+ goto end;
+
+ineffective:
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WRONG_VALUE_FOR_VAR,
+ "'pseudo_slave_mode' change was ineffective.");
+
+end:
+ return FALSE;
+}
+static Sys_var_mybool Sys_pseudo_slave_mode(
+ "pseudo_slave_mode",
+ "SET pseudo_slave_mode= 0,1 are commands that mysqlbinlog "
+ "adds to beginning and end of binary log dumps. While zero "
+ "value indeed disables, the actual enabling of the slave "
+ "applier execution mode is done implicitly when a "
+ "Format_description_event is sent through the session.",
+ SESSION_ONLY(pseudo_slave_mode), NO_CMD_LINE, DEFAULT(FALSE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_pseudo_slave_mode));
+
diff --git a/sql/table.cc b/sql/table.cc
index fba45f421ed..c92a096be90 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -323,7 +323,7 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
share->normalized_path.str= share->path.str;
share->normalized_path.length= path_length;
- share->version= refresh_version;
+ share->set_refresh_version();
/*
Since alloc_table_share() can be called without any locking (for
@@ -1003,7 +1003,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
}
}
if (j == first_key_parts)
- keyinfo->ext_key_flags= keyinfo->flags | HA_NOSAME | HA_EXT_NOSAME;
+ keyinfo->ext_key_flags= keyinfo->flags | HA_EXT_NOSAME;
}
share->ext_key_parts+= keyinfo->ext_key_parts;
}
diff --git a/sql/table.h b/sql/table.h
index c21b01f53f7..cfdc0ffd077 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -793,12 +793,42 @@ struct TABLE_SHARE
return table_map_id;
}
-
/** Is this table share being expelled from the table definition cache? */
inline bool has_old_version() const
{
return version != refresh_version;
}
+ inline bool protected_against_usage() const
+ {
+ return version == 0;
+ }
+ inline void protect_against_usage()
+ {
+ version= 0;
+ }
+ /*
+ This is used only for the case of locked tables, as we want to
+ allow one to do SHOW commands on them even after ALTER or REPAIR
+ */
+ inline void allow_access_to_protected_table()
+ {
+ DBUG_ASSERT(version == 0);
+ version= 1;
+ }
+ /*
+ Remove from table definition cache at close.
+ Table can still be opened by SHOW
+ */
+ inline void remove_from_cache_at_close()
+ {
+ if (version != 0) /* Don't remove protection */
+ version= 1;
+ }
+ inline void set_refresh_version()
+ {
+ version= refresh_version;
+ }
+
/**
Convert unrelated members of TABLE_SHARE to one enum
representing its type.
diff --git a/sql/threadpool_unix.cc b/sql/threadpool_unix.cc
index e324fa697da..94251660e37 100644
--- a/sql/threadpool_unix.cc
+++ b/sql/threadpool_unix.cc
@@ -29,14 +29,14 @@
#ifdef __linux__
#include <sys/epoll.h>
typedef struct epoll_event native_event;
-#endif
-#if defined (__FreeBSD__) || defined (__APPLE__)
+#elif defined(HAVE_KQUEUE)
#include <sys/event.h>
typedef struct kevent native_event;
-#endif
-#if defined (__sun)
+#elif defined (__sun)
#include <port.h>
typedef port_event_t native_event;
+#else
+#error threadpool is not available on this platform
#endif
/** Maximum number of native events a listener can read in one go */
@@ -285,7 +285,7 @@ static void *native_event_get_userdata(native_event *event)
return event->data.ptr;
}
-#elif defined (__FreeBSD__) || defined (__APPLE__)
+#elif defined(HAVE_KQUEUE)
int io_poll_create()
{
return kqueue();
@@ -386,8 +386,6 @@ static void* native_event_get_userdata(native_event *event)
{
return event->portev_user;
}
-#else
-#error not ported yet to this OS
#endif
diff --git a/sql/transaction.cc b/sql/transaction.cc
index ef4383df0ea..35d1388f311 100644
--- a/sql/transaction.cc
+++ b/sql/transaction.cc
@@ -603,15 +603,19 @@ bool trans_xa_start(THD *thd)
my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]);
else if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction())
my_error(ER_XAER_OUTSIDE, MYF(0));
- else if (xid_cache_search(thd->lex->xid))
- my_error(ER_XAER_DUPID, MYF(0));
else if (!trans_begin(thd))
{
DBUG_ASSERT(thd->transaction.xid_state.xid.is_null());
thd->transaction.xid_state.xa_state= XA_ACTIVE;
thd->transaction.xid_state.rm_error= 0;
thd->transaction.xid_state.xid.set(thd->lex->xid);
- xid_cache_insert(&thd->transaction.xid_state);
+ if (xid_cache_insert(&thd->transaction.xid_state))
+ {
+ thd->transaction.xid_state.xa_state= XA_NOTR;
+ thd->transaction.xid_state.xid.null();
+ trans_rollback(thd);
+ DBUG_RETURN(true);
+ }
DBUG_RETURN(FALSE);
}
@@ -697,6 +701,16 @@ bool trans_xa_commit(THD *thd)
if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
{
+ /*
+ xid_state.in_thd is always true beside of xa recovery procedure.
+ Note, that there is no race condition here between xid_cache_search
+ and xid_cache_delete, since we always delete our own XID
+ (thd->lex->xid == thd->transaction.xid_state.xid).
+ The only case when thd->lex->xid != thd->transaction.xid_state.xid
+ and xid_state->in_thd == 0 is in the function
+ xa_cache_insert(XID, xa_states), which is called before starting
+ client connections, and thus is always single-threaded.
+ */
XID_STATE *xs= xid_cache_search(thd->lex->xid);
res= !xs || xs->in_thd;
if (res)
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 8194367a7f9..0e793290bba 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -1856,7 +1856,7 @@ static Time_zone*
tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
{
TABLE *table= 0;
- TIME_ZONE_INFO *tz_info;
+ TIME_ZONE_INFO *tz_info= NULL;
Tz_names_entry *tmp_tzname;
Time_zone *return_val= 0;
int res;
@@ -1866,7 +1866,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
uchar keybuff[32];
Field *field;
String abbr(buff, sizeof(buff), &my_charset_latin1);
- char *alloc_buff, *tz_name_buff;
+ char *alloc_buff= NULL;
+ char *tz_name_buff= NULL;
/*
Temporary arrays that are used for loading of data for filling
TIME_ZONE_INFO structure
@@ -1886,22 +1887,6 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
DBUG_ENTER("tz_load_from_open_tables");
- /* Prepare tz_info for loading also let us make copy of time zone name */
- if (!(alloc_buff= (char*) alloc_root(&tz_storage, sizeof(TIME_ZONE_INFO) +
- tz_name->length() + 1)))
- {
- sql_print_error("Out of memory while loading time zone description");
- return 0;
- }
- tz_info= (TIME_ZONE_INFO *)alloc_buff;
- bzero(tz_info, sizeof(TIME_ZONE_INFO));
- tz_name_buff= alloc_buff + sizeof(TIME_ZONE_INFO);
- /*
- By writing zero to the end we guarantee that we can call ptr()
- instead of c_ptr() for time zone name.
- */
- strmake(tz_name_buff, tz_name->ptr(), tz_name->length());
-
/*
Let us find out time zone id by its name (there is only one index
and it is specifically for this purpose).
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index e705d1dd615..f5b96989811 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -909,10 +909,11 @@ int ha_archive::write_row(uchar *buf)
table->timestamp_field->set_time();
mysql_mutex_lock(&share->mutex);
- if (!share->archive_write_open)
- if (init_archive_writer())
- DBUG_RETURN(errno);
-
+ if (!share->archive_write_open && init_archive_writer())
+ {
+ rc= errno;
+ goto error;
+ }
if (table->next_number_field && record == table->record[0])
{
@@ -992,7 +993,6 @@ int ha_archive::write_row(uchar *buf)
error:
mysql_mutex_unlock(&share->mutex);
my_free(read_buf);
-
DBUG_RETURN(rc);
}
diff --git a/storage/heap/hp_delete.c b/storage/heap/hp_delete.c
index d00ac94a918..043e4d3540d 100644
--- a/storage/heap/hp_delete.c
+++ b/storage/heap/hp_delete.c
@@ -48,7 +48,6 @@ int heap_delete(HP_INFO *info, const uchar *record)
pos[share->reclength]=0; /* Record deleted */
share->deleted++;
share->key_version++;
- info->current_hash_ptr=0;
#if !defined(DBUG_OFF) && defined(EXTRA_HEAP_DEBUG)
DBUG_EXECUTE("check_heap",heap_check_heap(info, 0););
#endif
@@ -105,7 +104,7 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
const uchar *record, uchar *recpos, int flag)
{
- ulong blength,pos2,pos_hashnr,lastpos_hashnr;
+ ulong blength, pos2, pos_hashnr, lastpos_hashnr, key_pos;
HASH_INFO *lastpos,*gpos,*pos,*pos3,*empty,*last_ptr;
HP_SHARE *share=info->s;
DBUG_ENTER("hp_delete_key");
@@ -117,9 +116,9 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
last_ptr=0;
/* Search after record with key */
- pos= hp_find_hash(&keyinfo->block,
- hp_mask(hp_rec_hashnr(keyinfo, record), blength,
- share->records + 1));
+ key_pos= hp_mask(hp_rec_hashnr(keyinfo, record), blength, share->records + 1);
+ pos= hp_find_hash(&keyinfo->block, key_pos);
+
gpos = pos3 = 0;
while (pos->ptr_to_rec != recpos)
@@ -182,21 +181,50 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo,
}
pos2= hp_mask(lastpos_hashnr, blength, share->records + 1);
if (pos2 == hp_mask(pos_hashnr, blength, share->records + 1))
- { /* Identical key-positions */
+ {
+ /* lastpos and the row in the main bucket entry (pos) has the same hash */
if (pos2 != share->records)
{
- empty[0]=lastpos[0];
+ /*
+ The bucket entry was not deleted. Copy lastpos over the
+ deleted entry and update previous link to point to it.
+ */
+ empty[0]= lastpos[0];
hp_movelink(lastpos, pos, empty);
+ if (last_ptr == lastpos)
+ {
+ /*
+ We moved the row that info->current_hash_ptr points to.
+ Update info->current_hash_ptr to point to the new position.
+ */
+ info->current_hash_ptr= empty;
+ }
DBUG_RETURN(0);
}
- pos3= pos; /* Link pos->next after lastpos */
- }
- else
- {
- pos3= 0; /* Different positions merge */
- keyinfo->hash_buckets--;
+ /*
+ Shrinking the hash table deleted the main bucket entry for this hash.
+ In this case the last entry was the first key in the key chain.
+ We move things around so that we keep the original key order to ensure
+ that heap_rnext() works.
+
+ - Move the row at the main bucket entry to the empty spot.
+ - Move the last entry first in the new chain.
+ - Link in the first element of the hash.
+ */
+ empty[0]= pos[0];
+ pos[0]= lastpos[0];
+ hp_movelink(pos, pos, empty);
+
+ /* Update current_hash_ptr if the entry moved */
+ if (last_ptr == lastpos)
+ info->current_hash_ptr= pos;
+ else if (last_ptr == pos)
+ info->current_hash_ptr= empty;
+ DBUG_RETURN(0);
}
+ pos3= 0; /* Different positions merge */
+ keyinfo->hash_buckets--;
empty[0]=lastpos[0];
hp_movelink(pos3, empty, pos->next_key);
pos->next_key=empty;
diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
index 1f4d8126be6..24ff78df7c0 100644
--- a/storage/innobase/btr/btr0btr.c
+++ b/storage/innobase/btr/btr0btr.c
@@ -3094,6 +3094,8 @@ btr_lift_page_up(
buf_block_t* blocks[BTR_MAX_LEVELS];
ulint n_blocks; /*!< last used index in blocks[] */
ulint i;
+ ibool lift_father_up = FALSE;
+ buf_block_t* block_orig = block;
ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL);
ut_ad(btr_page_get_next(page, mtr) == FIL_NULL);
@@ -3104,11 +3106,13 @@ btr_lift_page_up(
{
btr_cur_t cursor;
- mem_heap_t* heap = mem_heap_create(100);
- ulint* offsets;
+ ulint* offsets = NULL;
+ mem_heap_t* heap = mem_heap_create(
+ sizeof(*offsets)
+ * (REC_OFFS_HEADER_SIZE + 1 + 1 + index->n_fields));
buf_block_t* b;
- offsets = btr_page_get_father_block(NULL, heap, index,
+ offsets = btr_page_get_father_block(offsets, heap, index,
block, mtr, &cursor);
father_block = btr_cur_get_block(&cursor);
father_page_zip = buf_block_get_page_zip(father_block);
@@ -3132,6 +3136,29 @@ btr_lift_page_up(
blocks[n_blocks++] = b = btr_cur_get_block(&cursor);
}
+ if (n_blocks && page_level == 0) {
+ /* The father page also should be the only on its level (not
+ root). We should lift up the father page at first.
+ Because the leaf page should be lifted up only for root page.
+ The freeing page is based on page_level (==0 or !=0)
+ to choose segment. If the page_level is changed ==0 from !=0,
+ later freeing of the page doesn't find the page allocation
+ to be freed.*/
+
+ lift_father_up = TRUE;
+ block = father_block;
+ page = buf_block_get_frame(block);
+ page_level = btr_page_get_level(page, mtr);
+
+ ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL);
+ ut_ad(btr_page_get_next(page, mtr) == FIL_NULL);
+ ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
+
+ father_block = blocks[0];
+ father_page_zip = buf_block_get_page_zip(father_block);
+ father_page = buf_block_get_frame(father_block);
+ }
+
mem_heap_free(heap);
}
@@ -3139,6 +3166,7 @@ btr_lift_page_up(
/* Make the father empty */
btr_page_empty(father_block, father_page_zip, index, page_level, mtr);
+ page_level++;
/* Copy the records to the father page one by one. */
if (0
@@ -3171,7 +3199,7 @@ btr_lift_page_up(
lock_update_copy_and_discard(father_block, block);
/* Go upward to root page, decrementing levels by one. */
- for (i = 0; i < n_blocks; i++, page_level++) {
+ for (i = lift_father_up ? 1 : 0; i < n_blocks; i++, page_level++) {
page_t* page = buf_block_get_frame(blocks[i]);
page_zip_des_t* page_zip= buf_block_get_page_zip(blocks[i]);
@@ -3193,7 +3221,7 @@ btr_lift_page_up(
ut_ad(page_validate(father_page, index));
ut_ad(btr_check_node_ptr(index, father_block, mtr));
- return(father_block);
+ return(lift_father_up ? block_orig : father_block);
}
/*************************************************************//**
diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
index 1f92de245b1..955be01f032 100644
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
@@ -97,6 +97,11 @@ srv_refresh_innodb_monitor_stats(). Referenced by
srv_printf_innodb_monitor(). */
UNIV_INTERN ulint btr_cur_n_sea_old = 0;
+#ifdef UNIV_DEBUG
+/* Flag to limit optimistic insert records */
+UNIV_INTERN uint btr_cur_limit_optimistic_insert_debug = 0;
+#endif /* UNIV_DEBUG */
+
/** In the optimistic insert, if the insert does not fit, but this much space
can be released by page reorganize, then it is reorganized */
#define BTR_CUR_PAGE_REORGANIZE_LIMIT (UNIV_PAGE_SIZE / 32)
@@ -1273,6 +1278,9 @@ btr_cur_optimistic_insert(
}
}
+ LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page),
+ goto fail);
+
/* If there have been many consecutive inserts, and we are on the leaf
level, check if we have to split the page to reserve enough free space
for future updates of records. */
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index 1af019dfc45..2406980196e 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -370,6 +370,33 @@ buf_get_total_list_len(
}
/********************************************************************//**
+Get total list size in bytes from all buffer pools. */
+UNIV_INTERN
+void
+buf_get_total_list_size_in_bytes(
+/*=============================*/
+ buf_pools_list_size_t* buf_pools_list_size) /*!< out: list sizes
+ in all buffer pools */
+{
+ ulint i;
+ ut_ad(buf_pools_list_size);
+ memset(buf_pools_list_size, 0, sizeof(*buf_pools_list_size));
+
+ for (i = 0; i < srv_buf_pool_instances; i++) {
+ buf_pool_t* buf_pool;
+
+ buf_pool = buf_pool_from_array(i);
+ /* We don't need mutex protection since this is
+ for statistics purpose */
+ buf_pools_list_size->LRU_bytes += buf_pool->stat.LRU_bytes;
+ buf_pools_list_size->unzip_LRU_bytes +=
+ UT_LIST_GET_LEN(buf_pool->unzip_LRU) * UNIV_PAGE_SIZE;
+ buf_pools_list_size->flush_list_bytes +=
+ buf_pool->stat.flush_list_bytes;
+ }
+}
+
+/********************************************************************//**
Get total buffer pool statistics. */
UNIV_INTERN
void
@@ -1657,34 +1684,24 @@ buf_page_make_young(
}
/********************************************************************//**
-Sets the time of the first access of a page and moves a page to the
-start of the buffer pool LRU list if it is too old. This high-level
-function can be used to prevent an important page from slipping
-out of the buffer pool. */
+Moves a page to the start of the buffer pool LRU list if it is too old.
+This high-level function can be used to prevent an important page from
+slipping out of the buffer pool. */
static
void
-buf_page_set_accessed_make_young(
-/*=============================*/
- buf_page_t* bpage, /*!< in/out: buffer block of a
+buf_page_make_young_if_needed(
+/*==========================*/
+ buf_page_t* bpage) /*!< in/out: buffer block of a
file page */
- unsigned access_time) /*!< in: bpage->access_time
- read under mutex protection,
- or 0 if unknown */
{
+#ifdef UNIV_DEBUG
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
-
ut_ad(!buf_pool_mutex_own(buf_pool));
+#endif /* UNIV_DEBUG */
ut_a(buf_page_in_file(bpage));
if (buf_page_peek_if_too_old(bpage)) {
- buf_pool_mutex_enter(buf_pool);
- buf_LRU_make_block_young(bpage);
- buf_pool_mutex_exit(buf_pool);
- } else if (!access_time) {
- ulint time_ms = ut_time_ms();
- buf_pool_mutex_enter(buf_pool);
- buf_page_set_accessed(bpage, time_ms);
- buf_pool_mutex_exit(buf_pool);
+ buf_page_make_young(bpage);
}
}
@@ -1797,7 +1814,6 @@ buf_page_get_zip(
buf_page_t* bpage;
mutex_t* block_mutex;
ibool must_read;
- unsigned access_time;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
buf_pool->stat.n_page_gets++;
@@ -1865,13 +1881,14 @@ err_exit:
got_block:
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
- access_time = buf_page_is_accessed(bpage);
buf_pool_mutex_exit(buf_pool);
+ buf_page_set_accessed(bpage);
+
mutex_exit(block_mutex);
- buf_page_set_accessed_make_young(bpage, access_time);
+ buf_page_make_young_if_needed(bpage);
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(!bpage->file_page_was_freed);
@@ -2458,22 +2475,29 @@ wait_until_unfixed:
UNIV_MEM_INVALID(bpage, sizeof *bpage);
- mutex_exit(&block->mutex);
- mutex_exit(&buf_pool->zip_mutex);
buf_pool->n_pend_unzip++;
-
buf_pool_mutex_exit(buf_pool);
+ access_time = buf_page_is_accessed(&block->page);
+ mutex_exit(&block->mutex);
+ mutex_exit(&buf_pool->zip_mutex);
+
buf_page_free_descriptor(bpage);
- /* Decompress the page and apply buffered operations
- while not holding buf_pool->mutex or block->mutex. */
+ /* Decompress the page while not holding
+ buf_pool->mutex or block->mutex. */
success = buf_zip_decompress(block, srv_use_checksums);
ut_a(success);
if (UNIV_LIKELY(!recv_no_ibuf_operations)) {
- ibuf_merge_or_delete_for_page(block, space, offset,
- zip_size, TRUE);
+ if (access_time) {
+#ifdef UNIV_IBUF_COUNT_DEBUG
+ ut_a(ibuf_count_get(space, offset) == 0);
+#endif /* UNIV_IBUF_COUNT_DEBUG */
+ } else {
+ ibuf_merge_or_delete_for_page(
+ block, space, offset, zip_size, TRUE);
+ }
}
/* Unfix and unlatch the block. */
@@ -2550,16 +2574,17 @@ wait_until_unfixed:
ut_a(mode == BUF_GET_POSSIBLY_FREED
|| !block->page.file_page_was_freed);
#endif
- mutex_exit(&block->mutex);
+ buf_pool_mutex_exit(buf_pool);
/* Check if this is the first access to the page */
-
access_time = buf_page_is_accessed(&block->page);
- buf_pool_mutex_exit(buf_pool);
+ buf_page_set_accessed(&block->page);
- if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) {
- buf_page_set_accessed_make_young(&block->page, access_time);
+ mutex_exit(&block->mutex);
+
+ if (mode != BUF_PEEK_IF_IN_POOL) {
+ buf_page_make_young_if_needed(&block->page);
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
@@ -2610,7 +2635,7 @@ wait_until_unfixed:
mtr_memo_push(mtr, block, fix_type);
- if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL) && !access_time) {
+ if (mode != BUF_PEEK_IF_IN_POOL && !access_time) {
/* In the case of a first access, try to apply linear
read-ahead */
@@ -2662,15 +2687,13 @@ buf_page_optimistic_get(
buf_block_buf_fix_inc(block, file, line);
- mutex_exit(&block->mutex);
+ access_time = buf_page_is_accessed(&block->page);
- /* Check if this is the first access to the page.
- We do a dirty read on purpose, to avoid mutex contention.
- This field is only used for heuristic purposes; it does not
- affect correctness. */
+ buf_page_set_accessed(&block->page);
- access_time = buf_page_is_accessed(&block->page);
- buf_page_set_accessed_make_young(&block->page, access_time);
+ mutex_exit(&block->mutex);
+
+ buf_page_make_young_if_needed(&block->page);
ut_ad(!ibuf_inside(mtr)
|| ibuf_page(buf_block_get_space(block),
@@ -2722,7 +2745,7 @@ buf_page_optimistic_get(
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE);
#endif
- if (UNIV_UNLIKELY(!access_time)) {
+ if (!access_time) {
/* In the case of a first access, try to apply linear
read-ahead */
@@ -2785,24 +2808,14 @@ buf_page_get_known_nowait(
buf_block_buf_fix_inc(block, file, line);
+ buf_page_set_accessed(&block->page);
+
mutex_exit(&block->mutex);
buf_pool = buf_pool_from_block(block);
- if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
- buf_pool_mutex_enter(buf_pool);
- buf_LRU_make_block_young(&block->page);
- buf_pool_mutex_exit(buf_pool);
- } else if (!buf_page_is_accessed(&block->page)) {
- /* Above, we do a dirty read on purpose, to avoid
- mutex contention. The field buf_page_t::access_time
- is only used for heuristic purposes. Writes to the
- field must be protected by mutex, however. */
- ulint time_ms = ut_time_ms();
-
- buf_pool_mutex_enter(buf_pool);
- buf_page_set_accessed(&block->page, time_ms);
- buf_pool_mutex_exit(buf_pool);
+ if (mode == BUF_MAKE_YOUNG) {
+ buf_page_make_young_if_needed(&block->page);
}
ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD);
@@ -2965,6 +2978,7 @@ buf_page_init(
ulint offset, /*!< in: offset of the page within space
in units of a page */
ulint fold, /*!< in: buf_page_address_fold(space,offset) */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
buf_block_t* block) /*!< in/out: block to init */
{
buf_page_t* hash_page;
@@ -3027,6 +3041,9 @@ buf_page_init(
ut_d(block->page.in_page_hash = TRUE);
HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
fold, &block->page);
+ if (zip_size) {
+ page_zip_set_size(&block->page.zip, zip_size);
+ }
}
/********************************************************************//**
@@ -3128,7 +3145,7 @@ err_exit:
ut_ad(buf_pool_from_bpage(bpage) == buf_pool);
- buf_page_init(buf_pool, space, offset, fold, block);
+ buf_page_init(buf_pool, space, offset, fold, zip_size, block);
/* The block must be put to the LRU list, to the old blocks */
buf_LRU_add_block(bpage, TRUE/* to old blocks */);
@@ -3146,8 +3163,6 @@ err_exit:
buf_page_set_io_fix(bpage, BUF_IO_READ);
if (UNIV_UNLIKELY(zip_size)) {
- page_zip_set_size(&block->page.zip, zip_size);
-
/* buf_pool->mutex may be released and
reacquired by buf_buddy_alloc(). Thus, we
must release block->mutex in order not to
@@ -3240,7 +3255,8 @@ err_exit:
HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold,
bpage);
- /* The block must be put to the LRU list, to the old blocks */
+ /* The block must be put to the LRU list, to the old blocks
+ The zip_size is already set into the page zip */
buf_LRU_add_block(bpage, TRUE/* to old blocks */);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(bpage);
@@ -3284,7 +3300,6 @@ buf_page_create(
buf_block_t* block;
ulint fold;
buf_block_t* free_block = NULL;
- ulint time_ms = ut_time_ms();
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ut_ad(mtr);
@@ -3332,7 +3347,7 @@ buf_page_create(
mutex_enter(&block->mutex);
- buf_page_init(buf_pool, space, offset, fold, block);
+ buf_page_init(buf_pool, space, offset, fold, zip_size, block);
/* The block must be put to the LRU list */
buf_LRU_add_block(&block->page, FALSE);
@@ -3350,8 +3365,6 @@ buf_page_create(
buf_page_set_io_fix(&block->page, BUF_IO_READ);
rw_lock_x_lock(&block->lock);
-
- page_zip_set_size(&block->page.zip, zip_size);
mutex_exit(&block->mutex);
/* buf_pool->mutex may be released and reacquired by
buf_buddy_alloc(). Thus, we must release block->mutex
@@ -3375,12 +3388,12 @@ buf_page_create(
rw_lock_x_unlock(&block->lock);
}
- buf_page_set_accessed(&block->page, time_ms);
-
buf_pool_mutex_exit(buf_pool);
mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
+ buf_page_set_accessed(&block->page);
+
mutex_exit(&block->mutex);
/* Delete possible entries for the page from the insert buffer:
diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
index 7cd09d6675e..c385dc793ab 100644
--- a/storage/innobase/buf/buf0flu.c
+++ b/storage/innobase/buf/buf0flu.c
@@ -79,6 +79,23 @@ static ulint buf_lru_flush_page_count = 0;
/* @} */
+/******************************************************************//**
+Increases flush_list size in bytes with zip_size for compressed page,
+UNIV_PAGE_SIZE for uncompressed page in inline function */
+static inline
+void
+incr_flush_list_size_in_bytes(
+/*==========================*/
+ buf_block_t* block, /*!< in: control block */
+ buf_pool_t* buf_pool) /*!< in: buffer pool instance */
+{
+ ulint zip_size;
+ ut_ad(buf_flush_list_mutex_own(buf_pool));
+ zip_size = page_zip_get_size(&block->page.zip);
+ buf_pool->stat.flush_list_bytes += zip_size ? zip_size : UNIV_PAGE_SIZE;
+ ut_ad(buf_pool->stat.flush_list_bytes <= buf_pool->curr_pool_size);
+}
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/******************************************************************//**
Validates the flush list.
@@ -308,6 +325,7 @@ buf_flush_insert_into_flush_list(
ut_d(block->page.in_flush_list = TRUE);
block->page.oldest_modification = lsn;
UT_LIST_ADD_FIRST(list, buf_pool->flush_list, &block->page);
+ incr_flush_list_size_in_bytes(block, buf_pool);
#ifdef UNIV_DEBUG_VALGRIND
{
@@ -412,6 +430,8 @@ buf_flush_insert_sorted_into_flush_list(
prev_b, &block->page);
}
+ incr_flush_list_size_in_bytes(block, buf_pool);
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(buf_flush_validate_low(buf_pool));
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
@@ -504,6 +524,7 @@ buf_flush_remove(
buf_page_t* bpage) /*!< in: pointer to the block in question */
{
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+ ulint zip_size;
ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
@@ -542,6 +563,9 @@ buf_flush_remove(
because we assert on in_flush_list in comparison function. */
ut_d(bpage->in_flush_list = FALSE);
+ zip_size = page_zip_get_size(&bpage->zip);
+ buf_pool->stat.flush_list_bytes -= zip_size ? zip_size : UNIV_PAGE_SIZE;
+
bpage->oldest_modification = 0;
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
index 60894cae6ad..b3e282d24b2 100644
--- a/storage/innobase/buf/buf0lru.c
+++ b/storage/innobase/buf/buf0lru.c
@@ -151,6 +151,23 @@ buf_LRU_block_free_hashed_page(
be in a state where it can be freed */
/******************************************************************//**
+Increases LRU size in bytes with zip_size for compressed page,
+UNIV_PAGE_SIZE for uncompressed page in inline function */
+static inline
+void
+incr_LRU_size_in_bytes(
+/*===================*/
+ buf_page_t* bpage, /*!< in: control block */
+ buf_pool_t* buf_pool) /*!< in: buffer pool instance */
+{
+ ulint zip_size;
+ ut_ad(buf_pool_mutex_own(buf_pool));
+ zip_size = page_zip_get_size(&bpage->zip);
+ buf_pool->stat.LRU_bytes += zip_size ? zip_size : UNIV_PAGE_SIZE;
+ ut_ad(buf_pool->stat.LRU_bytes <= buf_pool->curr_pool_size);
+}
+
+/******************************************************************//**
Determines if the unzip_LRU list should be used for evicting a victim
instead of the general LRU list.
@return TRUE if should use unzip_LRU */
@@ -1356,6 +1373,7 @@ buf_LRU_remove_block(
buf_page_t* bpage) /*!< in: control block */
{
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+ ulint zip_size;
ut_ad(buf_pool);
ut_ad(bpage);
@@ -1391,6 +1409,9 @@ buf_LRU_remove_block(
UT_LIST_REMOVE(LRU, buf_pool->LRU, bpage);
ut_d(bpage->in_LRU_list = FALSE);
+ zip_size = page_zip_get_size(&bpage->zip);
+ buf_pool->stat.LRU_bytes -= zip_size ? zip_size : UNIV_PAGE_SIZE;
+
buf_unzip_LRU_remove_block_if_needed(bpage);
/* If the LRU list is so short that LRU_old is not defined,
@@ -1451,7 +1472,10 @@ buf_unzip_LRU_add_block(
}
/******************************************************************//**
-Adds a block to the LRU list end. */
+Adds a block to the LRU list end. Please make sure that the zip_size is
+already set into the page zip when invoking the function, so that we
+can get correct zip_size from the buffer page when adding a block
+into LRU */
UNIV_INLINE
void
buf_LRU_add_block_to_end_low(
@@ -1470,6 +1494,8 @@ buf_LRU_add_block_to_end_low(
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
ut_d(bpage->in_LRU_list = TRUE);
+ incr_LRU_size_in_bytes(bpage, buf_pool);
+
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
ut_ad(buf_pool->LRU_old);
@@ -1498,7 +1524,10 @@ buf_LRU_add_block_to_end_low(
}
/******************************************************************//**
-Adds a block to the LRU list. */
+Adds a block to the LRU list. Please make sure that the zip_size is
+already set into the page zip when invoking the function, so that we
+can get correct zip_size from the buffer page when adding a block
+into LRU */
UNIV_INLINE
void
buf_LRU_add_block_low(
@@ -1540,6 +1569,8 @@ buf_LRU_add_block_low(
ut_d(bpage->in_LRU_list = TRUE);
+ incr_LRU_size_in_bytes(bpage, buf_pool);
+
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
ut_ad(buf_pool->LRU_old);
@@ -1567,7 +1598,10 @@ buf_LRU_add_block_low(
}
/******************************************************************//**
-Adds a block to the LRU list. */
+Adds a block to the LRU list. Please make sure that the zip_size is
+already set into the page zip when invoking the function, so that we
+can get correct zip_size from the buffer page when adding a block
+into LRU */
UNIV_INTERN
void
buf_LRU_add_block(
@@ -1753,6 +1787,8 @@ alloc:
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU,
prev_b, b);
+ incr_LRU_size_in_bytes(b, buf_pool);
+
if (buf_page_is_old(b)) {
buf_pool->LRU_old_len++;
if (UNIV_UNLIKELY
diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
index 22f0d4456d5..208d013e82d 100644
--- a/storage/innobase/dict/dict0load.c
+++ b/storage/innobase/dict/dict0load.c
@@ -2328,7 +2328,8 @@ dict_load_foreigns(
ibool check_charsets) /*!< in: TRUE=check charset
compatibility */
{
- char tuple_buf[DTUPLE_EST_ALLOC(1)];
+ ulint tuple_buf[(DTUPLE_EST_ALLOC(1) + sizeof(ulint) - 1)
+ / sizeof(ulint)];
btr_pcur_t pcur;
dtuple_t* tuple;
dfield_t* dfield;
diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
index 8fe33459994..2f875663039 100644
--- a/storage/innobase/fil/fil0fil.c
+++ b/storage/innobase/fil/fil0fil.c
@@ -1466,7 +1466,7 @@ fil_space_get_size(
ut_ad(fil_system);
- fil_mutex_enter_and_prepare_for_io(id);
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -1481,6 +1481,23 @@ fil_space_get_size(
ut_a(1 == UT_LIST_GET_LEN(space->chain));
+ mutex_exit(&fil_system->mutex);
+
+ /* It is possible that the space gets evicted at this point
+ before the fil_mutex_enter_and_prepare_for_io() acquires
+ the fil_system->mutex. Check for this after completing the
+ call to fil_mutex_enter_and_prepare_for_io(). */
+ fil_mutex_enter_and_prepare_for_io(id);
+
+ /* We are still holding the fil_system->mutex. Check if
+ the space is still in memory cache. */
+ space = fil_space_get_by_id(id);
+
+ if (space == NULL) {
+ mutex_exit(&fil_system->mutex);
+ return(0);
+ }
+
node = UT_LIST_GET_FIRST(space->chain);
/* It must be a single-table tablespace and we have not opened
@@ -1518,7 +1535,7 @@ fil_space_get_flags(
return(0);
}
- fil_mutex_enter_and_prepare_for_io(id);
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -1533,6 +1550,23 @@ fil_space_get_flags(
ut_a(1 == UT_LIST_GET_LEN(space->chain));
+ mutex_exit(&fil_system->mutex);
+
+ /* It is possible that the space gets evicted at this point
+ before the fil_mutex_enter_and_prepare_for_io() acquires
+ the fil_system->mutex. Check for this after completing the
+ call to fil_mutex_enter_and_prepare_for_io(). */
+ fil_mutex_enter_and_prepare_for_io(id);
+
+ /* We are still holding the fil_system->mutex. Check if
+ the space is still in memory cache. */
+ space = fil_space_get_by_id(id);
+
+ if (space == NULL) {
+ mutex_exit(&fil_system->mutex);
+ return(0);
+ }
+
node = UT_LIST_GET_FIRST(space->chain);
/* It must be a single-table tablespace and we have not opened
@@ -2702,7 +2736,7 @@ retry:
mutex_exit(&fil_system->mutex);
#ifndef UNIV_HOTBACKUP
- if (success) {
+ if (success && !recv_recovery_on) {
mtr_t mtr;
mtr_start(&mtr);
@@ -4947,3 +4981,28 @@ fil_close(void)
fil_system = NULL;
}
+
+/****************************************************************//**
+Generate redo logs for swapping two .ibd files */
+UNIV_INTERN
+void
+fil_mtr_rename_log(
+/*===============*/
+ ulint old_space_id, /*!< in: tablespace id of the old
+ table. */
+ const char* old_name, /*!< in: old table name */
+ ulint new_space_id, /*!< in: tablespace id of the new
+ table */
+ const char* new_name, /*!< in: new table name */
+ const char* tmp_name) /*!< in: temp table name used while
+ swapping */
+{
+ mtr_t mtr;
+ mtr_start(&mtr);
+ fil_op_write_log(MLOG_FILE_RENAME, old_space_id,
+ 0, 0, old_name, tmp_name, &mtr);
+ fil_op_write_log(MLOG_FILE_RENAME, new_space_id,
+ 0, 0, new_name, old_name, &mtr);
+ mtr_commit(&mtr);
+}
+
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index f54098814b8..3ed744382c7 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -635,8 +635,12 @@ innobase_commit_low(
static SHOW_VAR innodb_status_variables[]= {
{"buffer_pool_pages_data",
(char*) &export_vars.innodb_buffer_pool_pages_data, SHOW_LONG},
+ {"buffer_pool_bytes_data",
+ (char*) &export_vars.innodb_buffer_pool_bytes_data, SHOW_LONG},
{"buffer_pool_pages_dirty",
(char*) &export_vars.innodb_buffer_pool_pages_dirty, SHOW_LONG},
+ {"buffer_pool_bytes_dirty",
+ (char*) &export_vars.innodb_buffer_pool_bytes_dirty, SHOW_LONG},
{"buffer_pool_pages_flushed",
(char*) &export_vars.innodb_buffer_pool_pages_flushed, SHOW_LONG},
{"buffer_pool_pages_free",
@@ -727,6 +731,12 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &export_vars.innodb_rows_updated, SHOW_LONG},
{"truncated_status_writes",
(char*) &export_vars.innodb_truncated_status_writes, SHOW_LONG},
+#ifdef UNIV_DEBUG
+ {"purge_trx_id_age",
+ (char*) &export_vars.innodb_purge_trx_id_age, SHOW_LONG},
+ {"purge_view_trx_id_age",
+ (char*) &export_vars.innodb_purge_view_trx_id_age, SHOW_LONG},
+#endif /* UNIV_DEBUG */
{NullS, NullS, SHOW_LONG}
};
@@ -1114,6 +1124,8 @@ convert_error_code_to_mysql(
return(HA_ERR_INDEX_CORRUPT);
case DB_UNDO_RECORD_TOO_BIG:
return(HA_ERR_UNDO_REC_TOO_BIG);
+ case DB_OUT_OF_MEMORY:
+ return(HA_ERR_OUT_OF_MEM);
}
}
@@ -1291,100 +1303,6 @@ innobase_get_lower_case_table_names(void)
return(lower_case_table_names);
}
-#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
-extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
-/*******************************************************************//**
-Map an OS error to an errno value. The OS error number is stored in
-_doserrno and the mapped value is stored in errno) */
-extern "C"
-void __cdecl
-_dosmaperr(
- unsigned long); /*!< in: OS error value */
-
-/*********************************************************************//**
-Creates a temporary file.
-@return temporary file descriptor, or < 0 on error */
-extern "C" UNIV_INTERN
-int
-innobase_mysql_tmpfile(void)
-/*========================*/
-{
- int fd; /* handle of opened file */
- HANDLE osfh; /* OS handle of opened file */
- char* tmpdir; /* point to the directory
- where to create file */
- TCHAR path_buf[MAX_PATH - 14]; /* buffer for tmp file path.
- The length cannot be longer
- than MAX_PATH - 14, or
- GetTempFileName will fail. */
- char filename[MAX_PATH]; /* name of the tmpfile */
- DWORD fileaccess = GENERIC_READ /* OS file access */
- | GENERIC_WRITE
- | DELETE;
- DWORD fileshare = FILE_SHARE_READ /* OS file sharing mode */
- | FILE_SHARE_WRITE
- | FILE_SHARE_DELETE;
- DWORD filecreate = CREATE_ALWAYS; /* OS method of open/create */
- DWORD fileattrib = /* OS file attribute flags */
- FILE_ATTRIBUTE_NORMAL
- | FILE_FLAG_DELETE_ON_CLOSE
- | FILE_ATTRIBUTE_TEMPORARY
- | FILE_FLAG_SEQUENTIAL_SCAN;
-
- DBUG_ENTER("innobase_mysql_tmpfile");
-
- tmpdir = my_tmpdir(&mysql_tmpdir_list);
-
- /* The tmpdir parameter can not be NULL for GetTempFileName. */
- if (!tmpdir) {
- uint ret;
-
- /* Use GetTempPath to determine path for temporary files. */
- ret = GetTempPath(sizeof(path_buf), path_buf);
- if (ret > sizeof(path_buf) || (ret == 0)) {
-
- _dosmaperr(GetLastError()); /* map error */
- DBUG_RETURN(-1);
- }
-
- tmpdir = path_buf;
- }
-
- /* Use GetTempFileName to generate a unique filename. */
- if (!GetTempFileName(tmpdir, "ib", 0, filename)) {
-
- _dosmaperr(GetLastError()); /* map error */
- DBUG_RETURN(-1);
- }
-
- DBUG_PRINT("info", ("filename: %s", filename));
-
- /* Open/Create the file. */
- osfh = CreateFile(filename, fileaccess, fileshare, NULL,
- filecreate, fileattrib, NULL);
- if (osfh == INVALID_HANDLE_VALUE) {
-
- /* open/create file failed! */
- _dosmaperr(GetLastError()); /* map error */
- DBUG_RETURN(-1);
- }
-
- do {
- /* Associates a CRT file descriptor with the OS file handle. */
- fd = _open_osfhandle((intptr_t) osfh, 0);
- } while (fd == -1 && errno == EINTR);
-
- if (fd == -1) {
- /* Open failed, close the file handle. */
-
- _dosmaperr(GetLastError()); /* map error */
- CloseHandle(osfh); /* no need to check if
- CloseHandle fails */
- }
-
- DBUG_RETURN(fd);
-}
-#else
/*********************************************************************//**
Creates a temporary file.
@return temporary file descriptor, or < 0 on error */
@@ -1397,7 +1315,15 @@ innobase_mysql_tmpfile(void)
os_event_wait(srv_allow_writes_event);
#endif /* WITH_INNODB_DISALLOW_WRITES */
int fd2 = -1;
- File fd = mysql_tmpfile("ib");
+ File fd;
+
+ DBUG_EXECUTE_IF(
+ "innobase_tmpfile_creation_failure",
+ return(-1);
+ );
+
+ fd = mysql_tmpfile("ib");
+
if (fd >= 0) {
/* Copy the file descriptor, so that the additional resources
allocated by create_temp_file() can be freed by invoking
@@ -1441,7 +1367,6 @@ innobase_mysql_tmpfile(void)
}
return(fd2);
}
-#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */
/*********************************************************************//**
Wrapper around MySQL's copy_and_convert function.
@@ -13049,13 +12974,30 @@ static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
"trigger a readahead.",
NULL, NULL, 56, 0, 64, 0);
-#ifdef UNIV_DEBUG_never
+#ifdef UNIV_DEBUG
static MYSQL_SYSVAR_UINT(trx_rseg_n_slots_debug, trx_rseg_n_slots_debug,
- PLUGIN_VAR_RQCMDARG,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_NOCMDOPT,
"Debug flags for InnoDB to limit TRX_RSEG_N_SLOTS for trx_rsegf_undo_find_free()",
NULL, NULL, 0, 0, 1024, 0);
+
+static MYSQL_SYSVAR_UINT(limit_optimistic_insert_debug,
+ btr_cur_limit_optimistic_insert_debug, PLUGIN_VAR_RQCMDARG,
+ "Artificially limit the number of records per B-tree page (0=unlimited).",
+ NULL, NULL, 0, 0, UINT_MAX32, 0);
+
+static MYSQL_SYSVAR_BOOL(trx_purge_view_update_only_debug,
+ srv_purge_view_update_only_debug, PLUGIN_VAR_NOCMDOPT,
+ "Pause actual purging any delete-marked records, but merely update the purge view. "
+ "It is to create artificially the situation the purge view have been updated "
+ "but the each purges were not done yet.",
+ NULL, NULL, FALSE);
#endif /* UNIV_DEBUG */
+static MYSQL_SYSVAR_BOOL(print_all_deadlocks, srv_print_all_deadlocks,
+ PLUGIN_VAR_OPCMDARG,
+ "Print all deadlocks to MySQL error log (off by default)",
+ NULL, NULL, FALSE);
+
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
@@ -13128,9 +13070,12 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(purge_threads),
MYSQL_SYSVAR(purge_batch_size),
MYSQL_SYSVAR(rollback_segments),
-#ifdef UNIV_DEBUG_never /* disable this flag. --innodb-trx becomes ambiguous */
+#ifdef UNIV_DEBUG
MYSQL_SYSVAR(trx_rseg_n_slots_debug),
+ MYSQL_SYSVAR(limit_optimistic_insert_debug),
+ MYSQL_SYSVAR(trx_purge_view_update_only_debug),
#endif /* UNIV_DEBUG */
+ MYSQL_SYSVAR(print_all_deadlocks),
NULL
};
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index df657acba39..ad1d1abb188 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -105,8 +105,6 @@ innobase_col_to_mysql(
ut_ad(flen >= len);
ut_ad(DATA_MBMAXLEN(col->mbminmaxlen)
>= DATA_MBMINLEN(col->mbminmaxlen));
- ut_ad(DATA_MBMAXLEN(col->mbminmaxlen)
- > DATA_MBMINLEN(col->mbminmaxlen) || flen == len);
memcpy(dest, data, len);
break;
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index 6819f2bc2c5..283a6eec852 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -805,6 +805,11 @@ srv_printf_innodb_monitor(). */
extern ulint btr_cur_n_sea_old;
#endif /* !UNIV_HOTBACKUP */
+#ifdef UNIV_DEBUG
+/* Flag to limit optimistic insert records */
+extern uint btr_cur_limit_optimistic_insert_debug;
+#endif /* UNIV_DEBUG */
+
#ifndef UNIV_NONINL
#include "btr0cur.ic"
#endif
diff --git a/storage/innobase/include/btr0cur.ic b/storage/innobase/include/btr0cur.ic
index e31f77c77eb..5fc4651ca13 100644
--- a/storage/innobase/include/btr0cur.ic
+++ b/storage/innobase/include/btr0cur.ic
@@ -27,6 +27,16 @@ Created 10/16/1994 Heikki Tuuri
#include "btr0btr.h"
#ifdef UNIV_DEBUG
+# define LIMIT_OPTIMISTIC_INSERT_DEBUG(NREC, CODE)\
+if (btr_cur_limit_optimistic_insert_debug\
+ && (NREC) >= (ulint)btr_cur_limit_optimistic_insert_debug) {\
+ CODE;\
+}
+#else
+# define LIMIT_OPTIMISTIC_INSERT_DEBUG(NREC, CODE)
+#endif /* UNIV_DEBUG */
+
+#ifdef UNIV_DEBUG
/*********************************************************//**
Returns the page cursor component of a tree cursor.
@return pointer to page cursor component */
@@ -146,6 +156,9 @@ btr_cur_compress_recommendation(
page = btr_cur_get_page(cursor);
+ LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page) * 2,
+ return(FALSE));
+
if ((page_get_data_size(page) < BTR_CUR_PAGE_COMPRESS_LIMIT)
|| ((btr_page_get_next(page, mtr) == FIL_NULL)
&& (btr_page_get_prev(page, mtr) == FIL_NULL))) {
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index fd8620eab3b..b7f6eae3f09 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -198,6 +198,15 @@ struct buf_pool_info_struct{
typedef struct buf_pool_info_struct buf_pool_info_t;
+/** The occupied bytes of lists in all buffer pools */
+struct buf_pools_list_size_struct {
+ ulint LRU_bytes; /*!< LRU size in bytes */
+ ulint unzip_LRU_bytes; /*!< unzip_LRU size in bytes */
+ ulint flush_list_bytes; /*!< flush_list size in bytes */
+};
+
+typedef struct buf_pools_list_size_struct buf_pools_list_size_t;
+
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Acquire mutex on all buffer pool instances */
@@ -1024,8 +1033,7 @@ UNIV_INLINE
void
buf_page_set_accessed(
/*==================*/
- buf_page_t* bpage, /*!< in/out: control block */
- ulint time_ms) /*!< in: ut_time_ms() */
+ buf_page_t* bpage) /*!< in/out: control block */
__attribute__((nonnull));
/*********************************************************************//**
Gets the buf_block_t handle of a buffered file block if an uncompressed
@@ -1334,6 +1342,14 @@ buf_get_total_list_len(
ulint* free_len, /*!< out: length of all free lists */
ulint* flush_list_len);/*!< out: length of all flush lists */
/********************************************************************//**
+Get total list size in bytes from all buffer pools. */
+UNIV_INTERN
+void
+buf_get_total_list_size_in_bytes(
+/*=============================*/
+ buf_pools_list_size_t* buf_pools_list_size); /*!< out: list sizes
+ in all buffer pools */
+/********************************************************************//**
Get total buffer pool statistics. */
UNIV_INTERN
void
@@ -1504,10 +1520,11 @@ struct buf_page_struct{
to read this for heuristic
purposes without holding any
mutex or latch */
- unsigned access_time:32; /*!< time of first access, or
- 0 if the block was never accessed
- in the buffer pool */
/* @} */
+ unsigned access_time; /*!< time of first access, or
+ 0 if the block was never accessed
+ in the buffer pool. Protected by
+ block mutex */
# if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ibool file_page_was_freed;
/*!< this is set to TRUE when fsp
@@ -1685,6 +1702,8 @@ struct buf_pool_stat_struct{
young because the first access
was not long enough ago, in
buf_page_peek_if_too_old() */
+ ulint LRU_bytes; /*!< LRU size in bytes */
+ ulint flush_list_bytes;/*!< flush_list size in bytes */
};
/** Statistics of buddy blocks of a given size. */
diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
index 84c0ab9d610..bcbe454b037 100644
--- a/storage/innobase/include/buf0buf.ic
+++ b/storage/innobase/include/buf0buf.ic
@@ -614,18 +614,18 @@ UNIV_INLINE
void
buf_page_set_accessed(
/*==================*/
- buf_page_t* bpage, /*!< in/out: control block */
- ulint time_ms) /*!< in: ut_time_ms() */
+ buf_page_t* bpage) /*!< in/out: control block */
{
#ifdef UNIV_DEBUG
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
- ut_ad(buf_pool_mutex_own(buf_pool));
+ ut_ad(!buf_pool_mutex_own(buf_pool));
+ ut_ad(mutex_own(buf_page_get_mutex(bpage)));
#endif
ut_a(buf_page_in_file(bpage));
if (!bpage->access_time) {
/* Make this the time of the first access. */
- bpage->access_time = time_ms;
+ bpage->access_time = ut_time_ms();
}
}
diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
index 9ecb9de2afe..0e08f455800 100644
--- a/storage/innobase/include/buf0lru.h
+++ b/storage/innobase/include/buf0lru.h
@@ -149,7 +149,10 @@ buf_LRU_block_free_non_file_page(
/*=============================*/
buf_block_t* block); /*!< in: block, must not contain a file page */
/******************************************************************//**
-Adds a block to the LRU list. */
+Adds a block to the LRU list. Please make sure that the zip_size is
+already set into the page zip when invoking the function, so that we
+can get correct zip_size from the buffer page when adding a block
+into LRU */
UNIV_INTERN
void
buf_LRU_add_block(
diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic
index 757dd815c5e..7ec2cb6cf36 100644
--- a/storage/innobase/include/data0type.ic
+++ b/storage/innobase/include/data0type.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -459,36 +459,18 @@ dtype_get_fixed_size_low(
} else if (!comp) {
return(len);
} else {
- /* We play it safe here and ask MySQL for
- mbminlen and mbmaxlen. Although
- mbminlen and mbmaxlen are
- initialized if and only if prtype
- is (in one of the 3 functions in this file),
- it could be that none of these functions
- has been called. */
-
+#ifdef UNIV_DEBUG
ulint i_mbminlen, i_mbmaxlen;
innobase_get_cset_width(
dtype_get_charset_coll(prtype),
&i_mbminlen, &i_mbmaxlen);
- if (UNIV_UNLIKELY
- (DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen)
- != mbminmaxlen)) {
-
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: "
- "mbminlen=%lu, "
- "mbmaxlen=%lu, "
- "type->mbminlen=%lu, "
- "type->mbmaxlen=%lu\n",
- (ulong) i_mbminlen,
- (ulong) i_mbmaxlen,
- (ulong) DATA_MBMINLEN(mbminmaxlen),
- (ulong) DATA_MBMAXLEN(mbminmaxlen));
- }
- if (i_mbminlen == i_mbmaxlen) {
+ ut_ad(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen)
+ == mbminmaxlen);
+#endif /* UNIV_DEBUG */
+ if (DATA_MBMINLEN(mbminmaxlen)
+ == DATA_MBMAXLEN(mbminmaxlen)) {
return(len);
}
}
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index ed47ccff052..a804c261447 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -734,6 +734,21 @@ fil_tablespace_is_being_deleted(
/*============================*/
ulint id); /*!< in: space id */
+/****************************************************************//**
+Generate redo logs for swapping two .ibd files */
+UNIV_INTERN
+void
+fil_mtr_rename_log(
+/*===============*/
+ ulint old_space_id, /*!< in: tablespace id of the old
+ table. */
+ const char* old_name, /*!< in: old table name */
+ ulint new_space_id, /*!< in: tablespace id of the new
+ table */
+ const char* new_name, /*!< in: new table name */
+ const char* tmp_name); /*!< in: temp table name used while
+ swapping */
+
typedef struct fil_space_struct fil_space_t;
#endif
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index e5a61e599bc..a44770beede 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -797,15 +797,20 @@ lock_rec_get_page_no(
remains set when the waiting lock is granted,
or if the lock is inherited to a neighboring
record */
-#define WSREP_BF 4096
-#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_MODE_MASK
-# error
-#endif
-#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_TYPE_MASK
+#define LOCK_CONV_BY_OTHER 4096 /*!< this bit is set when the lock is created
+ by other transaction */
+#define WSREP_BF 8192
+#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_CONV_BY_OTHER)&LOCK_TYPE_MASK
# error
#endif
/* @} */
+/** Checks if this is a waiting lock created by lock->trx itself.
+@param type_mode lock->type_mode
+@return whether it is a waiting lock belonging to lock->trx */
+#define lock_is_wait_not_by_other(type_mode) \
+ ((type_mode & (LOCK_CONV_BY_OTHER | LOCK_WAIT)) == LOCK_WAIT)
+
/** Lock operation struct */
typedef struct lock_op_struct lock_op_t;
/** Lock operation struct */
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h
index e2af5998899..5687f51d985 100644
--- a/storage/innobase/include/rem0rec.h
+++ b/storage/innobase/include/rem0rec.h
@@ -362,24 +362,6 @@ rec_get_offsets_func(
rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__)
/******************************************************//**
-Determine the offset to each field in a leaf-page record
-in ROW_FORMAT=COMPACT. This is a special case of
-rec_init_offsets() and rec_get_offsets_func(). */
-UNIV_INTERN
-void
-rec_init_offsets_comp_ordinary(
-/*===========================*/
- const rec_t* rec, /*!< in: physical record in
- ROW_FORMAT=COMPACT */
- ulint extra, /*!< in: number of bytes to reserve
- between the record header and
- the data payload
- (usually REC_N_NEW_EXTRA_BYTES) */
- const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets);/*!< in/out: array of offsets;
- in: n=rec_offs_n_fields(offsets) */
-
-/******************************************************//**
The following function determines the offsets to each field
in the record. It can reuse a previously allocated array. */
UNIV_INTERN
@@ -644,8 +626,48 @@ rec_copy(
/*=====*/
void* buf, /*!< in: buffer */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ __attribute__((nonnull));
#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
+Determines the size of a data tuple prefix in a temporary file.
+@return total size */
+UNIV_INTERN
+ulint
+rec_get_converted_size_temp(
+/*========================*/
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra) /*!< out: extra size */
+ __attribute__((warn_unused_result, nonnull));
+
+/******************************************************//**
+Determine the offset to each field in temporary file.
+@see rec_convert_dtuple_to_temp() */
+UNIV_INTERN
+void
+rec_init_offsets_temp(
+/*==================*/
+ const rec_t* rec, /*!< in: temporary file record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets)/*!< in/out: array of offsets;
+ in: n=rec_offs_n_fields(offsets) */
+ __attribute__((nonnull));
+
+/*********************************************************//**
+Builds a temporary file record out of a data tuple.
+@see rec_init_offsets_temp() */
+UNIV_INTERN
+void
+rec_convert_dtuple_to_temp(
+/*=======================*/
+ rec_t* rec, /*!< out: record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields) /*!< in: number of fields */
+ __attribute__((nonnull));
+
/**************************************************************//**
Copies the first n fields of a physical record to a new physical record in
a buffer.
@@ -680,21 +702,6 @@ rec_fold(
__attribute__((pure));
#endif /* !UNIV_HOTBACKUP */
/*********************************************************//**
-Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
-UNIV_INTERN
-void
-rec_convert_dtuple_to_rec_comp(
-/*===========================*/
- rec_t* rec, /*!< in: origin of record */
- ulint extra, /*!< in: number of bytes to
- reserve between the record
- header and the data payload
- (normally REC_N_NEW_EXTRA_BYTES) */
- const dict_index_t* index, /*!< in: record descriptor */
- ulint status, /*!< in: status bits of the record */
- const dfield_t* fields, /*!< in: array of data fields */
- ulint n_fields);/*!< in: number of data fields */
-/*********************************************************//**
Builds a physical record out of a data tuple and
stores it into the given buffer.
@return pointer to the origin of physical record */
@@ -727,10 +734,7 @@ UNIV_INTERN
ulint
rec_get_converted_size_comp_prefix(
/*===============================*/
- const dict_index_t* index, /*!< in: record descriptor;
- dict_table_is_comp() is
- assumed to hold, even if
- it does not */
+ const dict_index_t* index, /*!< in: record descriptor */
const dfield_t* fields, /*!< in: array of data fields */
ulint n_fields,/*!< in: number of data fields */
ulint* extra); /*!< out: extra size */
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 91151312367..acd120d4d33 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -269,6 +269,10 @@ extern ulint srv_fatal_semaphore_wait_threshold;
#define SRV_SEMAPHORE_WAIT_EXTENSION 7200
extern ulint srv_dml_needed_delay;
+#ifdef UNIV_DEBUG
+extern my_bool srv_purge_view_update_only_debug;
+#endif /* UNIV_DEBUG */
+
extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs,
query threads, and lock table: we allocate
it from dynamic memory to get it to the
@@ -337,6 +341,9 @@ extern ulint srv_buf_pool_flushed;
reading of a disk page */
extern ulint srv_buf_pool_reads;
+/** print all user-level transactions deadlocks to mysqld stderr */
+extern my_bool srv_print_all_deadlocks;
+
/** Status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
@@ -712,7 +719,9 @@ struct export_var_struct{
ulint innodb_data_reads; /*!< I/O read requests */
ulint innodb_buffer_pool_pages_total; /*!< Buffer pool size */
ulint innodb_buffer_pool_pages_data; /*!< Data pages */
+ ulint innodb_buffer_pool_bytes_data; /*!< File bytes used */
ulint innodb_buffer_pool_pages_dirty; /*!< Dirty data pages */
+ ulint innodb_buffer_pool_bytes_dirty; /*!< File bytes modified */
ulint innodb_buffer_pool_pages_misc; /*!< Miscellanous pages */
ulint innodb_buffer_pool_pages_free; /*!< Free pages */
#ifdef UNIV_DEBUG
@@ -754,6 +763,11 @@ struct export_var_struct{
ulint innodb_rows_updated; /*!< srv_n_rows_updated */
ulint innodb_rows_deleted; /*!< srv_n_rows_deleted */
ulint innodb_truncated_status_writes; /*!< srv_truncated_status_writes */
+#ifdef UNIV_DEBUG
+ ulint innodb_purge_trx_id_age; /*!< max_trx_id - purged trx_id */
+ ulint innodb_purge_view_trx_id_age; /*!< rw_max_trx_id
+ - purged view's min trx_id */
+#endif /* UNIV_DEBUG */
};
/** Thread slot in the thread table */
diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h
index 2bd9e64476b..1e8acd65e01 100644
--- a/storage/innobase/include/trx0purge.h
+++ b/storage/innobase/include/trx0purge.h
@@ -156,6 +156,10 @@ struct trx_purge_struct{
than this */
undo_no_t purge_undo_no; /*!< Purge has advanced past all records
whose undo number is less than this */
+#ifdef UNIV_DEBUG
+ trx_id_t done_trx_no; /* Indicate 'purge pointer' which have
+ purged already accurately. */
+#endif /* UNIV_DEBUG */
/*-----------------------------*/
ibool next_stored; /*!< TRUE if the info of the next record
to purge is stored below: if yes, then
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 0b0b4b8d04c..800f4359c8a 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -49,9 +49,10 @@ Created 1/20/1994 Heikki Tuuri
#define _IB_TO_STR(s) #s
#define IB_TO_STR(s) _IB_TO_STR(s)
-#define INNODB_VERSION_MAJOR 1
-#define INNODB_VERSION_MINOR 1
-#define INNODB_VERSION_BUGFIX 8
+#include <mysql_version.h>
+
+#define INNODB_VERSION_MAJOR MYSQL_MAJOR_VERSION
+#define INNODB_VERSION_MINOR MYSQL_MINOR_VERSION
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
@@ -62,10 +63,7 @@ component, i.e. we show M.N.P as M.N */
#define INNODB_VERSION_SHORT \
(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
-#define INNODB_VERSION_STR \
- IB_TO_STR(INNODB_VERSION_MAJOR) "." \
- IB_TO_STR(INNODB_VERSION_MINOR) "." \
- IB_TO_STR(INNODB_VERSION_BUGFIX)
+#define INNODB_VERSION_STR MYSQL_SERVER_VERSION
#define REFMAN "http://dev.mysql.com/doc/refman/" \
IB_TO_STR(MYSQL_MAJOR_VERSION) "." \
diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
index 1b31d43e2b9..4791100f555 100644
--- a/storage/innobase/lock/lock0lock.c
+++ b/storage/innobase/lock/lock0lock.c
@@ -793,12 +793,16 @@ lock_reset_lock_and_trx_wait(
/*=========================*/
lock_t* lock) /*!< in: record lock */
{
- ut_ad((lock->trx)->wait_lock == lock);
ut_ad(lock_get_wait(lock));
/* Reset the back pointer in trx to this waiting lock request */
- (lock->trx)->wait_lock = NULL;
+ if (!(lock->type_mode & LOCK_CONV_BY_OTHER)) {
+ ut_ad((lock->trx)->wait_lock == lock);
+ (lock->trx)->wait_lock = NULL;
+ } else {
+ ut_ad(lock_get_type_low(lock) == LOCK_REC);
+ }
lock->type_mode &= ~LOCK_WAIT;
}
@@ -1439,9 +1443,9 @@ lock_rec_has_expl(
while (lock) {
if (lock->trx == trx
+ && !lock_is_wait_not_by_other(lock->type_mode)
&& lock_mode_stronger_or_eq(lock_get_mode(lock),
precise_mode & LOCK_MODE_MASK)
- && !lock_get_wait(lock)
&& (!lock_rec_get_rec_not_gap(lock)
|| (precise_mode & LOCK_REC_NOT_GAP)
|| heap_no == PAGE_HEAP_NO_SUPREMUM)
@@ -1862,7 +1866,7 @@ lock_rec_create(
HASH_INSERT(lock_t, hash, lock_sys->rec_hash,
lock_rec_fold(space, page_no), lock);
#endif
- if (UNIV_UNLIKELY(type_mode & LOCK_WAIT)) {
+ if (lock_is_wait_not_by_other(type_mode)) {
lock_set_lock_and_trx_wait(lock, trx);
}
@@ -1896,10 +1900,11 @@ lock_rec_enqueue_waiting(
const buf_block_t* block, /*!< in: buffer block containing
the record */
ulint heap_no,/*!< in: heap number of the record */
+ lock_t* lock, /*!< in: lock object; NULL if a new
+ one should be created. */
dict_index_t* index, /*!< in: index of record */
que_thr_t* thr) /*!< in: query thread */
{
- lock_t* lock;
trx_t* trx;
ut_ad(mutex_own(&kernel_mutex));
@@ -1934,17 +1939,26 @@ lock_rec_enqueue_waiting(
ut_ad(0);
}
- /* Enqueue the lock request that will wait to be granted */
+ if (lock == NULL) {
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) && trx->was_chosen_as_deadlock_victim) {
- return(DB_DEADLOCK);
- }
- lock = lock_rec_create(c_lock, type_mode | LOCK_WAIT,
- block, heap_no, index, trx);
+ if (wsrep_on(trx->mysql_thd) && trx->was_chosen_as_deadlock_victim) {
+ return(DB_DEADLOCK);
+ }
+ /* Enqueue the lock request that will wait to be granted */
+ lock = lock_rec_create(c_lock, type_mode | LOCK_WAIT,
+ block, heap_no, index, trx);
#else
- lock = lock_rec_create(type_mode | LOCK_WAIT,
- block, heap_no, index, trx);
-#endif
+ /* Enqueue the lock request that will wait to be granted */
+ lock = lock_rec_create(type_mode | LOCK_WAIT,
+ block, heap_no, index, trx);
+#endif /*WITH_WSREP */
+ } else {
+ ut_ad(lock->type_mode & LOCK_WAIT);
+ ut_ad(lock->type_mode & LOCK_CONV_BY_OTHER);
+
+ lock->type_mode &= ~LOCK_CONV_BY_OTHER;
+ lock_set_lock_and_trx_wait(lock, trx);
+ }
/* Check if a deadlock occurs: if yes, remove the lock request and
return an error code */
@@ -2217,6 +2231,7 @@ lock_rec_lock_slow(
#ifdef WITH_WSREP
lock_t *c_lock;
#endif
+ lock_t* lock;
ut_ad(mutex_own(&kernel_mutex));
ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
@@ -2236,7 +2251,27 @@ lock_rec_lock_slow(
trx = thr_get_trx(thr);
- if (lock_rec_has_expl(mode, block, heap_no, trx)) {
+ lock = lock_rec_has_expl(mode, block, heap_no, trx);
+ if (lock) {
+ if (lock->type_mode & LOCK_CONV_BY_OTHER) {
+ /* This lock or lock waiting was created by the other
+ transaction, not by the transaction (trx) itself.
+ So, the transaction (trx) should treat it collectly
+ according as whether granted or not. */
+
+ if (lock->type_mode & LOCK_WAIT) {
+ /* This lock request was not granted yet.
+ Should wait for granted. */
+
+ goto enqueue_waiting;
+ } else {
+ /* This lock request was already granted.
+ Just clearing the flag. */
+
+ lock->type_mode &= ~LOCK_CONV_BY_OTHER;
+ }
+ }
+
/* The trx already has a strong enough lock on rec: do
nothing */
@@ -2251,12 +2286,14 @@ lock_rec_lock_slow(
the queue, as this transaction does not have a lock strong
enough already granted on the record, we have to wait. */
+ ut_ad(lock == NULL);
+enqueue_waiting:
#ifdef WITH_WSREP
return(lock_rec_enqueue_waiting(c_lock,mode, block, heap_no,
- index, thr));
+ lock, index, thr));
#else
return(lock_rec_enqueue_waiting(mode, block, heap_no,
- index, thr));
+ lock, index, thr));
#endif
} else if (!impl) {
/* Set the requested lock on the record */
@@ -2408,7 +2445,8 @@ lock_grant(
TRX_QUE_LOCK_WAIT state, and there is no need to end the lock wait
for it */
- if (lock->trx->que_state == TRX_QUE_LOCK_WAIT) {
+ if (!(lock->type_mode & LOCK_CONV_BY_OTHER)
+ && lock->trx->que_state == TRX_QUE_LOCK_WAIT) {
trx_end_lock_wait(lock->trx);
}
}
@@ -2425,6 +2463,7 @@ lock_rec_cancel(
{
ut_ad(mutex_own(&kernel_mutex));
ut_ad(lock_get_type_low(lock) == LOCK_REC);
+ ut_ad(!(lock->type_mode & LOCK_CONV_BY_OTHER));
/* Reset the bit (there can be only one set bit) in the lock bitmap */
lock_rec_reset_nth_bit(lock, lock_rec_find_set_bit(lock));
@@ -2567,8 +2606,12 @@ lock_rec_reset_and_release_wait(
lock = lock_rec_get_first(block, heap_no);
while (lock != NULL) {
- if (lock_get_wait(lock)) {
+ if (lock_is_wait_not_by_other(lock->type_mode)) {
lock_rec_cancel(lock);
+ } else if (lock_get_wait(lock)) {
+ /* just reset LOCK_WAIT */
+ lock_rec_reset_nth_bit(lock, heap_no);
+ lock_reset_lock_and_trx_wait(lock);
} else {
lock_rec_reset_nth_bit(lock, heap_no);
}
@@ -3456,6 +3499,80 @@ lock_rec_restore_from_page_infimum(
/*=========== DEADLOCK CHECKING ======================================*/
+/*********************************************************************//**
+rewind(3) the file used for storing the latest detected deadlock and
+print a heading message to stderr if printing of all deadlocks to stderr
+is enabled. */
+UNIV_INLINE
+void
+lock_deadlock_start_print()
+/*=======================*/
+{
+ rewind(lock_latest_err_file);
+ ut_print_timestamp(lock_latest_err_file);
+
+ if (srv_print_all_deadlocks) {
+ fprintf(stderr, "InnoDB: transactions deadlock detected, "
+ "dumping detailed information.\n");
+ ut_print_timestamp(stderr);
+ }
+}
+
+/*********************************************************************//**
+Print a message to the deadlock file and possibly to stderr. */
+UNIV_INLINE
+void
+lock_deadlock_fputs(
+/*================*/
+ const char* msg) /*!< in: message to print */
+{
+ fputs(msg, lock_latest_err_file);
+
+ if (srv_print_all_deadlocks) {
+ fputs(msg, stderr);
+ }
+}
+
+/*********************************************************************//**
+Print transaction data to the deadlock file and possibly to stderr. */
+UNIV_INLINE
+void
+lock_deadlock_trx_print(
+/*====================*/
+ trx_t* trx, /*!< in: transaction */
+ ulint max_query_len) /*!< in: max query length to print, or 0 to
+ use the default max length */
+{
+ trx_print(lock_latest_err_file, trx, max_query_len);
+
+ if (srv_print_all_deadlocks) {
+ trx_print(stderr, trx, max_query_len);
+ }
+}
+
+/*********************************************************************//**
+Print lock data to the deadlock file and possibly to stderr. */
+UNIV_INLINE
+void
+lock_deadlock_lock_print(
+/*=====================*/
+ const lock_t* lock) /*!< in: record or table type lock */
+{
+ if (lock_get_type_low(lock) == LOCK_REC) {
+ lock_rec_print(lock_latest_err_file, lock);
+
+ if (srv_print_all_deadlocks) {
+ lock_rec_print(stderr, lock);
+ }
+ } else {
+ lock_table_print(lock_latest_err_file, lock);
+
+ if (srv_print_all_deadlocks) {
+ lock_table_print(stderr, lock);
+ }
+ }
+}
+
/********************************************************************//**
Checks if a lock request results in a deadlock.
@return TRUE if a deadlock was detected and we chose trx as a victim;
@@ -3499,30 +3616,25 @@ retry:
/* If the lock search exceeds the max step
or the max depth, the current trx will be
the victim. Print its information. */
- rewind(lock_latest_err_file);
- ut_print_timestamp(lock_latest_err_file);
+ lock_deadlock_start_print();
- fputs("TOO DEEP OR LONG SEARCH IN THE LOCK TABLE"
- " WAITS-FOR GRAPH, WE WILL ROLL BACK"
- " FOLLOWING TRANSACTION \n",
- lock_latest_err_file);
+ lock_deadlock_fputs(
+ "TOO DEEP OR LONG SEARCH IN THE LOCK TABLE"
+ " WAITS-FOR GRAPH, WE WILL ROLL BACK"
+ " FOLLOWING TRANSACTION \n\n"
+ "*** TRANSACTION:\n");
- fputs("\n*** TRANSACTION:\n", lock_latest_err_file);
- trx_print(lock_latest_err_file, trx, 3000);
+ lock_deadlock_trx_print(trx, 3000);
- fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n",
- lock_latest_err_file);
+ lock_deadlock_fputs(
+ "*** WAITING FOR THIS LOCK TO BE GRANTED:\n");
+
+ lock_deadlock_lock_print(lock);
- if (lock_get_type(lock) == LOCK_REC) {
- lock_rec_print(lock_latest_err_file, lock);
- } else {
- lock_table_print(lock_latest_err_file, lock);
- }
break;
case LOCK_VICTIM_IS_START:
- fputs("*** WE ROLL BACK TRANSACTION (2)\n",
- lock_latest_err_file);
+ lock_deadlock_fputs("*** WE ROLL BACK TRANSACTION (2)\n");
break;
default:
@@ -3637,45 +3749,33 @@ lock_deadlock_recursive(
point: a deadlock detected; or we have
searched the waits-for graph too long */
- FILE* ef = lock_latest_err_file;
+ lock_deadlock_start_print();
- rewind(ef);
- ut_print_timestamp(ef);
+ lock_deadlock_fputs("\n*** (1) TRANSACTION:\n");
- fputs("\n*** (1) TRANSACTION:\n", ef);
+ lock_deadlock_trx_print(wait_lock->trx, 3000);
- trx_print(ef, wait_lock->trx, 3000);
+ lock_deadlock_fputs(
+ "*** (1) WAITING FOR THIS LOCK"
+ " TO BE GRANTED:\n");
- fputs("*** (1) WAITING FOR THIS LOCK"
- " TO BE GRANTED:\n", ef);
+ lock_deadlock_lock_print(wait_lock);
- if (lock_get_type_low(wait_lock) == LOCK_REC) {
- lock_rec_print(ef, wait_lock);
- } else {
- lock_table_print(ef, wait_lock);
- }
+ lock_deadlock_fputs("*** (2) TRANSACTION:\n");
- fputs("*** (2) TRANSACTION:\n", ef);
+ lock_deadlock_trx_print(lock->trx, 3000);
- trx_print(ef, lock->trx, 3000);
+ lock_deadlock_fputs(
+ "*** (2) HOLDS THE LOCK(S):\n");
- fputs("*** (2) HOLDS THE LOCK(S):\n", ef);
+ lock_deadlock_lock_print(lock);
- if (lock_get_type_low(lock) == LOCK_REC) {
- lock_rec_print(ef, lock);
- } else {
- lock_table_print(ef, lock);
- }
+ lock_deadlock_fputs(
+ "*** (2) WAITING FOR THIS LOCK"
+ " TO BE GRANTED:\n");
- fputs("*** (2) WAITING FOR THIS LOCK"
- " TO BE GRANTED:\n", ef);
+ lock_deadlock_lock_print(start->wait_lock);
- if (lock_get_type_low(start->wait_lock)
- == LOCK_REC) {
- lock_rec_print(ef, start->wait_lock);
- } else {
- lock_table_print(ef, start->wait_lock);
- }
#ifdef UNIV_DEBUG
if (lock_print_waits) {
fputs("Deadlock detected\n",
@@ -3684,7 +3784,7 @@ lock_deadlock_recursive(
#endif /* UNIV_DEBUG */
#ifdef WITH_WSREP
if (wsrep_debug)
- fputs("WSREP: Deadlock detected\n", ef);
+ fputs("WSREP: Deadlock detected\n", stderr);
if (wsrep_thd_is_brute_force(start->mysql_thd) &&
wsrep_thd_is_brute_force(
wait_lock->trx->mysql_thd) &&
@@ -3702,14 +3802,6 @@ lock_deadlock_recursive(
}
}
#endif
- if (too_far) {
-
- fputs("TOO DEEP OR LONG SEARCH"
- " IN THE LOCK TABLE"
- " WAITS-FOR GRAPH\n", ef);
-
- return(LOCK_VICTIM_IS_START);
- }
if (trx_weight_ge(wait_lock->trx, start)) {
/* Our recursion starting point
@@ -3739,8 +3831,8 @@ lock_deadlock_recursive(
as a victim to try to avoid deadlocking our
recursion starting point transaction */
- fputs("*** WE ROLL BACK TRANSACTION (1)\n",
- ef);
+ lock_deadlock_fputs(
+ "*** WE ROLL BACK TRANSACTION (1)\n");
wait_lock->trx->was_chosen_as_deadlock_victim
= TRUE;
@@ -3828,6 +3920,7 @@ lock_table_create(
ut_ad(table && trx);
ut_ad(mutex_own(&kernel_mutex));
+ ut_ad(!(type_mode & LOCK_CONV_BY_OTHER));
if ((type_mode & LOCK_MODE_MASK) == LOCK_AUTO_INC) {
++table->n_waiting_or_granted_auto_inc_locks;
@@ -4429,6 +4522,7 @@ lock_cancel_waiting_and_release(
lock_t* lock) /*!< in: waiting lock request */
{
ut_ad(mutex_own(&kernel_mutex));
+ ut_ad(!(lock->type_mode & LOCK_CONV_BY_OTHER));
if (lock_get_type_low(lock) == LOCK_REC) {
@@ -5482,12 +5576,12 @@ lock_rec_insert_check_and_lock(
err = lock_rec_enqueue_waiting(c_lock, LOCK_X | LOCK_GAP
| LOCK_INSERT_INTENTION,
block, next_rec_heap_no,
- index, thr);
+ NULL, index, thr);
#else
err = lock_rec_enqueue_waiting(LOCK_X | LOCK_GAP
| LOCK_INSERT_INTENTION,
block, next_rec_heap_no,
- index, thr);
+ NULL, index, thr);
#endif
} else {
err = DB_SUCCESS;
@@ -5564,10 +5658,23 @@ lock_rec_convert_impl_to_expl(
if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, block,
heap_no, impl_trx)) {
+ ulint type_mode = (LOCK_REC | LOCK_X
+ | LOCK_REC_NOT_GAP);
+
+ /* If the delete-marked record was locked already,
+ we should reserve lock waiting for impl_trx as
+ implicit lock. Because cannot lock at this moment.*/
+
+ if (rec_get_deleted_flag(rec, rec_offs_comp(offsets))
+ && lock_rec_other_has_conflicting(
+ LOCK_X | LOCK_REC_NOT_GAP, block,
+ heap_no, impl_trx)) {
+
+ type_mode |= (LOCK_WAIT | LOCK_CONV_BY_OTHER);
+ }
lock_rec_add_to_queue(
- LOCK_REC | LOCK_X | LOCK_REC_NOT_GAP,
- block, heap_no, index, impl_trx);
+ type_mode, block, heap_no, index, impl_trx);
}
}
}
diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c
index 03ba4d12cd0..c4ad94a4906 100644
--- a/storage/innobase/log/log0recv.c
+++ b/storage/innobase/log/log0recv.c
@@ -965,8 +965,11 @@ recv_parse_or_apply_log_rec_body(
not NULL, then the log record is
applied to the page, and the log
record should be complete then */
- mtr_t* mtr) /*!< in: mtr or NULL; should be non-NULL
+ mtr_t* mtr, /*!< in: mtr or NULL; should be non-NULL
if and only if block is non-NULL */
+ ulint space_id)
+ /*!< in: tablespace id obtained by
+ parsing initial log record */
{
dict_index_t* index = NULL;
page_t* page;
@@ -1238,8 +1241,11 @@ recv_parse_or_apply_log_rec_body(
ut_ad(!page || page_type != FIL_PAGE_TYPE_ALLOCATED);
ptr = mlog_parse_string(ptr, end_ptr, page, page_zip);
break;
- case MLOG_FILE_CREATE:
case MLOG_FILE_RENAME:
+ ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type,
+ space_id, 0);
+ break;
+ case MLOG_FILE_CREATE:
case MLOG_FILE_DELETE:
case MLOG_FILE_CREATE2:
ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0, 0);
@@ -1611,7 +1617,8 @@ recv_recover_page_func(
recv_parse_or_apply_log_rec_body(recv->type, buf,
buf + recv->len,
- block, &mtr);
+ block, &mtr,
+ recv_addr->space);
end_lsn = recv->start_lsn + recv->len;
mach_write_to_8(FIL_PAGE_LSN + page, end_lsn);
@@ -2078,7 +2085,7 @@ recv_parse_log_rec(
#endif /* UNIV_LOG_LSN_DEBUG */
new_ptr = recv_parse_or_apply_log_rec_body(*type, new_ptr, end_ptr,
- NULL, NULL);
+ NULL, NULL, *space);
if (UNIV_UNLIKELY(new_ptr == NULL)) {
return(0);
diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c
index 0e8f606c311..8ea62c32113 100644
--- a/storage/innobase/rem/rem0rec.c
+++ b/storage/innobase/rem/rem0rec.c
@@ -170,7 +170,6 @@ rec_get_n_extern_new(
{
const byte* nulls;
const byte* lens;
- dict_field_t* field;
ulint null_mask;
ulint n_extern;
ulint i;
@@ -191,10 +190,13 @@ rec_get_n_extern_new(
/* read the lengths of fields 0..n */
do {
- ulint len;
+ const dict_field_t* field
+ = dict_index_get_nth_field(index, i);
+ const dict_col_t* col
+ = dict_field_get_col(field);
+ ulint len;
- field = dict_index_get_nth_field(index, i);
- if (!(dict_field_get_col(field)->prtype & DATA_NOT_NULL)) {
+ if (!(col->prtype & DATA_NOT_NULL)) {
/* nullable field => read the null flag */
if (UNIV_UNLIKELY(!(byte) null_mask)) {
@@ -212,8 +214,6 @@ rec_get_n_extern_new(
if (UNIV_UNLIKELY(!field->fixed_len)) {
/* Variable-length field: read the length */
- const dict_col_t* col
- = dict_field_get_col(field);
len = *lens--;
/* If the maximum length of the field is up
to 255 bytes, the actual length is always
@@ -242,16 +242,15 @@ rec_get_n_extern_new(
Determine the offset to each field in a leaf-page record
in ROW_FORMAT=COMPACT. This is a special case of
rec_init_offsets() and rec_get_offsets_func(). */
-UNIV_INTERN
+UNIV_INLINE __attribute__((nonnull))
void
rec_init_offsets_comp_ordinary(
/*===========================*/
const rec_t* rec, /*!< in: physical record in
ROW_FORMAT=COMPACT */
- ulint extra, /*!< in: number of bytes to reserve
- between the record header and
- the data payload
- (usually REC_N_NEW_EXTRA_BYTES) */
+ ibool temp, /*!< in: whether to use the
+ format for temporary files in
+ index creation */
const dict_index_t* index, /*!< in: record descriptor */
ulint* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
@@ -259,27 +258,38 @@ rec_init_offsets_comp_ordinary(
ulint i = 0;
ulint offs = 0;
ulint any_ext = 0;
- const byte* nulls = rec - (extra + 1);
+ const byte* nulls = temp
+ ? rec - 1
+ : rec - (1 + REC_N_NEW_EXTRA_BYTES);
const byte* lens = nulls
- UT_BITS_IN_BYTES(index->n_nullable);
- dict_field_t* field;
ulint null_mask = 1;
#ifdef UNIV_DEBUG
- /* We cannot invoke rec_offs_make_valid() here, because it can hold
- that extra != REC_N_NEW_EXTRA_BYTES. Similarly, rec_offs_validate()
- will fail in that case, because it invokes rec_get_status(). */
+ /* We cannot invoke rec_offs_make_valid() here if temp=TRUE.
+ Similarly, rec_offs_validate() will fail in that case, because
+ it invokes rec_get_status(). */
offsets[2] = (ulint) rec;
offsets[3] = (ulint) index;
#endif /* UNIV_DEBUG */
+ ut_ad(temp || dict_table_is_comp(index->table));
+
+ if (temp && dict_table_is_comp(index->table)) {
+ /* No need to do adjust fixed_len=0. We only need to
+ adjust it for ROW_FORMAT=REDUNDANT. */
+ temp = FALSE;
+ }
+
/* read the lengths of fields 0..n */
do {
- ulint len;
+ const dict_field_t* field
+ = dict_index_get_nth_field(index, i);
+ const dict_col_t* col
+ = dict_field_get_col(field);
+ ulint len;
- field = dict_index_get_nth_field(index, i);
- if (!(dict_field_get_col(field)->prtype
- & DATA_NOT_NULL)) {
+ if (!(col->prtype & DATA_NOT_NULL)) {
/* nullable field => read the null flag */
if (UNIV_UNLIKELY(!(byte) null_mask)) {
@@ -299,10 +309,9 @@ rec_init_offsets_comp_ordinary(
null_mask <<= 1;
}
- if (UNIV_UNLIKELY(!field->fixed_len)) {
+ if (!field->fixed_len
+ || (temp && !dict_col_get_fixed_size(col, temp))) {
/* Variable-length field: read the length */
- const dict_col_t* col
- = dict_field_get_col(field);
len = *lens--;
/* If the maximum length of the field is up
to 255 bytes, the actual length is always
@@ -396,9 +405,8 @@ rec_init_offsets(
= dict_index_get_n_unique_in_tree(index);
break;
case REC_STATUS_ORDINARY:
- rec_init_offsets_comp_ordinary(rec,
- REC_N_NEW_EXTRA_BYTES,
- index, offsets);
+ rec_init_offsets_comp_ordinary(
+ rec, FALSE, index, offsets);
return;
}
@@ -769,17 +777,19 @@ rec_get_nth_field_offs_old(
/**********************************************************//**
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
@return total size */
-UNIV_INTERN
+UNIV_INLINE __attribute__((warn_unused_result, nonnull(1,2)))
ulint
-rec_get_converted_size_comp_prefix(
-/*===============================*/
+rec_get_converted_size_comp_prefix_low(
+/*===================================*/
const dict_index_t* index, /*!< in: record descriptor;
dict_table_is_comp() is
assumed to hold, even if
it does not */
const dfield_t* fields, /*!< in: array of data fields */
ulint n_fields,/*!< in: number of data fields */
- ulint* extra) /*!< out: extra size */
+ ulint* extra, /*!< out: extra size */
+ ibool temp) /*!< in: whether this is a
+ temporary file record */
{
ulint extra_size;
ulint data_size;
@@ -788,15 +798,25 @@ rec_get_converted_size_comp_prefix(
ut_ad(fields);
ut_ad(n_fields > 0);
ut_ad(n_fields <= dict_index_get_n_fields(index));
+ ut_ad(!temp || extra);
- extra_size = REC_N_NEW_EXTRA_BYTES
+ extra_size = temp
+ ? UT_BITS_IN_BYTES(index->n_nullable)
+ : REC_N_NEW_EXTRA_BYTES
+ UT_BITS_IN_BYTES(index->n_nullable);
data_size = 0;
+ if (temp && dict_table_is_comp(index->table)) {
+ /* No need to do adjust fixed_len=0. We only need to
+ adjust it for ROW_FORMAT=REDUNDANT. */
+ temp = FALSE;
+ }
+
/* read the lengths of fields 0..n */
for (i = 0; i < n_fields; i++) {
const dict_field_t* field;
ulint len;
+ ulint fixed_len;
const dict_col_t* col;
field = dict_index_get_nth_field(index, i);
@@ -812,8 +832,14 @@ rec_get_converted_size_comp_prefix(
continue;
}
- ut_ad(len <= col->len || col->mtype == DATA_BLOB);
+ ut_ad(len <= col->len || col->mtype == DATA_BLOB
+ || (col->len == 0 && col->mtype == DATA_VARCHAR));
+ fixed_len = field->fixed_len;
+ if (temp && fixed_len
+ && !dict_col_get_fixed_size(col, temp)) {
+ fixed_len = 0;
+ }
/* If the maximum length of a variable-length field
is up to 255 bytes, the actual length is always stored
in one byte. If the maximum length is more than 255
@@ -821,11 +847,20 @@ rec_get_converted_size_comp_prefix(
0..127. The length will be encoded in two bytes when
it is 128 or more, or when the field is stored externally. */
- if (field->fixed_len) {
- ut_ad(len == field->fixed_len);
+ if (fixed_len) {
+#ifdef UNIV_DEBUG
+ ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
+ ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
+
+ ut_ad(len <= fixed_len);
+
+ ut_ad(!mbmaxlen || len >= mbminlen
+ * (fixed_len / mbmaxlen));
+
/* dict_index_add_col() should guarantee this */
ut_ad(!field->prefix_len
- || field->fixed_len == field->prefix_len);
+ || fixed_len == field->prefix_len);
+#endif /* UNIV_DEBUG */
} else if (dfield_is_ext(&fields[i])) {
ut_ad(col->len >= 256 || col->mtype == DATA_BLOB);
extra_size += 2;
@@ -842,7 +877,7 @@ rec_get_converted_size_comp_prefix(
data_size += len;
}
- if (UNIV_LIKELY_NULL(extra)) {
+ if (extra) {
*extra = extra_size;
}
@@ -850,6 +885,23 @@ rec_get_converted_size_comp_prefix(
}
/**********************************************************//**
+Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
+@return total size */
+UNIV_INTERN
+ulint
+rec_get_converted_size_comp_prefix(
+/*===============================*/
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra) /*!< out: extra size */
+{
+ ut_ad(dict_table_is_comp(index->table));
+ return(rec_get_converted_size_comp_prefix_low(
+ index, fields, n_fields, extra, FALSE));
+}
+
+/**********************************************************//**
Determines the size of a data tuple in ROW_FORMAT=COMPACT.
@return total size */
UNIV_INTERN
@@ -893,8 +945,8 @@ rec_get_converted_size_comp(
return(ULINT_UNDEFINED);
}
- return(size + rec_get_converted_size_comp_prefix(index, fields,
- n_fields, extra));
+ return(size + rec_get_converted_size_comp_prefix_low(
+ index, fields, n_fields, extra, FALSE));
}
/***********************************************************//**
@@ -1071,19 +1123,18 @@ rec_convert_dtuple_to_rec_old(
/*********************************************************//**
Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
-UNIV_INTERN
+UNIV_INLINE __attribute__((nonnull))
void
rec_convert_dtuple_to_rec_comp(
/*===========================*/
rec_t* rec, /*!< in: origin of record */
- ulint extra, /*!< in: number of bytes to
- reserve between the record
- header and the data payload
- (normally REC_N_NEW_EXTRA_BYTES) */
const dict_index_t* index, /*!< in: record descriptor */
- ulint status, /*!< in: status bits of the record */
const dfield_t* fields, /*!< in: array of data fields */
- ulint n_fields)/*!< in: number of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint status, /*!< in: status bits of the record */
+ ibool temp) /*!< in: whether to use the
+ format for temporary files in
+ index creation */
{
const dfield_t* field;
const dtype_t* type;
@@ -1095,31 +1146,44 @@ rec_convert_dtuple_to_rec_comp(
ulint n_node_ptr_field;
ulint fixed_len;
ulint null_mask = 1;
- ut_ad(extra == 0 || dict_table_is_comp(index->table));
- ut_ad(extra == 0 || extra == REC_N_NEW_EXTRA_BYTES);
+ ut_ad(temp || dict_table_is_comp(index->table));
ut_ad(n_fields > 0);
- switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
- case REC_STATUS_ORDINARY:
+ if (temp) {
+ ut_ad(status == REC_STATUS_ORDINARY);
ut_ad(n_fields <= dict_index_get_n_fields(index));
n_node_ptr_field = ULINT_UNDEFINED;
- break;
- case REC_STATUS_NODE_PTR:
- ut_ad(n_fields == dict_index_get_n_unique_in_tree(index) + 1);
- n_node_ptr_field = n_fields - 1;
- break;
- case REC_STATUS_INFIMUM:
- case REC_STATUS_SUPREMUM:
- ut_ad(n_fields == 1);
- n_node_ptr_field = ULINT_UNDEFINED;
- break;
- default:
- ut_error;
- return;
+ nulls = rec - 1;
+ if (dict_table_is_comp(index->table)) {
+ /* No need to do adjust fixed_len=0. We only
+ need to adjust it for ROW_FORMAT=REDUNDANT. */
+ temp = FALSE;
+ }
+ } else {
+ nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
+
+ switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
+ case REC_STATUS_ORDINARY:
+ ut_ad(n_fields <= dict_index_get_n_fields(index));
+ n_node_ptr_field = ULINT_UNDEFINED;
+ break;
+ case REC_STATUS_NODE_PTR:
+ ut_ad(n_fields
+ == dict_index_get_n_unique_in_tree(index) + 1);
+ n_node_ptr_field = n_fields - 1;
+ break;
+ case REC_STATUS_INFIMUM:
+ case REC_STATUS_SUPREMUM:
+ ut_ad(n_fields == 1);
+ n_node_ptr_field = ULINT_UNDEFINED;
+ break;
+ default:
+ ut_error;
+ return;
+ }
}
end = rec;
- nulls = rec - (extra + 1);
lens = nulls - UT_BITS_IN_BYTES(index->n_nullable);
/* clear the SQL-null flags */
memset(lens + 1, 0, nulls - lens);
@@ -1165,6 +1229,10 @@ rec_convert_dtuple_to_rec_comp(
ifield = dict_index_get_nth_field(index, i);
fixed_len = ifield->fixed_len;
+ if (temp && fixed_len
+ && !dict_col_get_fixed_size(ifield->col, temp)) {
+ fixed_len = 0;
+ }
/* If the maximum length of a variable-length field
is up to 255 bytes, the actual length is always stored
in one byte. If the maximum length is more than 255
@@ -1172,8 +1240,17 @@ rec_convert_dtuple_to_rec_comp(
0..127. The length will be encoded in two bytes when
it is 128 or more, or when the field is stored externally. */
if (fixed_len) {
- ut_ad(len == fixed_len);
+#ifdef UNIV_DEBUG
+ ulint mbminlen = DATA_MBMINLEN(
+ ifield->col->mbminmaxlen);
+ ulint mbmaxlen = DATA_MBMAXLEN(
+ ifield->col->mbminmaxlen);
+
+ ut_ad(len <= fixed_len);
+ ut_ad(!mbmaxlen || len >= mbminlen
+ * (fixed_len / mbmaxlen));
ut_ad(!dfield_is_ext(field));
+#endif /* UNIV_DEBUG */
} else if (dfield_is_ext(field)) {
ut_ad(ifield->col->len >= 256
|| ifield->col->mtype == DATA_BLOB);
@@ -1225,8 +1302,7 @@ rec_convert_dtuple_to_rec_new(
rec = buf + extra_size;
rec_convert_dtuple_to_rec_comp(
- rec, REC_N_NEW_EXTRA_BYTES, index, status,
- dtuple->fields, dtuple->n_fields);
+ rec, index, dtuple->fields, dtuple->n_fields, status, FALSE);
/* Set the info bits of the record */
rec_set_info_and_status_bits(rec, dtuple_get_info_bits(dtuple));
@@ -1288,6 +1364,54 @@ rec_convert_dtuple_to_rec(
return(rec);
}
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
+Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
+@return total size */
+UNIV_INTERN
+ulint
+rec_get_converted_size_temp(
+/*========================*/
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra) /*!< out: extra size */
+{
+ return(rec_get_converted_size_comp_prefix_low(
+ index, fields, n_fields, extra, TRUE));
+}
+
+/******************************************************//**
+Determine the offset to each field in temporary file.
+@see rec_convert_dtuple_to_temp() */
+UNIV_INTERN
+void
+rec_init_offsets_temp(
+/*==================*/
+ const rec_t* rec, /*!< in: temporary file record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets)/*!< in/out: array of offsets;
+ in: n=rec_offs_n_fields(offsets) */
+{
+ rec_init_offsets_comp_ordinary(rec, TRUE, index, offsets);
+}
+
+/*********************************************************//**
+Builds a temporary file record out of a data tuple.
+@see rec_init_offsets_temp() */
+UNIV_INTERN
+void
+rec_convert_dtuple_to_temp(
+/*=======================*/
+ rec_t* rec, /*!< out: record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields) /*!< in: number of fields */
+{
+ rec_convert_dtuple_to_rec_comp(rec, index, fields, n_fields,
+ REC_STATUS_ORDINARY, TRUE);
+}
+
/**************************************************************//**
Copies the first n fields of a physical record to a data tuple. The fields
are copied to the memory heap. */
@@ -1498,6 +1622,7 @@ rec_copy_prefix_to_buf(
return(*buf + (rec - (lens + 1)));
}
+#endif /* UNIV_HOTBACKUP */
/***************************************************************//**
Validates the consistency of an old-style physical record.
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index 0b9993e2969..f5d387191ac 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -2301,7 +2301,10 @@ row_ins_index_entry(
err = row_ins_index_entry_low(BTR_MODIFY_LEAF, index, entry,
n_ext, thr);
if (err != DB_FAIL) {
-
+ if (index == dict_table_get_first_index(index->table)
+ && thr_get_trx(thr)->mysql_thd != 0) {
+ DEBUG_SYNC_C("row_ins_clust_index_entry_leaf_after");
+ }
return(err);
}
diff --git a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c
index 7c9fb8812e6..d34ad467588 100644
--- a/storage/innobase/row/row0merge.c
+++ b/storage/innobase/row/row0merge.c
@@ -298,6 +298,7 @@ row_merge_buf_add(
for (i = 0; i < n_fields; i++, field++, ifield++) {
const dict_col_t* col;
ulint col_no;
+ ulint fixed_len;
const dfield_t* row_field;
ulint len;
@@ -346,9 +347,30 @@ row_merge_buf_add(
ut_ad(len <= col->len || col->mtype == DATA_BLOB);
- if (ifield->fixed_len) {
- ut_ad(len == ifield->fixed_len);
+ fixed_len = ifield->fixed_len;
+ if (fixed_len && !dict_table_is_comp(index->table)
+ && DATA_MBMINLEN(col->mbminmaxlen)
+ != DATA_MBMAXLEN(col->mbminmaxlen)) {
+ /* CHAR in ROW_FORMAT=REDUNDANT is always
+ fixed-length, but in the temporary file it is
+ variable-length for variable-length character
+ sets. */
+ fixed_len = 0;
+ }
+
+ if (fixed_len) {
+#ifdef UNIV_DEBUG
+ ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
+ ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
+
+ /* len should be between size calcualted base on
+ mbmaxlen and mbminlen */
+ ut_ad(len <= fixed_len);
+ ut_ad(!mbmaxlen || len >= mbminlen
+ * (fixed_len / mbmaxlen));
+
ut_ad(!dfield_is_ext(field));
+#endif /* UNIV_DEBUG */
} else if (dfield_is_ext(field)) {
extra_size += 2;
} else if (len < 128
@@ -369,12 +391,11 @@ row_merge_buf_add(
ulint size;
ulint extra;
- size = rec_get_converted_size_comp(index,
- REC_STATUS_ORDINARY,
- entry, n_fields, &extra);
+ size = rec_get_converted_size_temp(
+ index, entry, n_fields, &extra);
- ut_ad(data_size + extra_size + REC_N_NEW_EXTRA_BYTES == size);
- ut_ad(extra_size + REC_N_NEW_EXTRA_BYTES == extra);
+ ut_ad(data_size + extra_size == size);
+ ut_ad(extra_size == extra);
}
#endif /* UNIV_DEBUG */
@@ -578,14 +599,9 @@ row_merge_buf_write(
ulint extra_size;
const dfield_t* entry = buf->tuples[i];
- size = rec_get_converted_size_comp(index,
- REC_STATUS_ORDINARY,
- entry, n_fields,
- &extra_size);
+ size = rec_get_converted_size_temp(
+ index, entry, n_fields, &extra_size);
ut_ad(size >= extra_size);
- ut_ad(extra_size >= REC_N_NEW_EXTRA_BYTES);
- extra_size -= REC_N_NEW_EXTRA_BYTES;
- size -= REC_N_NEW_EXTRA_BYTES;
/* Encode extra_size + 1 */
if (extra_size + 1 < 0x80) {
@@ -598,9 +614,8 @@ row_merge_buf_write(
ut_ad(b + size < block[1]);
- rec_convert_dtuple_to_rec_comp(b + extra_size, 0, index,
- REC_STATUS_ORDINARY,
- entry, n_fields);
+ rec_convert_dtuple_to_temp(b + extra_size, index,
+ entry, n_fields);
b += size;
@@ -704,6 +719,8 @@ row_merge_read(
ib_uint64_t ofs = ((ib_uint64_t) offset) * sizeof *buf;
ibool success;
+ DBUG_EXECUTE_IF("row_merge_read_failure", return(FALSE););
+
#ifdef UNIV_DEBUG
if (row_merge_print_block_read) {
fprintf(stderr, "row_merge_read fd=%d ofs=%lu\n",
@@ -750,6 +767,8 @@ row_merge_write(
(ulint) (ofs >> 32),
buf_len);
+ DBUG_EXECUTE_IF("row_merge_write_failure", return(FALSE););
+
#ifdef UNIV_DEBUG
if (row_merge_print_block_write) {
fprintf(stderr, "row_merge_write fd=%d ofs=%lu\n",
@@ -862,7 +881,7 @@ err_exit:
*mrec = *buf + extra_size;
- rec_init_offsets_comp_ordinary(*mrec, 0, index, offsets);
+ rec_init_offsets_temp(*mrec, index, offsets);
data_size = rec_offs_data_size(offsets);
@@ -881,7 +900,7 @@ err_exit:
*mrec = b + extra_size;
- rec_init_offsets_comp_ordinary(*mrec, 0, index, offsets);
+ rec_init_offsets_temp(*mrec, index, offsets);
data_size = rec_offs_data_size(offsets);
ut_ad(extra_size + data_size < sizeof *buf);
@@ -2214,7 +2233,7 @@ row_merge_drop_temp_indexes(void)
/*********************************************************************//**
Creates temperary merge files, and if UNIV_PFS_IO defined, register
the file descriptor with Performance Schema.
-@return File descriptor */
+@return file descriptor, or -1 on failure */
UNIV_INLINE
int
row_merge_file_create_low(void)
@@ -2236,12 +2255,19 @@ row_merge_file_create_low(void)
#ifdef UNIV_PFS_IO
register_pfs_file_open_end(locker, fd);
#endif
+ if (fd < 0) {
+ fprintf(stderr,
+ "InnoDB: Error: Cannot create temporary merge file\n");
+ return(-1);
+ }
return(fd);
}
+
/*********************************************************************//**
-Create a merge file. */
-static
-void
+Create a merge file.
+@return file descriptor, or -1 on failure */
+static __attribute__((nonnull, warn_unused_result))
+int
row_merge_file_create(
/*==================*/
merge_file_t* merge_file) /*!< out: merge file structure */
@@ -2249,6 +2275,7 @@ row_merge_file_create(
merge_file->fd = row_merge_file_create_low();
merge_file->offset = 0;
merge_file->n_rec = 0;
+ return(merge_file->fd);
}
/*********************************************************************//**
@@ -2494,6 +2521,28 @@ row_merge_rename_tables(
goto err_exit;
}
+ /* Generate the redo logs for file operations */
+ fil_mtr_rename_log(old_table->space, old_name,
+ new_table->space, new_table->name, tmp_name);
+
+ /* What if the redo logs are flushed to disk here? This is
+ tested with following crash point */
+ DBUG_EXECUTE_IF("bug14669848_precommit", log_buffer_flush_to_disk();
+ DBUG_SUICIDE(););
+
+ /* File operations cannot be rolled back. So, before proceeding
+ with file operations, commit the dictionary changes.*/
+ trx_commit_for_mysql(trx);
+
+ /* If server crashes here, the dictionary in InnoDB and MySQL
+ will differ. The .ibd files and the .frm files must be swapped
+ manually by the administrator. No loss of data. */
+ DBUG_EXECUTE_IF("bug14669848", DBUG_SUICIDE(););
+
+ /* Ensure that the redo logs are flushed to disk. The config
+ innodb_flush_log_at_trx_commit must not affect this. */
+ log_buffer_flush_to_disk();
+
/* The following calls will also rename the .ibd data files if
the tables are stored in a single-table tablespace */
@@ -2665,7 +2714,7 @@ row_merge_build_indexes(
ulint block_size;
ulint i;
ulint error;
- int tmpfd;
+ int tmpfd = -1;
ut_ad(trx);
ut_ad(old_table);
@@ -2682,13 +2731,31 @@ row_merge_build_indexes(
block_size = 3 * sizeof *block;
block = os_mem_alloc_large(&block_size);
+ /* Initialize all the merge file descriptors, so that we
+ don't call row_merge_file_destroy() on uninitialized
+ merge file descriptor */
+
+ for (i = 0; i < n_indexes; i++) {
+ merge_files[i].fd = -1;
+ }
+
for (i = 0; i < n_indexes; i++) {
- row_merge_file_create(&merge_files[i]);
+ if (row_merge_file_create(&merge_files[i]) < 0)
+ {
+ error = DB_OUT_OF_MEMORY;
+ goto func_exit;
+ }
}
tmpfd = row_merge_file_create_low();
+ if (tmpfd < 0)
+ {
+ error = DB_OUT_OF_MEMORY;
+ goto func_exit;
+ }
+
/* Reset the MySQL row buffer that is used when reporting
duplicate keys. */
innobase_rec_reset(table);
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 7e1d18d41b6..73da6215f0d 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -4140,6 +4140,13 @@ end:
trx->error_state = DB_SUCCESS;
trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
+ } else {
+ if (old_is_tmp && !new_is_tmp) {
+ /* After ALTER TABLE the table statistics
+ needs to be rebuilt. It will be rebuilt
+ when the table is loaded again. */
+ table->stat_initialized = FALSE;
+ }
}
}
diff --git a/storage/innobase/row/row0umod.c b/storage/innobase/row/row0umod.c
index 9e5fb8686c6..3c933c87b27 100644
--- a/storage/innobase/row/row0umod.c
+++ b/storage/innobase/row/row0umod.c
@@ -519,6 +519,7 @@ row_undo_mod_upd_del_sec(
ulint err = DB_SUCCESS;
ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
+ ut_ad(!node->undo_row);
heap = mem_heap_create(1024);
while (node->index != NULL) {
@@ -580,6 +581,8 @@ row_undo_mod_del_mark_sec(
dict_index_t* index;
ulint err;
+ ut_ad(!node->undo_row);
+
heap = mem_heap_create(1024);
while (node->index != NULL) {
diff --git a/storage/innobase/row/row0undo.c b/storage/innobase/row/row0undo.c
index a1c1d72f8c6..74fc1baf1d2 100644
--- a/storage/innobase/row/row0undo.c
+++ b/storage/innobase/row/row0undo.c
@@ -216,7 +216,7 @@ row_undo_search_clust_to_pcur(
node->row = row_build(ROW_COPY_DATA, clust_index, rec,
offsets, NULL, ext, node->heap);
- if (node->update) {
+ if (node->rec_type == TRX_UNDO_UPD_EXIST_REC) {
node->undo_row = dtuple_copy(node->row, node->heap);
row_upd_replace(node->undo_row, &node->undo_ext,
clust_index, node->update, node->heap);
diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
index dfa5a683acf..f872955f955 100644
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
@@ -58,6 +58,8 @@ Created 10/8/1995 Heikki Tuuri
*******************************************************/
/* Dummy comment */
+#include "m_string.h" /* for my_sys.h */
+#include "my_sys.h" /* DEBUG_SYNC_C */
#include "srv0srv.h"
#include "ut0mem.h"
@@ -83,6 +85,7 @@ Created 10/8/1995 Heikki Tuuri
#include "ha_prototypes.h"
#include "trx0i_s.h"
#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
+#include "read0read.h"
#include "mysql/plugin.h"
#include "mysql/service_thd_wait.h"
@@ -364,6 +367,9 @@ UNIV_INTERN lint srv_conc_n_threads = 0;
InnoDB */
UNIV_INTERN ulint srv_conc_n_waiting_threads = 0;
+/* print all user-level transactions deadlocks to mysqld stderr */
+UNIV_INTERN my_bool srv_print_all_deadlocks = FALSE;
+
typedef struct srv_conc_slot_struct srv_conc_slot_t;
struct srv_conc_slot_struct{
os_event_t event; /*!< event to wait */
@@ -1658,6 +1664,10 @@ srv_suspend_mysql_thread(
trx = thr_get_trx(thr);
+ if (trx->mysql_thd != 0) {
+ DEBUG_SYNC_C("srv_suspend_mysql_thread_enter");
+ }
+
os_event_set(srv_lock_timeout_thread_event);
mutex_enter(&kernel_mutex);
@@ -2109,13 +2119,15 @@ void
srv_export_innodb_status(void)
/*==========================*/
{
- buf_pool_stat_t stat;
- ulint LRU_len;
- ulint free_len;
- ulint flush_list_len;
+ buf_pool_stat_t stat;
+ buf_pools_list_size_t buf_pools_list_size;
+ ulint LRU_len;
+ ulint free_len;
+ ulint flush_list_len;
buf_get_total_stat(&stat);
buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len);
+ buf_get_total_list_size_in_bytes(&buf_pools_list_size);
mutex_enter(&srv_innodb_monitor_mutex);
@@ -2144,7 +2156,12 @@ srv_export_innodb_status(void)
export_vars.innodb_buffer_pool_read_ahead_evicted
= stat.n_ra_pages_evicted;
export_vars.innodb_buffer_pool_pages_data = LRU_len;
+ export_vars.innodb_buffer_pool_bytes_data =
+ buf_pools_list_size.LRU_bytes
+ + buf_pools_list_size.unzip_LRU_bytes;
export_vars.innodb_buffer_pool_pages_dirty = flush_list_len;
+ export_vars.innodb_buffer_pool_bytes_dirty =
+ buf_pools_list_size.flush_list_bytes;
export_vars.innodb_buffer_pool_pages_free = free_len;
#ifdef UNIV_DEBUG
export_vars.innodb_buffer_pool_pages_latched
@@ -2190,6 +2207,23 @@ srv_export_innodb_status(void)
export_vars.innodb_rows_deleted = srv_n_rows_deleted;
export_vars.innodb_truncated_status_writes = srv_truncated_status_writes;
+#ifdef UNIV_DEBUG
+ if (trx_sys->max_trx_id < purge_sys->done_trx_no) {
+ export_vars.innodb_purge_trx_id_age = 0;
+ } else {
+ export_vars.innodb_purge_trx_id_age =
+ trx_sys->max_trx_id - purge_sys->done_trx_no;
+ }
+
+ if (!purge_sys->view
+ || trx_sys->max_trx_id < purge_sys->view->up_limit_id) {
+ export_vars.innodb_purge_view_trx_id_age = 0;
+ } else {
+ export_vars.innodb_purge_view_trx_id_age =
+ trx_sys->max_trx_id - purge_sys->view->up_limit_id;
+ }
+#endif /* UNIV_DEBUG */
+
mutex_exit(&srv_innodb_monitor_mutex);
}
@@ -2916,6 +2950,26 @@ loop:
for (i = 0; i < 10; i++) {
ulint cur_time = ut_time_ms();
+#ifdef UNIV_DEBUG
+ if (btr_cur_limit_optimistic_insert_debug
+ && srv_n_purge_threads == 0) {
+ /* If btr_cur_limit_optimistic_insert_debug is enabled
+ and no purge_threads, purge opportunity is increased
+ by x100 (1purge/100msec), to speed up debug scripts
+ which should wait for purged. */
+ next_itr_time -= 900;
+
+ srv_main_thread_op_info = "master purging";
+
+ srv_master_do_purge();
+
+ if (srv_fast_shutdown && srv_shutdown_state > 0) {
+
+ goto background_loop;
+ }
+ }
+#endif /* UNIV_DEBUG */
+
/* ALTER TABLE in MySQL requires on Unix that the table handler
can drop tables lazily after there no longer are SELECT
queries to them. */
diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c
index 96f01ea81b5..719851218c3 100644
--- a/storage/innobase/trx/trx0purge.c
+++ b/storage/innobase/trx/trx0purge.c
@@ -61,6 +61,10 @@ UNIV_INTERN mysql_pfs_key_t trx_purge_latch_key;
UNIV_INTERN mysql_pfs_key_t purge_sys_bh_mutex_key;
#endif /* UNIV_PFS_MUTEX */
+#ifdef UNIV_DEBUG
+UNIV_INTERN my_bool srv_purge_view_update_only_debug;
+#endif /* UNIV_DEBUG */
+
/*****************************************************************//**
Checks if trx_id is >= purge_view: then it is guaranteed that its update
undo log still exists in the system.
@@ -236,6 +240,7 @@ trx_purge_sys_create(
purge_sys->purge_trx_no = 0;
purge_sys->purge_undo_no = 0;
purge_sys->next_stored = FALSE;
+ ut_d(purge_sys->done_trx_no = 0);
rw_lock_create(trx_purge_latch_key,
&purge_sys->latch, SYNC_PURGE_LATCH);
@@ -656,6 +661,12 @@ trx_purge_truncate_if_arr_empty(void)
{
static ulint count;
+#ifdef UNIV_DEBUG
+ if (purge_sys->arr->n_used == 0) {
+ purge_sys->done_trx_no = purge_sys->purge_trx_no;
+ }
+#endif /* UNIV_DEBUG */
+
if (!(++count % TRX_SYS_N_RSEGS) && purge_sys->arr->n_used == 0) {
trx_purge_truncate_history();
@@ -1173,6 +1184,12 @@ trx_purge(
rw_lock_x_unlock(&(purge_sys->latch));
+#ifdef UNIV_DEBUG
+ if (srv_purge_view_update_only_debug) {
+ return(0);
+ }
+#endif
+
purge_sys->state = TRX_PURGE_ON;
purge_sys->handle_limit = purge_sys->n_pages_handled + limit;
diff --git a/storage/innobase/trx/trx0rec.c b/storage/innobase/trx/trx0rec.c
index 2f1389ae263..f80f58493aa 100644
--- a/storage/innobase/trx/trx0rec.c
+++ b/storage/innobase/trx/trx0rec.c
@@ -36,6 +36,7 @@ Created 3/26/1996 Heikki Tuuri
#ifndef UNIV_HOTBACKUP
#include "dict0dict.h"
#include "ut0mem.h"
+#include "read0read.h"
#include "row0ext.h"
#include "row0upd.h"
#include "que0que.h"
@@ -1634,6 +1635,25 @@ trx_undo_prev_version_build(
if (row_upd_changes_field_size_or_external(index, offsets, update)) {
ulint n_ext;
+ /* We should confirm the existence of disowned external data,
+ if the previous version record is delete marked. If the trx_id
+ of the previous record is seen by purge view, we should treat
+ it as missing history, because the disowned external data
+ might be purged already.
+
+ The inherited external data (BLOBs) can be freed (purged)
+ after trx_id was committed, provided that no view was started
+ before trx_id. If the purge view can see the committed
+ delete-marked record by trx_id, no transactions need to access
+ the BLOB. */
+
+ if ((update->info_bits & REC_INFO_DELETED_FLAG)
+ && read_view_sees_trx_id(purge_sys->view, trx_id)) {
+ /* treat as a fresh insert, not to
+ cause assertion error at the caller. */
+ return(DB_SUCCESS);
+ }
+
/* We have to set the appropriate extern storage bits in the
old version of the record: the extern bits in rec for those
fields that update does NOT update, as well as the bits for
diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h
index 545daca12fe..80762296395 100644
--- a/storage/maria/ha_maria.h
+++ b/storage/maria/ha_maria.h
@@ -35,7 +35,6 @@ C_MODE_START
ICP_RESULT index_cond_func_maria(void *arg);
C_MODE_END
-extern ulong maria_sort_buffer_size;
extern TYPELIB maria_recover_typelib;
extern ulonglong maria_recover_options;
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 8e68f5a7898..1feb2ae5df2 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -4021,8 +4021,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
if (rep_quick && (param->testflag & T_FORCE_UNIQUENESS))
{
- my_off_t skr= (share->state.state.data_file_length +
- (sort_info.org_data_file_type == COMPRESSED_RECORD) ?
+ my_off_t skr= share->state.state.data_file_length +
+ ((sort_info.org_data_file_type == COMPRESSED_RECORD) ?
MEMMAP_EXTRA_MARGIN : 0);
#ifdef USE_RELOC
if (sort_info.org_data_file_type == STATIC_RECORD &&
@@ -4540,8 +4540,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info,
if (rep_quick && (param->testflag & T_FORCE_UNIQUENESS))
{
- my_off_t skr= (share->state.state.data_file_length +
- (sort_info.org_data_file_type == COMPRESSED_RECORD) ?
+ my_off_t skr= share->state.state.data_file_length +
+ ((sort_info.org_data_file_type == COMPRESSED_RECORD) ?
MEMMAP_EXTRA_MARGIN : 0);
#ifdef USE_RELOC
if (sort_info.org_data_file_type == STATIC_RECORD &&
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index df534242f87..770c7d660b2 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -77,7 +77,7 @@ static MYSQL_THDVAR_ULONG(repair_threads, PLUGIN_VAR_RQCMDARG,
static MYSQL_THDVAR_ULONGLONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG,
"The buffer that is allocated when sorting the index when doing "
"a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE", NULL, NULL,
- 8192 * 1024, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD), SIZE_T_MAX, 1);
+ 8192 * 1024, MIN_SORT_BUFFER + MALLOC_OVERHEAD, SIZE_T_MAX, 1);
static MYSQL_SYSVAR_BOOL(use_mmap, opt_myisam_use_mmap, PLUGIN_VAR_NOCMDARG,
"Use memory mapping for reading and writing MyISAM tables", NULL, NULL, FALSE);
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index 438057e22df..22225303bae 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -349,6 +349,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
}
else if (pos->type == HA_KEYTYPE_BINARY)
pos->charset= &my_charset_bin;
+ if (!(share->keyinfo[i].flag & HA_SPATIAL) &&
+ pos->start > share->base.reclength)
+ {
+ my_errno= HA_ERR_CRASHED;
+ goto err;
+ }
}
if (share->keyinfo[i].flag & HA_SPATIAL)
{
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index 968cb9624a6..01fa10de7a3 100644
--- a/storage/myisam/mi_search.c
+++ b/storage/myisam/mi_search.c
@@ -949,9 +949,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
("Found too long binary packed key: %u of %u at 0x%lx",
length, keyinfo->maxlength, (long) *page_pos));
DBUG_DUMP("key", *page_pos, 16);
- mi_print_error(keyinfo->share, HA_ERR_CRASHED);
- my_errno=HA_ERR_CRASHED;
- DBUG_RETURN(0); /* Wrong key */
+ goto crashed; /* Wrong key */
}
/* Key is packed against prev key, take prefix from prev key. */
from= key;
@@ -994,6 +992,8 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
if (from == from_end) { from=page; from_end=page_end; }
length+= (uint) ((*key++ = *from++));
}
+ if (length > keyseg->length)
+ goto crashed;
}
else
length=keyseg->length;
@@ -1033,15 +1033,18 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
if (from_end != page_end)
{
DBUG_PRINT("error",("Error when unpacking key"));
- mi_print_error(keyinfo->share, HA_ERR_CRASHED);
- my_errno=HA_ERR_CRASHED;
- DBUG_RETURN(0); /* Error */
+ goto crashed; /* Error */
}
/* Copy data pointer and, if appropriate, key block pointer. */
memcpy((uchar*) key,(uchar*) from,(size_t) length);
*page_pos= from+length;
}
DBUG_RETURN((uint) (key-start_key)+keyseg->length);
+
+ crashed:
+ mi_print_error(keyinfo->share, HA_ERR_CRASHED);
+ my_errno= HA_ERR_CRASHED;
+ DBUG_RETURN(0);
}
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index c8546ee56f5..7be84599d86 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -284,25 +284,25 @@ static struct my_option my_long_options[] =
{ "read_buffer_size", OPT_READ_BUFFER_SIZE, "",
&check_param.read_buffer_length,
&check_param.read_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
- (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
- INT_MAX32, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ READ_BUFFER_INIT, MALLOC_OVERHEAD,
+ INT_MAX32, MALLOC_OVERHEAD, 1L, 0},
{ "write_buffer_size", OPT_WRITE_BUFFER_SIZE, "",
&check_param.write_buffer_length,
&check_param.write_buffer_length, 0, GET_ULONG, REQUIRED_ARG,
- (long) READ_BUFFER_INIT, (long) MALLOC_OVERHEAD,
- INT_MAX32, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ READ_BUFFER_INIT, MALLOC_OVERHEAD,
+ INT_MAX32, MALLOC_OVERHEAD, 1L, 0},
{ "sort_buffer_size", OPT_SORT_BUFFER_SIZE,
"Deprecated. myisam_sort_buffer_size alias is being used",
&check_param.sort_buffer_length,
&check_param.sort_buffer_length, 0, GET_ULL, REQUIRED_ARG,
- (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD),
- SIZE_T_MAX, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ SORT_BUFFER_INIT, MIN_SORT_BUFFER + MALLOC_OVERHEAD,
+ SIZE_T_MAX, MALLOC_OVERHEAD, 1L, 0},
{ "myisam_sort_buffer_size", OPT_SORT_BUFFER_SIZE,
"Alias of sort_buffer_size parameter",
&check_param.sort_buffer_length,
&check_param.sort_buffer_length, 0, GET_ULL, REQUIRED_ARG,
- (long) SORT_BUFFER_INIT, (long) (MIN_SORT_BUFFER + MALLOC_OVERHEAD),
- SIZE_T_MAX, (long) MALLOC_OVERHEAD, (long) 1L, 0},
+ SORT_BUFFER_INIT, MIN_SORT_BUFFER + MALLOC_OVERHEAD,
+ SIZE_T_MAX, MALLOC_OVERHEAD, 1L, 0},
{ "sort_key_blocks", OPT_SORT_KEY_BLOCKS, "",
&check_param.sort_key_blocks,
&check_param.sort_key_blocks, 0, GET_ULONG, REQUIRED_ARG,
diff --git a/storage/oqgraph/CMakeLists.txt b/storage/oqgraph/CMakeLists.txt
index 83acb99b2a2..593fced6235 100644
--- a/storage/oqgraph/CMakeLists.txt
+++ b/storage/oqgraph/CMakeLists.txt
@@ -3,6 +3,7 @@ IF(NOT Boost_FOUND)
RETURN()
ENDIF()
INCLUDE_DIRECTORIES(BEFORE ${Boost_INCLUDE_DIRS})
+SET(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${Boost_INCLUDE_DIRS})
IF(MSVC)
# lp:756966 OQGRAPH on Win64 does not compile
diff --git a/storage/perfschema/pfs_events_waits.cc b/storage/perfschema/pfs_events_waits.cc
index b6cadf9e61c..a941f815dca 100644
--- a/storage/perfschema/pfs_events_waits.cc
+++ b/storage/perfschema/pfs_events_waits.cc
@@ -93,6 +93,9 @@ static inline void copy_events_waits(PFS_events_waits *dest,
*/
void insert_events_waits_history(PFS_thread *thread, PFS_events_waits *wait)
{
+ if (unlikely(events_waits_history_per_thread == 0))
+ return;
+
uint index= thread->m_waits_history_index;
/*
@@ -120,6 +123,9 @@ void insert_events_waits_history(PFS_thread *thread, PFS_events_waits *wait)
*/
void insert_events_waits_history_long(PFS_events_waits *wait)
{
+ if (unlikely(events_waits_history_long_size == 0))
+ return;
+
uint index= PFS_atomic::add_u32(&events_waits_history_long_index, 1);
index= index % events_waits_history_long_size;
diff --git a/storage/xtradb/btr/btr0btr.c b/storage/xtradb/btr/btr0btr.c
index ed97fc5bd58..a3e57d632a0 100644
--- a/storage/xtradb/btr/btr0btr.c
+++ b/storage/xtradb/btr/btr0btr.c
@@ -1641,7 +1641,7 @@ btr_page_reorganize_low(
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
btr_assert_not_corrupted(block, index);
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
data_size1 = page_get_data_size(page);
max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1);
@@ -1760,7 +1760,7 @@ btr_page_reorganize_low(
func_exit:
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
#ifndef UNIV_HOTBACKUP
buf_block_free(temp_block);
@@ -1835,7 +1835,7 @@ btr_page_empty(
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
ut_ad(page_zip == buf_block_get_page_zip(block));
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
btr_search_drop_page_hash_index(block);
@@ -1892,10 +1892,10 @@ btr_root_raise_and_insert(
root_block = btr_cur_get_block(cursor);
root_page_zip = buf_block_get_page_zip(root_block);
ut_ad(page_get_n_recs(root) > 0);
+ index = btr_cur_get_index(cursor);
#ifdef UNIV_ZIP_DEBUG
- ut_a(!root_page_zip || page_zip_validate(root_page_zip, root));
+ ut_a(!root_page_zip || page_zip_validate(root_page_zip, root, index));
#endif /* UNIV_ZIP_DEBUG */
- index = btr_cur_get_index(cursor);
#ifdef UNIV_BTR_DEBUG
if (!dict_index_is_ibuf(index)) {
ulint space = dict_index_get_space(index);
@@ -2825,8 +2825,8 @@ insert_empty:
#ifdef UNIV_ZIP_DEBUG
if (UNIV_LIKELY_NULL(page_zip)) {
- ut_a(page_zip_validate(page_zip, page));
- ut_a(page_zip_validate(new_page_zip, new_page));
+ ut_a(page_zip_validate(page_zip, page, cursor->index));
+ ut_a(page_zip_validate(new_page_zip, new_page, cursor->index));
}
#endif /* UNIV_ZIP_DEBUG */
@@ -2860,7 +2860,8 @@ insert_empty:
= buf_block_get_page_zip(insert_block);
ut_a(!insert_page_zip
- || page_zip_validate(insert_page_zip, insert_page));
+ || page_zip_validate(insert_page_zip, insert_page,
+ cursor->index));
}
#endif /* UNIV_ZIP_DEBUG */
@@ -3140,6 +3141,8 @@ btr_lift_page_up(
buf_block_t* blocks[BTR_MAX_LEVELS];
ulint n_blocks; /*!< last used index in blocks[] */
ulint i;
+ ibool lift_father_up = FALSE;
+ buf_block_t* block_orig = block;
ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL);
ut_ad(btr_page_get_next(page, mtr) == FIL_NULL);
@@ -3150,11 +3153,13 @@ btr_lift_page_up(
{
btr_cur_t cursor;
- mem_heap_t* heap = mem_heap_create(100);
- ulint* offsets;
+ ulint* offsets = NULL;
+ mem_heap_t* heap = mem_heap_create(
+ sizeof(*offsets)
+ * (REC_OFFS_HEADER_SIZE + 1 + 1 + index->n_fields));
buf_block_t* b;
- offsets = btr_page_get_father_block(NULL, heap, index,
+ offsets = btr_page_get_father_block(offsets, heap, index,
block, mtr, &cursor);
father_block = btr_cur_get_block(&cursor);
father_page_zip = buf_block_get_page_zip(father_block);
@@ -3178,6 +3183,29 @@ btr_lift_page_up(
blocks[n_blocks++] = b = btr_cur_get_block(&cursor);
}
+ if (n_blocks && page_level == 0) {
+ /* The father page also should be the only on its level (not
+ root). We should lift up the father page at first.
+ Because the leaf page should be lifted up only for root page.
+ The freeing page is based on page_level (==0 or !=0)
+ to choose segment. If the page_level is changed ==0 from !=0,
+ later freeing of the page doesn't find the page allocation
+ to be freed.*/
+
+ lift_father_up = TRUE;
+ block = father_block;
+ page = buf_block_get_frame(block);
+ page_level = btr_page_get_level(page, mtr);
+
+ ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL);
+ ut_ad(btr_page_get_next(page, mtr) == FIL_NULL);
+ ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
+
+ father_block = blocks[0];
+ father_page_zip = buf_block_get_page_zip(father_block);
+ father_page = buf_block_get_frame(father_block);
+ }
+
mem_heap_free(heap);
}
@@ -3185,6 +3213,7 @@ btr_lift_page_up(
/* Make the father empty */
btr_page_empty(father_block, father_page_zip, index, page_level, mtr);
+ page_level++;
/* Copy the records to the father page one by one. */
if (0
@@ -3217,7 +3246,7 @@ btr_lift_page_up(
lock_update_copy_and_discard(father_block, block);
/* Go upward to root page, decrementing levels by one. */
- for (i = 0; i < n_blocks; i++, page_level++) {
+ for (i = lift_father_up ? 1 : 0; i < n_blocks; i++, page_level++) {
page_t* page = buf_block_get_frame(blocks[i]);
page_zip_des_t* page_zip= buf_block_get_page_zip(blocks[i]);
@@ -3225,7 +3254,7 @@ btr_lift_page_up(
btr_page_set_level(page, page_zip, page_level, mtr);
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
}
@@ -3239,7 +3268,7 @@ btr_lift_page_up(
ut_ad(page_validate(father_page, index));
ut_ad(btr_check_node_ptr(index, father_block, mtr));
- return(father_block);
+ return(lift_father_up ? block_orig : father_block);
}
/*************************************************************//**
@@ -3310,6 +3339,7 @@ btr_compress(
if (adjust) {
nth_rec = page_rec_get_n_recs_before(btr_cur_get_rec(cursor));
+ ut_ad(nth_rec > 0);
}
/* Decide the page to which we try to merge and which will inherit
@@ -3400,8 +3430,8 @@ err_exit:
const page_zip_des_t* page_zip
= buf_block_get_page_zip(block);
ut_a(page_zip);
- ut_a(page_zip_validate(merge_page_zip, merge_page));
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(merge_page_zip, merge_page, index));
+ ut_a(page_zip_validate(page_zip, page, index));
}
#endif /* UNIV_ZIP_DEBUG */
@@ -3534,7 +3564,8 @@ err_exit:
ut_ad(page_validate(merge_page, index));
#ifdef UNIV_ZIP_DEBUG
- ut_a(!merge_page_zip || page_zip_validate(merge_page_zip, merge_page));
+ ut_a(!merge_page_zip || page_zip_validate(merge_page_zip, merge_page,
+ index));
#endif /* UNIV_ZIP_DEBUG */
/* Free the file page */
@@ -3545,6 +3576,7 @@ func_exit:
mem_heap_free(heap);
if (adjust) {
+ ut_ad(nth_rec > 0);
btr_cur_position(
index,
page_rec_get_nth(merge_block->frame, nth_rec),
@@ -3716,7 +3748,7 @@ btr_discard_page(
page_zip_des_t* merge_page_zip
= buf_block_get_page_zip(merge_block);
ut_a(!merge_page_zip
- || page_zip_validate(merge_page_zip, merge_page));
+ || page_zip_validate(merge_page_zip, merge_page, index));
}
#endif /* UNIV_ZIP_DEBUG */
@@ -4058,8 +4090,22 @@ btr_index_page_validate(
{
page_cur_t cur;
ibool ret = TRUE;
+#ifndef DBUG_OFF
+ ulint nth = 1;
+#endif /* !DBUG_OFF */
page_cur_set_before_first(block, &cur);
+
+ /* Directory slot 0 should only contain the infimum record. */
+ DBUG_EXECUTE_IF("check_table_rec_next",
+ ut_a(page_rec_get_nth_const(
+ page_cur_get_page(&cur), 0)
+ == cur.rec);
+ ut_a(page_dir_slot_get_n_owned(
+ page_dir_get_nth_slot(
+ page_cur_get_page(&cur), 0))
+ == 1););
+
page_cur_move_to_next(&cur);
for (;;) {
@@ -4073,6 +4119,16 @@ btr_index_page_validate(
return(FALSE);
}
+ /* Verify that page_rec_get_nth_const() is correctly
+ retrieving each record. */
+ DBUG_EXECUTE_IF("check_table_rec_next",
+ ut_a(cur.rec == page_rec_get_nth_const(
+ page_cur_get_page(&cur),
+ page_rec_get_n_recs_before(
+ cur.rec)));
+ ut_a(nth++ == page_rec_get_n_recs_before(
+ cur.rec)););
+
page_cur_move_to_next(&cur);
}
@@ -4170,7 +4226,7 @@ btr_validate_level(
ut_a(space == page_get_space_id(page));
#ifdef UNIV_ZIP_DEBUG
page_zip = buf_block_get_page_zip(block);
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
ut_a(!page_is_leaf(page));
@@ -4198,7 +4254,7 @@ loop:
#ifdef UNIV_ZIP_DEBUG
page_zip = buf_block_get_page_zip(block);
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
/* Check ordering etc. of records */
diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c
index 687853a422e..d089fb5ad22 100644
--- a/storage/xtradb/btr/btr0cur.c
+++ b/storage/xtradb/btr/btr0cur.c
@@ -97,6 +97,11 @@ srv_refresh_innodb_monitor_stats(). Referenced by
srv_printf_innodb_monitor(). */
UNIV_INTERN ulint btr_cur_n_sea_old = 0;
+#ifdef UNIV_DEBUG
+/* Flag to limit optimistic insert records */
+UNIV_INTERN uint btr_cur_limit_optimistic_insert_debug = 0;
+#endif /* UNIV_DEBUG */
+
/** In the optimistic insert, if the insert does not fit, but this much space
can be released by page reorganize, then it is reorganized */
#define BTR_CUR_PAGE_REORGANIZE_LIMIT (UNIV_PAGE_SIZE / 32)
@@ -748,7 +753,7 @@ retry_page_get:
#ifdef UNIV_ZIP_DEBUG
const page_zip_des_t* page_zip
= buf_block_get_page_zip(block);
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
buf_block_dbg_add_level(
@@ -1378,6 +1383,9 @@ btr_cur_optimistic_insert(
}
}
+ LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page),
+ goto fail);
+
/* If there have been many consecutive inserts, and we are on the leaf
level, check if we have to split the page to reserve enough free space
for future updates of records. */
@@ -2189,7 +2197,7 @@ any_extern:
page_zip = buf_block_get_page_zip(block);
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
if (page_zip
@@ -2406,7 +2414,7 @@ btr_cur_pessimistic_update(
MTR_MEMO_X_LOCK));
ut_ad((thr && thr_get_trx(thr)->fake_changes) || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
/* The insert buffer tree should never be updated in place. */
ut_ad(!dict_index_is_ibuf(index));
@@ -2561,7 +2569,7 @@ make_external:
btr_search_update_hash_on_delete(cursor);
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
page_cursor = btr_cur_get_page_cur(cursor);
@@ -2668,7 +2676,7 @@ make_external:
buf_block_t* rec_block = btr_cur_get_block(cursor);
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
page = buf_block_get_frame(rec_block);
#endif /* UNIV_ZIP_DEBUG */
page_zip = buf_block_get_page_zip(rec_block);
@@ -2694,7 +2702,7 @@ make_external:
return_after_reservations:
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
if (n_extents > 0) {
@@ -3066,7 +3074,7 @@ btr_cur_set_deleted_flag_for_ibuf(
when the tablespace is
uncompressed */
ibool val, /*!< in: value to set */
- mtr_t* mtr) /*!< in: mtr */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
{
/* We do not need to reserve btr_search_latch, as the page
has just been read to the buffer pool and there cannot be
@@ -3171,12 +3179,14 @@ btr_cur_optimistic_delete(
page, 1);
}
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip
+ || page_zip_validate(page_zip, page, cursor->index));
#endif /* UNIV_ZIP_DEBUG */
page_cur_delete_rec(btr_cur_get_page_cur(cursor),
cursor->index, offsets, mtr);
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip
+ || page_zip_validate(page_zip, page, cursor->index));
#endif /* UNIV_ZIP_DEBUG */
if (dict_index_is_clust(cursor->index)
@@ -3273,7 +3283,7 @@ btr_cur_pessimistic_delete(
rec = btr_cur_get_rec(cursor);
page_zip = buf_block_get_page_zip(block);
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED, &heap);
@@ -3283,7 +3293,7 @@ btr_cur_pessimistic_delete(
rec, offsets, page_zip,
rb_ctx, mtr);
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
}
@@ -3344,7 +3354,7 @@ btr_cur_pessimistic_delete(
page_cur_delete_rec(btr_cur_get_page_cur(cursor), index, offsets, mtr);
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
ut_ad(btr_check_node_ptr(index, block, mtr));
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c
index bbc1042ca78..5bcfb0f51b9 100644
--- a/storage/xtradb/buf/buf0buf.c
+++ b/storage/xtradb/buf/buf0buf.c
@@ -66,9 +66,7 @@ _increment_page_get_statistics(buf_block_t* block, trx_t* trx)
byte block_hash_offset;
ut_ad(block);
-
- if (!innobase_get_slow_log() || !trx || !trx->take_stats)
- return;
+ ut_ad(trx && trx->take_stats);
if (!trx->distinct_page_access_hash) {
trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
@@ -279,7 +277,7 @@ the read requests for the whole area.
#ifndef UNIV_HOTBACKUP
/** Value in microseconds */
-static const int WAIT_FOR_READ = 5000;
+static const int WAIT_FOR_READ = 100;
/** Number of attemtps made to read in a page in the buffer pool */
static const ulint BUF_PAGE_READ_MAX_RETRIES = 100;
@@ -412,6 +410,33 @@ buf_get_total_list_len(
}
/********************************************************************//**
+Get total list size in bytes from all buffer pools. */
+UNIV_INTERN
+void
+buf_get_total_list_size_in_bytes(
+/*=============================*/
+ buf_pools_list_size_t* buf_pools_list_size) /*!< out: list sizes
+ in all buffer pools */
+{
+ ulint i;
+ ut_ad(buf_pools_list_size);
+ memset(buf_pools_list_size, 0, sizeof(*buf_pools_list_size));
+
+ for (i = 0; i < srv_buf_pool_instances; i++) {
+ buf_pool_t* buf_pool;
+
+ buf_pool = buf_pool_from_array(i);
+ /* We don't need mutex protection since this is
+ for statistics purpose */
+ buf_pools_list_size->LRU_bytes += buf_pool->stat.LRU_bytes;
+ buf_pools_list_size->unzip_LRU_bytes +=
+ UT_LIST_GET_LEN(buf_pool->unzip_LRU) * UNIV_PAGE_SIZE;
+ buf_pools_list_size->flush_list_bytes +=
+ buf_pool->stat.flush_list_bytes;
+ }
+}
+
+/********************************************************************//**
Get total buffer pool statistics. */
UNIV_INTERN
void
@@ -1807,40 +1832,24 @@ buf_page_make_young(
}
/********************************************************************//**
-Sets the time of the first access of a page and moves a page to the
-start of the buffer pool LRU list if it is too old. This high-level
-function can be used to prevent an important page from slipping
-out of the buffer pool. */
+Moves a page to the start of the buffer pool LRU list if it is too old.
+This high-level function can be used to prevent an important page from
+slipping out of the buffer pool. */
static
void
-buf_page_set_accessed_make_young(
-/*=============================*/
- buf_page_t* bpage, /*!< in/out: buffer block of a
+buf_page_make_young_if_needed(
+/*==========================*/
+ buf_page_t* bpage) /*!< in/out: buffer block of a
file page */
- unsigned access_time) /*!< in: bpage->access_time
- read under mutex protection,
- or 0 if unknown */
{
+#ifdef UNIV_DEBUG
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
-
ut_ad(!buf_pool_mutex_own(buf_pool));
+#endif /* UNIV_DEBUG */
ut_a(buf_page_in_file(bpage));
if (buf_page_peek_if_too_old(bpage)) {
- //buf_pool_mutex_enter(buf_pool);
- mutex_enter(&buf_pool->LRU_list_mutex);
- buf_LRU_make_block_young(bpage);
- //buf_pool_mutex_exit(buf_pool);
- mutex_exit(&buf_pool->LRU_list_mutex);
- } else if (!access_time) {
- ulint time_ms = ut_time_ms();
- mutex_t* block_mutex = buf_page_get_mutex_enter(bpage);
- //buf_pool_mutex_enter(buf_pool);
- if (block_mutex) {
- buf_page_set_accessed(bpage, time_ms);
- mutex_exit(block_mutex);
- }
- //buf_pool_mutex_exit(buf_pool);
+ buf_page_make_young(bpage);
}
}
@@ -1959,7 +1968,6 @@ buf_page_get_zip(
buf_page_t* bpage;
mutex_t* block_mutex;
ibool must_read;
- unsigned access_time;
trx_t* trx = NULL;
ulint sec;
ulint ms;
@@ -1967,7 +1975,7 @@ buf_page_get_zip(
ib_uint64_t finish_time;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
- if (innobase_get_slow_log()) {
+ if (UNIV_UNLIKELY(innobase_get_slow_log())) {
trx = innobase_get_trx();
}
buf_pool->stat.n_page_gets++;
@@ -2089,13 +2097,14 @@ err_exit:
got_block:
must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ;
- access_time = buf_page_is_accessed(bpage);
//buf_pool_mutex_exit(buf_pool);
+ buf_page_set_accessed(bpage);
+
mutex_exit(block_mutex);
- buf_page_set_accessed_make_young(bpage, access_time);
+ buf_page_make_young_if_needed(bpage);
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(!bpage->file_page_was_freed);
@@ -2111,7 +2120,7 @@ got_block:
/* Let us wait until the read operation
completes */
- if (innobase_get_slow_log() && trx && trx->take_stats)
+ if (UNIV_UNLIKELY(trx && trx->take_stats))
{
ut_usectime(&sec, &ms);
start_time = (ib_uint64_t)sec * 1000000 + ms;
@@ -2132,7 +2141,7 @@ got_block:
break;
}
}
- if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ if (UNIV_UNLIKELY(start_time != 0))
{
ut_usectime(&sec, &ms);
finish_time = (ib_uint64_t)sec * 1000000 + ms;
@@ -2487,7 +2496,7 @@ buf_page_get_gen(
|| ibuf_page_low(space, zip_size, offset,
FALSE, file, line, NULL));
#endif
- if (innobase_get_slow_log()) {
+ if (UNIV_UNLIKELY(innobase_get_slow_log())) {
trx = innobase_get_trx();
}
buf_pool->stat.n_page_gets++;
@@ -2774,6 +2783,8 @@ wait_until_unfixed:
UNIV_MEM_INVALID(bpage, sizeof *bpage);
+ access_time = buf_page_is_accessed(&block->page);
+
mutex_exit(block_mutex);
mutex_exit(&buf_pool->zip_mutex);
@@ -2781,18 +2792,22 @@ wait_until_unfixed:
buf_pool->n_pend_unzip++;
buf_pool_mutex_exit(buf_pool);
- //buf_pool_mutex_exit(buf_pool);
-
buf_page_free_descriptor(bpage);
- /* Decompress the page and apply buffered operations
- while not holding buf_pool->mutex or block->mutex. */
+ /* Decompress the page while not holding
+ buf_pool->mutex or block->mutex. */
success = buf_zip_decompress(block, srv_use_checksums);
ut_a(success);
if (UNIV_LIKELY(!recv_no_ibuf_operations)) {
- ibuf_merge_or_delete_for_page(block, space, offset,
- zip_size, TRUE);
+ if (access_time) {
+#ifdef UNIV_IBUF_COUNT_DEBUG
+ ut_a(ibuf_count_get(space, offset) == 0);
+#endif /* UNIV_IBUF_COUNT_DEBUG */
+ } else {
+ ibuf_merge_or_delete_for_page(
+ block, space, offset, zip_size, TRUE);
+ }
}
/* Unfix and unlatch the block. */
@@ -2888,17 +2903,16 @@ wait_until_unfixed:
ut_a(mode == BUF_GET_POSSIBLY_FREED
|| !block->page.file_page_was_freed);
#endif
- //mutex_exit(&block->mutex);
/* Check if this is the first access to the page */
-
access_time = buf_page_is_accessed(&block->page);
- //buf_pool_mutex_exit(buf_pool);
- mutex_exit(block_mutex);
+ buf_page_set_accessed(&block->page);
+
+ mutex_exit(&block->mutex);
- if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) {
- buf_page_set_accessed_make_young(&block->page, access_time);
+ if (mode != BUF_PEEK_IF_IN_POOL) {
+ buf_page_make_young_if_needed(&block->page);
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
@@ -2913,7 +2927,7 @@ wait_until_unfixed:
/* Let us wait until the read operation
completes */
- if (innobase_get_slow_log() && trx && trx->take_stats)
+ if (UNIV_UNLIKELY(trx && trx->take_stats))
{
ut_usectime(&sec, &ms);
start_time = (ib_uint64_t)sec * 1000000 + ms;
@@ -2928,13 +2942,14 @@ wait_until_unfixed:
mutex_exit(&block->mutex);
if (io_fix == BUF_IO_READ) {
-
- os_thread_sleep(WAIT_FOR_READ);
+ /* wait by temporaly s-latch */
+ rw_lock_s_lock(&(block->lock));
+ rw_lock_s_unlock(&(block->lock));
} else {
break;
}
}
- if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ if (UNIV_UNLIKELY(start_time != 0))
{
ut_usectime(&sec, &ms);
finish_time = (ib_uint64_t)sec * 1000000 + ms;
@@ -2961,7 +2976,7 @@ wait_until_unfixed:
mtr_memo_push(mtr, block, fix_type);
- if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL) && !access_time) {
+ if (mode != BUF_PEEK_IF_IN_POOL && !access_time) {
/* In the case of a first access, try to apply linear
read-ahead */
@@ -2973,7 +2988,7 @@ wait_until_unfixed:
ut_a(ibuf_count_get(buf_block_get_space(block),
buf_block_get_page_no(block)) == 0);
#endif
- if (innobase_get_slow_log()) {
+ if (UNIV_UNLIKELY(trx && trx->take_stats)) {
_increment_page_get_statistics(block, trx);
}
@@ -3018,15 +3033,13 @@ buf_page_optimistic_get(
buf_block_buf_fix_inc(block, file, line);
- mutex_exit(&block->mutex);
+ access_time = buf_page_is_accessed(&block->page);
- /* Check if this is the first access to the page.
- We do a dirty read on purpose, to avoid mutex contention.
- This field is only used for heuristic purposes; it does not
- affect correctness. */
+ buf_page_set_accessed(&block->page);
- access_time = buf_page_is_accessed(&block->page);
- buf_page_set_accessed_make_young(&block->page, access_time);
+ mutex_exit(&block->mutex);
+
+ buf_page_make_young_if_needed(&block->page);
ut_ad(!ibuf_inside(mtr)
|| ibuf_page(buf_block_get_space(block),
@@ -3078,11 +3091,11 @@ buf_page_optimistic_get(
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
ut_a(block->page.file_page_was_freed == FALSE);
#endif
- if (innobase_get_slow_log()) {
+ if (UNIV_UNLIKELY(innobase_get_slow_log())) {
trx = innobase_get_trx();
}
- if (UNIV_UNLIKELY(!access_time)) {
+ if (!access_time) {
/* In the case of a first access, try to apply linear
read-ahead */
@@ -3099,7 +3112,7 @@ buf_page_optimistic_get(
buf_pool = buf_pool_from_block(block);
buf_pool->stat.n_page_gets++;
- if (innobase_get_slow_log()) {
+ if (UNIV_UNLIKELY(trx && trx->take_stats)) {
_increment_page_get_statistics(block, trx);
}
return(TRUE);
@@ -3149,28 +3162,14 @@ buf_page_get_known_nowait(
buf_block_buf_fix_inc(block, file, line);
+ buf_page_set_accessed(&block->page);
+
mutex_exit(&block->mutex);
buf_pool = buf_pool_from_block(block);
- if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) {
- //buf_pool_mutex_enter(buf_pool);
- mutex_enter(&buf_pool->LRU_list_mutex);
- buf_LRU_make_block_young(&block->page);
- //buf_pool_mutex_exit(buf_pool);
- mutex_exit(&buf_pool->LRU_list_mutex);
- } else if (!buf_page_is_accessed(&block->page)) {
- /* Above, we do a dirty read on purpose, to avoid
- mutex contention. The field buf_page_t::access_time
- is only used for heuristic purposes. Writes to the
- field must be protected by mutex, however. */
- ulint time_ms = ut_time_ms();
-
- //buf_pool_mutex_enter(buf_pool);
- mutex_enter(&block->mutex);
- buf_page_set_accessed(&block->page, time_ms);
- //buf_pool_mutex_exit(buf_pool);
- mutex_exit(&block->mutex);
+ if (mode == BUF_MAKE_YOUNG) {
+ buf_page_make_young_if_needed(&block->page);
}
ut_ad(!ibuf_inside(mtr) || mode == BUF_KEEP_OLD);
@@ -3211,9 +3210,13 @@ buf_page_get_known_nowait(
#endif
buf_pool->stat.n_page_gets++;
- if (innobase_get_slow_log()) {
+ if (UNIV_UNLIKELY(innobase_get_slow_log())) {
+
trx = innobase_get_trx();
- _increment_page_get_statistics(block, trx);
+ if (trx != NULL && trx->take_stats) {
+
+ _increment_page_get_statistics(block, trx);
+ }
}
return(TRUE);
@@ -3342,6 +3345,7 @@ buf_page_init(
ulint offset, /*!< in: offset of the page within space
in units of a page */
ulint fold, /*!< in: buf_page_address_fold(space,offset) */
+ ulint zip_size,/*!< in: compressed page size, or 0 */
buf_block_t* block) /*!< in/out: block to init */
{
buf_page_t* hash_page;
@@ -3411,6 +3415,9 @@ buf_page_init(
ut_d(block->page.in_page_hash = TRUE);
HASH_INSERT(buf_page_t, hash, buf_pool->page_hash,
fold, &block->page);
+ if (zip_size) {
+ page_zip_set_size(&block->page.zip, zip_size);
+ }
}
/********************************************************************//**
@@ -3537,7 +3544,7 @@ err_exit:
ut_ad(buf_pool_from_bpage(bpage) == buf_pool);
- buf_page_init(buf_pool, space, offset, fold, block);
+ buf_page_init(buf_pool, space, offset, fold, zip_size, block);
rw_lock_x_unlock(&buf_pool->page_hash_latch);
@@ -3557,8 +3564,6 @@ err_exit:
buf_page_set_io_fix(bpage, BUF_IO_READ);
if (UNIV_UNLIKELY(zip_size)) {
- page_zip_set_size(&block->page.zip, zip_size);
-
/* buf_pool->mutex may be released and
reacquired by buf_buddy_alloc(). Thus, we
must release block->mutex in order not to
@@ -3658,7 +3663,8 @@ err_exit:
rw_lock_x_unlock(&buf_pool->page_hash_latch);
- /* The block must be put to the LRU list, to the old blocks */
+ /* The block must be put to the LRU list, to the old blocks
+ The zip_size is already set into the page zip */
buf_LRU_add_block(bpage, TRUE/* to old blocks */);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(bpage);
@@ -3706,7 +3712,6 @@ buf_page_create(
buf_block_t* block;
ulint fold;
buf_block_t* free_block = NULL;
- ulint time_ms = ut_time_ms();
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ut_ad(mtr);
@@ -3774,7 +3779,7 @@ retry:
mutex_enter(&block->mutex);
- buf_page_init(buf_pool, space, offset, fold, block);
+ buf_page_init(buf_pool, space, offset, fold, zip_size,block);
rw_lock_x_unlock(&buf_pool->page_hash_latch);
/* The block must be put to the LRU list */
@@ -3793,8 +3798,6 @@ retry:
buf_page_set_io_fix(&block->page, BUF_IO_READ);
rw_lock_x_lock(&block->lock);
-
- page_zip_set_size(&block->page.zip, zip_size);
mutex_exit(&block->mutex);
/* buf_pool->mutex may be released and reacquired by
buf_buddy_alloc(). Thus, we must release block->mutex
@@ -3818,13 +3821,12 @@ retry:
rw_lock_x_unlock(&block->lock);
}
- buf_page_set_accessed(&block->page, time_ms);
-
- //buf_pool_mutex_exit(buf_pool);
mutex_exit(&buf_pool->LRU_list_mutex);
mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);
+ buf_page_set_accessed(&block->page);
+
mutex_exit(&block->mutex);
/* Delete possible entries for the page from the insert buffer:
@@ -3937,7 +3939,7 @@ buf_page_io_complete(
ensures that this is the only thread that handles the i/o for this
block. */
- io_type = buf_page_get_io_fix(bpage);
+ io_type = buf_page_get_io_fix_unlocked(bpage);
ut_ad(io_type == BUF_IO_READ || io_type == BUF_IO_WRITE);
if (io_type == BUF_IO_READ) {
diff --git a/storage/xtradb/buf/buf0flu.c b/storage/xtradb/buf/buf0flu.c
index 39351cd3678..663e2d8f537 100644
--- a/storage/xtradb/buf/buf0flu.c
+++ b/storage/xtradb/buf/buf0flu.c
@@ -79,6 +79,23 @@ static buf_flush_stat_t buf_flush_stat_sum;
/* @} */
+/******************************************************************//**
+Increases flush_list size in bytes with zip_size for compressed page,
+UNIV_PAGE_SIZE for uncompressed page in inline function */
+static inline
+void
+incr_flush_list_size_in_bytes(
+/*==========================*/
+ buf_block_t* block, /*!< in: control block */
+ buf_pool_t* buf_pool) /*!< in: buffer pool instance */
+{
+ ulint zip_size;
+ ut_ad(buf_flush_list_mutex_own(buf_pool));
+ zip_size = page_zip_get_size(&block->page.zip);
+ buf_pool->stat.flush_list_bytes += zip_size ? zip_size : UNIV_PAGE_SIZE;
+ ut_ad(buf_pool->stat.flush_list_bytes <= buf_pool->curr_pool_size);
+}
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/******************************************************************//**
Validates the flush list.
@@ -308,6 +325,7 @@ buf_flush_insert_into_flush_list(
ut_d(block->page.in_flush_list = TRUE);
block->page.oldest_modification = lsn;
UT_LIST_ADD_FIRST(flush_list, buf_pool->flush_list, &block->page);
+ incr_flush_list_size_in_bytes(block, buf_pool);
#ifdef UNIV_DEBUG_VALGRIND
{
@@ -412,6 +430,8 @@ buf_flush_insert_sorted_into_flush_list(
prev_b, &block->page);
}
+ incr_flush_list_size_in_bytes(block, buf_pool);
+
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
ut_a(buf_flush_validate_low(buf_pool));
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
@@ -514,6 +534,7 @@ buf_flush_remove(
buf_page_t* bpage) /*!< in: pointer to the block in question */
{
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+ ulint zip_size;
//ut_ad(buf_pool_mutex_own(buf_pool));
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
@@ -552,6 +573,9 @@ buf_flush_remove(
because we assert on in_flush_list in comparison function. */
ut_d(bpage->in_flush_list = FALSE);
+ zip_size = page_zip_get_size(&bpage->zip);
+ buf_pool->stat.flush_list_bytes -= zip_size ? zip_size : UNIV_PAGE_SIZE;
+
bpage->oldest_modification = 0;
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
@@ -915,7 +939,7 @@ flush:
"InnoDB: Page buf fix count %lu,"
" io fix %lu, state %lu\n",
(ulong)block->page.buf_fix_count,
- (ulong)buf_block_get_io_fix(block),
+ (ulong)buf_block_get_io_fix_unlocked(block),
(ulong)buf_block_get_state(block));
}
@@ -1115,7 +1139,7 @@ buf_flush_write_block_low(
ut_ad(!mutex_own(&buf_pool->LRU_list_mutex));
ut_ad(!buf_flush_list_mutex_own(buf_pool));
ut_ad(!mutex_own(buf_page_get_mutex(bpage)));
- ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_WRITE);
+ ut_ad(buf_page_get_io_fix_unlocked(bpage) == BUF_IO_WRITE);
ut_ad(bpage->oldest_modification != 0);
#ifdef UNIV_IBUF_COUNT_DEBUG
@@ -1181,10 +1205,10 @@ buf_flush_write_block_low(
# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
/********************************************************************//**
Writes a flushable page asynchronously from the buffer pool to a file.
-NOTE: buf_pool->mutex and block->mutex must be held upon entering this
-function, and they will be released by this function after flushing.
+NOTE: block->mutex must be held upon entering this function, and it will be
+released by this function after flushing.
This is loosely based on buf_flush_batch() and buf_flush_page().
-@return TRUE if the page was flushed and the mutexes released */
+@return TRUE if the page was flushed and the mutex released */
UNIV_INTERN
ibool
buf_flush_page_try(
@@ -1553,16 +1577,14 @@ scan:
Check if the block is modified and ready for flushing. If the the block
is ready to flush then flush the page and try o flush its neighbors.
-@return TRUE if buf_pool mutex was not released during this function.
+@return TRUE if LRU list mutex was not released during this function.
This does not guarantee that some pages were written as well.
Number of pages written are incremented to the count. */
static
ibool
buf_flush_page_and_try_neighbors(
/*=============================*/
- buf_page_t* bpage, /*!< in: buffer control block,
- must be
- buf_page_in_file(bpage) */
+ buf_page_t* bpage, /*!< in: buffer control block */
enum buf_flush flush_type, /*!< in: BUF_FLUSH_LRU
or BUF_FLUSH_LIST */
ulint n_to_flush, /*!< in: number of pages to
diff --git a/storage/xtradb/buf/buf0lru.c b/storage/xtradb/buf/buf0lru.c
index 14b5c65132c..cd99d3e4e13 100644
--- a/storage/xtradb/buf/buf0lru.c
+++ b/storage/xtradb/buf/buf0lru.c
@@ -153,6 +153,23 @@ buf_LRU_block_free_hashed_page(
ibool have_page_hash_mutex);
/******************************************************************//**
+Increases LRU size in bytes with zip_size for compressed page,
+UNIV_PAGE_SIZE for uncompressed page in inline function */
+static inline
+void
+incr_LRU_size_in_bytes(
+/*===================*/
+ buf_page_t* bpage, /*!< in: control block */
+ buf_pool_t* buf_pool) /*!< in: buffer pool instance */
+{
+ ulint zip_size;
+ ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
+ zip_size = page_zip_get_size(&bpage->zip);
+ buf_pool->stat.LRU_bytes += zip_size ? zip_size : UNIV_PAGE_SIZE;
+ ut_ad(buf_pool->stat.LRU_bytes <= buf_pool->curr_pool_size);
+}
+
+/******************************************************************//**
Determines if the unzip_LRU list should be used for evicting a victim
instead of the general LRU list.
@return TRUE if should use unzip_LRU */
@@ -393,18 +410,18 @@ buf_flush_yield(
{
mutex_t* block_mutex;
+ block_mutex = buf_page_get_mutex(bpage);
+
+ ut_ad(mutex_own(block_mutex));
ut_ad(mutex_own(&buf_pool->LRU_list_mutex));
ut_ad(buf_page_in_file(bpage));
- block_mutex = buf_page_get_mutex(bpage);
-
- mutex_enter(block_mutex);
/* "Fix" the block so that the position cannot be
changed after we release the buffer pool and
block mutexes. */
buf_page_set_sticky(bpage);
- /* Now it is safe to release the buf_pool->mutex. */
+ /* Now it is safe to release the LRU list mutex. */
mutex_exit(&buf_pool->LRU_list_mutex);
mutex_exit(block_mutex);
@@ -415,7 +432,7 @@ buf_flush_yield(
mutex_enter(block_mutex);
/* "Unfix" the block now that we have both the
- buffer pool and block mutex again. */
+ LRU list and block mutex again. */
buf_page_unset_sticky(bpage);
mutex_exit(block_mutex);
}
@@ -431,7 +448,9 @@ buf_flush_try_yield(
/*================*/
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
buf_page_t* bpage, /*!< in/out: bpage to remove */
- ulint processed) /*!< in: number of pages processed */
+ ulint processed, /*!< in: number of pages processed */
+ ibool* must_restart) /*!< in/out: if TRUE, we have to
+ restart the flush list scan */
{
/* Every BUF_LRU_DROP_SEARCH_SIZE iterations in the
loop we release buf_pool->mutex to let other threads
@@ -441,10 +460,40 @@ buf_flush_try_yield(
if (bpage != NULL
&& processed >= BUF_LRU_DROP_SEARCH_SIZE
- && buf_page_get_io_fix(bpage) == BUF_IO_NONE) {
+ && buf_page_get_io_fix_unlocked(bpage) == BUF_IO_NONE) {
+
+ mutex_t* block_mutex;
buf_flush_list_mutex_exit(buf_pool);
+ /* We don't have to worry about bpage becoming a dangling
+ pointer by a compressed page flush list relocation because
+ buf_page_get_gen() won't be called for pages from this
+ tablespace. */
+
+ block_mutex = buf_page_get_mutex_enter(bpage);
+ if (UNIV_UNLIKELY(block_mutex == NULL)) {
+
+ buf_flush_list_mutex_enter(buf_pool);
+
+ *must_restart = TRUE;
+ return FALSE;
+ }
+
+ /* Recheck the I/O fix and the flush list presence now that we
+ hold the right mutex */
+ if (UNIV_UNLIKELY(buf_page_get_io_fix(bpage) != BUF_IO_NONE
+ || bpage->oldest_modification == 0)) {
+
+ mutex_exit(block_mutex);
+ buf_flush_list_mutex_enter(buf_pool);
+
+ *must_restart = TRUE;
+ return FALSE;
+ }
+
+ *must_restart = FALSE;
+
/* Release the LRU list and block mutex
to give the other threads a go. */
@@ -473,7 +522,9 @@ ibool
buf_flush_or_remove_page(
/*=====================*/
buf_pool_t* buf_pool, /*!< in/out: buffer pool instance */
- buf_page_t* bpage) /*!< in/out: bpage to remove */
+ buf_page_t* bpage, /*!< in/out: bpage to remove */
+ ibool* must_restart) /*!< in/out: if TRUE, must restart the
+ flush list scan */
{
mutex_t* block_mutex;
ibool processed = FALSE;
@@ -487,7 +538,8 @@ buf_flush_or_remove_page(
buf_pool->mutex and block_mutex. It is safe to check
them while holding buf_pool->mutex only. */
- if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
+ if (UNIV_UNLIKELY(buf_page_get_io_fix_unlocked(bpage)
+ != BUF_IO_NONE)) {
/* We cannot remove this page during this scan
yet; maybe the system is currently reading it
@@ -496,21 +548,38 @@ buf_flush_or_remove_page(
} else {
/* We have to release the flush_list_mutex to obey the
- latching order. We are however guaranteed that the page
- will stay in the flush_list because buf_flush_remove()
- needs buf_pool->mutex as well (for the non-flush case). */
+ latching order. We are not however guaranteed that the page
+ will stay in the flush_list. */
buf_flush_list_mutex_exit(buf_pool);
+ /* We don't have to worry about bpage becoming a dangling
+ pointer by a compressed page flush list relocation because
+ buf_page_get_gen() won't be called for pages from this
+ tablespace. */
+
mutex_enter(block_mutex);
- ut_ad(bpage->oldest_modification != 0);
+ /* Recheck the page I/O fix and the flush list presence now
+ thatwe hold the right mutex. */
+ if (UNIV_UNLIKELY(buf_page_get_io_fix(bpage) != BUF_IO_NONE
+ || bpage->oldest_modification == 0)) {
- if (bpage->buf_fix_count == 0) {
+ /* The page became I/O-fixed or is not on the flush
+ list anymore, this invalidates any flush-list-page
+ pointers we have. */
+ *must_restart = TRUE;
- buf_flush_remove(bpage);
+ } else {
+
+ ut_ad(bpage->oldest_modification != 0);
+
+ if (bpage->buf_fix_count == 0) {
+
+ buf_flush_remove(bpage);
- processed = TRUE;
+ processed = TRUE;
+ }
}
mutex_exit(block_mutex);
@@ -541,11 +610,12 @@ buf_flush_or_remove_pages(
buf_page_t* bpage;
ulint processed = 0;
ibool all_freed = TRUE;
+ ibool must_restart = FALSE;
buf_flush_list_mutex_enter(buf_pool);
for (bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
- bpage != NULL;
+ !must_restart && bpage != NULL;
bpage = prev) {
ut_a(buf_page_in_file(bpage));
@@ -561,22 +631,31 @@ buf_flush_or_remove_pages(
/* Skip this block, as it does not belong to
the target space. */
- } else if (!buf_flush_or_remove_page(buf_pool, bpage)) {
+ } else if (!buf_flush_or_remove_page(buf_pool, bpage,
+ &must_restart)) {
/* Remove was unsuccessful, we have to try again
by scanning the entire list from the end. */
all_freed = FALSE;
}
+ if (UNIV_UNLIKELY(must_restart)) {
+ ut_ad(!all_freed);
+ break;
+ }
++processed;
/* Yield if we have hogged the CPU and mutexes for too long. */
- if (buf_flush_try_yield(buf_pool, prev, processed)) {
+ if (buf_flush_try_yield(buf_pool, prev, processed,
+ &must_restart)) {
+ ut_ad(!must_restart);
/* Reset the batch size counter if we had to yield. */
processed = 0;
+ } else if (UNIV_UNLIKELY(must_restart)) {
+ all_freed = FALSE;
}
}
@@ -641,41 +720,39 @@ scan_again:
/* No op */) {
buf_page_t* prev_bpage;
- mutex_t* block_mutex = NULL;
+ mutex_t* block_mutex;
ut_a(buf_page_in_file(bpage));
ut_ad(bpage->in_LRU_list);
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
- /* bpage->space and bpage->io_fix are protected by
- buf_pool->mutex and the block_mutex. It is safe to check
- them while holding buf_pool->mutex only. */
+ block_mutex = buf_page_get_mutex_enter(bpage);
+
+ if (!block_mutex) {
+ /* It may be impossible case...
+ Something wrong, so will be scan_again */
+
+ all_freed = FALSE;
+ goto next_page;
+ }
if (buf_page_get_space(bpage) != id) {
/* Skip this block, as it does not belong to
the space that is being invalidated. */
+
+ mutex_exit(block_mutex);
goto next_page;
} else if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
/* We cannot remove this page during this scan
yet; maybe the system is currently reading it
in, or flushing the modifications to the file */
+ mutex_exit(block_mutex);
all_freed = FALSE;
goto next_page;
} else {
- block_mutex = buf_page_get_mutex_enter(bpage);
-
- if (!block_mutex) {
- /* It may be impossible case...
- Something wrong, so will be scan_again */
-
- all_freed = FALSE;
- goto next_page;
- }
-
-
if (bpage->buf_fix_count > 0) {
mutex_exit(block_mutex);
@@ -1491,6 +1568,7 @@ buf_LRU_remove_block(
buf_page_t* bpage) /*!< in: control block */
{
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+ ulint zip_size;
ut_ad(buf_pool);
ut_ad(bpage);
@@ -1527,6 +1605,9 @@ buf_LRU_remove_block(
UT_LIST_REMOVE(LRU, buf_pool->LRU, bpage);
bpage->in_LRU_list = FALSE;
+ zip_size = page_zip_get_size(&bpage->zip);
+ buf_pool->stat.LRU_bytes -= zip_size ? zip_size : UNIV_PAGE_SIZE;
+
buf_unzip_LRU_remove_block_if_needed(bpage);
/* If the LRU list is so short that LRU_old is not defined,
@@ -1588,7 +1669,10 @@ buf_unzip_LRU_add_block(
}
/******************************************************************//**
-Adds a block to the LRU list end. */
+Adds a block to the LRU list end. Please make sure that the zip_size is
+already set into the page zip when invoking the function, so that we
+can get correct zip_size from the buffer page when adding a block
+into LRU */
UNIV_INLINE
void
buf_LRU_add_block_to_end_low(
@@ -1608,6 +1692,8 @@ buf_LRU_add_block_to_end_low(
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
bpage->in_LRU_list = TRUE;
+ incr_LRU_size_in_bytes(bpage, buf_pool);
+
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
ut_ad(buf_pool->LRU_old);
@@ -1636,7 +1722,10 @@ buf_LRU_add_block_to_end_low(
}
/******************************************************************//**
-Adds a block to the LRU list. */
+Adds a block to the LRU list. Please make sure that the zip_size is
+already set into the page zip when invoking the function, so that we
+can get correct zip_size from the buffer page when adding a block
+into LRU */
UNIV_INLINE
void
buf_LRU_add_block_low(
@@ -1679,6 +1768,8 @@ buf_LRU_add_block_low(
bpage->in_LRU_list = TRUE;
+ incr_LRU_size_in_bytes(bpage, buf_pool);
+
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
ut_ad(buf_pool->LRU_old);
@@ -1706,7 +1797,10 @@ buf_LRU_add_block_low(
}
/******************************************************************//**
-Adds a block to the LRU list. */
+Adds a block to the LRU list. Please make sure that the zip_size is
+already set into the page zip when invoking the function, so that we
+can get correct zip_size from the buffer page when adding a block
+into LRU */
UNIV_INTERN
void
buf_LRU_add_block(
@@ -1853,7 +1947,7 @@ alloc:
|| !buf_page_can_relocate(bpage)) {
not_freed:
if (b) {
- buf_buddy_free(buf_pool, b, sizeof *b, TRUE);
+ buf_page_free_descriptor(b);
}
if (!have_LRU_mutex)
mutex_exit(&buf_pool->LRU_list_mutex);
@@ -1935,6 +2029,8 @@ not_freed:
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU,
prev_b, b);
+ incr_LRU_size_in_bytes(b, buf_pool);
+
if (buf_page_is_old(b)) {
buf_pool->LRU_old_len++;
if (UNIV_UNLIKELY
@@ -2196,7 +2292,9 @@ buf_LRU_block_remove_hashed_page(
break;
case FIL_PAGE_INDEX:
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(&bpage->zip, page));
+ ut_a(page_zip_validate(
+ &bpage->zip, page,
+ ((buf_block_t*) bpage)->index));
#endif /* UNIV_ZIP_DEBUG */
break;
default:
diff --git a/storage/xtradb/buf/buf0rea.c b/storage/xtradb/buf/buf0rea.c
index 6d76a488af7..cf0a029df92 100644
--- a/storage/xtradb/buf/buf0rea.c
+++ b/storage/xtradb/buf/buf0rea.c
@@ -235,7 +235,8 @@ not_to_recover:
sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
((buf_block_t*) bpage)->frame, bpage, trx);
}
- if(sync) {
+
+ if (sync) {
thd_wait_end(NULL);
}
diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c
index 0d484dc44cd..4c6875bca10 100644
--- a/storage/xtradb/dict/dict0dict.c
+++ b/storage/xtradb/dict/dict0dict.c
@@ -525,6 +525,20 @@ dict_index_get_nth_col_or_prefix_pos(
return(ULINT_UNDEFINED);
}
+/********************************************************************//**
+Looks for column n in an index.
+@return position in internal representation of the index;
+ULINT_UNDEFINED if not contained */
+UNIV_INTERN
+ulint
+dict_index_get_nth_col_pos(
+/*=======================*/
+ const dict_index_t* index, /*!< in: index */
+ ulint n) /*!< in: column number */
+{
+ return(dict_index_get_nth_col_or_prefix_pos(index, n, FALSE));
+}
+
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Returns TRUE if the index contains a column or a prefix of that column.
@@ -2088,7 +2102,6 @@ dict_index_build_internal_clust(
{
dict_index_t* new_index;
dict_field_t* field;
- ulint fixed_size;
ulint trx_id_pos;
ulint i;
ibool* indexed;
@@ -2165,7 +2178,7 @@ dict_index_build_internal_clust(
for (i = 0; i < trx_id_pos; i++) {
- fixed_size = dict_col_get_fixed_size(
+ ulint fixed_size = dict_col_get_fixed_size(
dict_index_get_nth_col(new_index, i),
dict_table_is_comp(table));
@@ -2182,7 +2195,20 @@ dict_index_build_internal_clust(
break;
}
- new_index->trx_id_offset += (unsigned int) fixed_size;
+ /* Add fixed_size to new_index->trx_id_offset.
+ Because the latter is a bit-field, an overflow
+ can theoretically occur. Check for it. */
+ fixed_size += new_index->trx_id_offset;
+
+ new_index->trx_id_offset = fixed_size;
+
+ if (new_index->trx_id_offset != fixed_size) {
+ /* Overflow. Pretend that this is a
+ variable-length PRIMARY KEY. */
+ ut_ad(0);
+ new_index->trx_id_offset = 0;
+ break;
+ }
}
}
diff --git a/storage/xtradb/dict/dict0load.c b/storage/xtradb/dict/dict0load.c
index 0ef74ea8b7c..cdef0d1b270 100644
--- a/storage/xtradb/dict/dict0load.c
+++ b/storage/xtradb/dict/dict0load.c
@@ -2399,7 +2399,8 @@ dict_load_foreigns(
ibool check_charsets) /*!< in: TRUE=check charset
compatibility */
{
- char tuple_buf[DTUPLE_EST_ALLOC(1)];
+ ulint tuple_buf[(DTUPLE_EST_ALLOC(1) + sizeof(ulint) - 1)
+ / sizeof(ulint)];
btr_pcur_t pcur;
dtuple_t* tuple;
dfield_t* dfield;
diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c
index 4ab2c16d41f..af8353cdf45 100644
--- a/storage/xtradb/fil/fil0fil.c
+++ b/storage/xtradb/fil/fil0fil.c
@@ -195,14 +195,16 @@ struct fil_space_struct {
requests on the file */
ibool stop_new_ops;
/*!< we set this TRUE when we start
- deleting a single-table tablespace */
- ibool is_being_deleted;
- /*!< this is set to TRUE when we start
- deleting a single-table tablespace and its
- file; when this flag is set no further i/o
- or flush requests can be placed on this space,
- though there may be such requests still being
- processed on this space */
+ deleting a single-table tablespace.
+ When this is set following new ops
+ are not allowed:
+ * read IO request
+ * ibuf merge
+ * file flush
+ Note that we can still possibly have
+ new write operations because we don't
+ check this flag when doing flush
+ batches. */
ulint purpose;/*!< FIL_TABLESPACE, FIL_LOG, or
FIL_ARCH_LOG */
UT_LIST_BASE_NODE_T(fil_node_t) chain;
@@ -865,7 +867,7 @@ fil_node_close_file(
ut_ad(node && system);
ut_ad(mutex_own(&(system->mutex)));
ut_a(node->open);
- ut_a(node->n_pending == 0 || node->space->is_being_deleted);
+ ut_a(node->n_pending == 0 || node->space->stop_new_ops);
ut_a(node->n_pending_flushes == 0);
#ifndef UNIV_HOTBACKUP
ut_a(node->modification_counter == node->flush_counter
@@ -1099,7 +1101,7 @@ fil_node_free(
ut_ad(node && system && space);
ut_ad(mutex_own(&(system->mutex)));
ut_a(node->magic_n == FIL_NODE_MAGIC_N);
- ut_a(node->n_pending == 0 || space->is_being_deleted);
+ ut_a(node->n_pending == 0 || space->stop_new_ops);
if (node->open) {
/* We fool the assertion in fil_node_close_file() to think
@@ -1297,7 +1299,6 @@ try_again:
space->stop_ios = FALSE;
space->stop_new_ops = FALSE;
- space->is_being_deleted = FALSE;
space->purpose = purpose;
space->size = 0;
space->flags = flags;
@@ -1478,7 +1479,7 @@ fil_space_get_size(
ut_ad(fil_system);
- fil_mutex_enter_and_prepare_for_io(id);
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -1493,6 +1494,23 @@ fil_space_get_size(
ut_a(1 == UT_LIST_GET_LEN(space->chain));
+ mutex_exit(&fil_system->mutex);
+
+ /* It is possible that the space gets evicted at this point
+ before the fil_mutex_enter_and_prepare_for_io() acquires
+ the fil_system->mutex. Check for this after completing the
+ call to fil_mutex_enter_and_prepare_for_io(). */
+ fil_mutex_enter_and_prepare_for_io(id);
+
+ /* We are still holding the fil_system->mutex. Check if
+ the space is still in memory cache. */
+ space = fil_space_get_by_id(id);
+
+ if (space == NULL) {
+ mutex_exit(&fil_system->mutex);
+ return(0);
+ }
+
node = UT_LIST_GET_FIRST(space->chain);
/* It must be a single-table tablespace and we have not opened
@@ -1530,7 +1548,7 @@ fil_space_get_flags(
return(0);
}
- fil_mutex_enter_and_prepare_for_io(id);
+ mutex_enter(&fil_system->mutex);
space = fil_space_get_by_id(id);
@@ -1545,6 +1563,23 @@ fil_space_get_flags(
ut_a(1 == UT_LIST_GET_LEN(space->chain));
+ mutex_exit(&fil_system->mutex);
+
+ /* It is possible that the space gets evicted at this point
+ before the fil_mutex_enter_and_prepare_for_io() acquires
+ the fil_system->mutex. Check for this after completing the
+ call to fil_mutex_enter_and_prepare_for_io(). */
+ fil_mutex_enter_and_prepare_for_io(id);
+
+ /* We are still holding the fil_system->mutex. Check if
+ the space is still in memory cache. */
+ space = fil_space_get_by_id(id);
+
+ if (space == NULL) {
+ mutex_exit(&fil_system->mutex);
+ return(0);
+ }
+
node = UT_LIST_GET_FIRST(space->chain);
/* It must be a single-table tablespace and we have not opened
@@ -2325,11 +2360,9 @@ try_again:
return(FALSE);
}
- ut_a(space);
+ ut_a(space->stop_new_ops);
ut_a(space->n_pending_ops == 0);
- space->is_being_deleted = TRUE;
-
ut_a(UT_LIST_GET_LEN(space->chain) == 1);
node = UT_LIST_GET_FIRST(space->chain);
@@ -2372,12 +2405,26 @@ try_again:
rw_lock_x_lock(&space->latch);
#ifndef UNIV_HOTBACKUP
- /* Invalidate in the buffer pool all pages belonging to the
- tablespace. Since we have set space->is_being_deleted = TRUE, readahead
- or ibuf merge can no longer read more pages of this tablespace to the
- buffer pool. Thus we can clean the tablespace out of the buffer pool
- completely and permanently. The flag is_being_deleted also prevents
- fil_flush() from being applied to this tablespace. */
+ /* IMPORTANT: Because we have set space::stop_new_ops there
+ can't be any new ibuf merges, reads or flushes. We are here
+ because node::n_pending was zero above. However, it is still
+ possible to have pending read and write requests:
+
+ A read request can happen because the reader thread has
+ gone through the ::stop_new_ops check in buf_page_init_for_read()
+ before the flag was set and has not yet incremented ::n_pending
+ when we checked it above.
+
+ A write request can be issued any time because we don't check
+ the ::stop_new_ops flag when queueing a block for write.
+
+ We deal with pending write requests in the following function
+ where we'd minimally evict all dirty pages belonging to this
+ space from the flush_list. Not that if a block is IO-fixed
+ we'll wait for IO to complete.
+
+ To deal with potential read requests by checking the
+ ::stop_new_ops flag in fil_io() */
if (srv_lazy_drop_table) {
buf_LRU_mark_space_was_deleted(id);
@@ -2393,6 +2440,15 @@ try_again:
mutex_enter(&fil_system->mutex);
+ /* Double check the sanity of pending ops after reacquiring
+ the fil_system::mutex. */
+ if (fil_space_get_by_id(id)) {
+ ut_a(space->n_pending_ops == 0);
+ ut_a(UT_LIST_GET_LEN(space->chain) == 1);
+ node = UT_LIST_GET_FIRST(space->chain);
+ ut_a(node->n_pending == 0);
+ }
+
success = fil_space_free(id, TRUE);
mutex_exit(&fil_system->mutex);
@@ -2450,7 +2506,7 @@ fil_tablespace_is_being_deleted(
ut_a(space != NULL);
- is_being_deleted = space->is_being_deleted;
+ is_being_deleted = space->stop_new_ops;
mutex_exit(&fil_system->mutex);
@@ -2710,7 +2766,7 @@ retry:
mutex_exit(&fil_system->mutex);
#ifndef UNIV_HOTBACKUP
- if (success) {
+ if (success && !recv_recovery_on) {
mtr_t mtr;
mtr_start(&mtr);
@@ -4531,7 +4587,7 @@ fil_tablespace_deleted_or_being_deleted_in_mem(
space = fil_space_get_by_id(id);
- if (space == NULL || space->is_being_deleted) {
+ if (space == NULL || space->stop_new_ops) {
mutex_exit(&fil_system->mutex);
return(TRUE);
@@ -5271,7 +5327,9 @@ _fil_io(
space = fil_space_get_by_id(space_id);
- if (!space) {
+ /* If we are deleting a tablespace we don't allow any read
+ operations on that. However, we do allow write operations. */
+ if (!space || (type == OS_FILE_READ && space->stop_new_ops)) {
mutex_exit(&fil_system->mutex);
ut_print_timestamp(stderr);
@@ -5362,8 +5420,8 @@ _fil_io(
/* Do aio */
- ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
- ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
+ ut_a(byte_offset % OS_MIN_LOG_BLOCK_SIZE == 0);
+ ut_a((len % OS_MIN_LOG_BLOCK_SIZE) == 0);
if (srv_pass_corrupt_table == 1 && space->is_corrupt) {
/* should ignore i/o for the crashed space */
@@ -5551,7 +5609,7 @@ fil_aio_wait(
&& ((buf_page_t*)message)->space_was_being_deleted) {
/* intended not to be uncompress read page */
- ut_a(buf_page_get_io_fix(message) == BUF_IO_WRITE
+ ut_a(buf_page_get_io_fix_unlocked(message) == BUF_IO_WRITE
|| !buf_page_get_zip_size(message)
|| buf_page_get_state(message) != BUF_BLOCK_FILE_PAGE);
@@ -5612,7 +5670,7 @@ fil_flush(
space = fil_space_get_by_id(space_id);
- if (!space || space->is_being_deleted) {
+ if (!space || space->stop_new_ops) {
mutex_exit(&fil_system->mutex);
return;
@@ -5743,7 +5801,7 @@ fil_flush_file_spaces(
space;
space = UT_LIST_GET_NEXT(unflushed_spaces, space)) {
- if (space->purpose == purpose && !space->is_being_deleted) {
+ if (space->purpose == purpose && !space->stop_new_ops) {
space_ids[n_space_ids++] = space->id;
}
@@ -5982,3 +6040,26 @@ fil_space_set_corrupt(
mutex_exit(&fil_system->mutex);
}
+/****************************************************************//**
+Generate redo logs for swapping two .ibd files */
+UNIV_INTERN
+void
+fil_mtr_rename_log(
+/*===============*/
+ ulint old_space_id, /*!< in: tablespace id of the old
+ table. */
+ const char* old_name, /*!< in: old table name */
+ ulint new_space_id, /*!< in: tablespace id of the new
+ table */
+ const char* new_name, /*!< in: new table name */
+ const char* tmp_name) /*!< in: temp table name used while
+ swapping */
+{
+ mtr_t mtr;
+ mtr_start(&mtr);
+ fil_op_write_log(MLOG_FILE_RENAME, old_space_id,
+ 0, 0, old_name, tmp_name, &mtr);
+ fil_op_write_log(MLOG_FILE_RENAME, new_space_id,
+ 0, 0, new_name, old_name, &mtr);
+ mtr_commit(&mtr);
+}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 7b96c18d835..02ee941351e 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -85,6 +85,7 @@ extern "C" {
#include "row0sel.h"
#include "row0upd.h"
#include "log0log.h"
+#include "log0online.h"
#include "lock0lock.h"
#include "dict0crea.h"
#include "btr0cur.h"
@@ -326,6 +327,7 @@ static PSI_mutex_info all_innodb_mutexes[] = {
{&ibuf_pessimistic_insert_mutex_key,
"ibuf_pessimistic_insert_mutex", 0},
{&kernel_mutex_key, "kernel_mutex", 0},
+ {&log_bmp_sys_mutex_key, "log_bmp_sys_mutex", 0},
{&log_sys_mutex_key, "log_sys_mutex", 0},
# ifdef UNIV_MEM_DEBUG
{&mem_hash_mutex_key, "mem_hash_mutex", 0},
@@ -465,6 +467,25 @@ uint
innobase_alter_table_flags(
/*=======================*/
uint flags);
+/************************************************************//**
+Synchronously read and parse the redo log up to the last
+checkpoint to write the changed page bitmap.
+@return 0 to indicate success. Current implementation cannot fail. */
+static
+my_bool
+innobase_flush_changed_page_bitmaps() __attribute__((unused));
+/*==================================*/
+/************************************************************//**
+Delete all the bitmap files for data less than the specified LSN.
+If called with lsn == 0 (i.e. set by RESET request) or
+IB_ULONGLONG_MAX, restart the bitmap file sequence, otherwise
+continue it.
+@return 0 to indicate success, 1 for failure. */
+static
+my_bool
+innobase_purge_changed_page_bitmaps(
+/*================================*/
+ ulonglong lsn) __attribute__((unused)); /*!< in: LSN to purge files up to */
static const char innobase_hton_name[]= "InnoDB";
@@ -709,8 +730,12 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &export_vars.innodb_background_log_sync, SHOW_LONG},
{"buffer_pool_pages_data",
(char*) &export_vars.innodb_buffer_pool_pages_data, SHOW_LONG},
+ {"buffer_pool_bytes_data",
+ (char*) &export_vars.innodb_buffer_pool_bytes_data, SHOW_LONG},
{"buffer_pool_pages_dirty",
(char*) &export_vars.innodb_buffer_pool_pages_dirty, SHOW_LONG},
+ {"buffer_pool_bytes_dirty",
+ (char*) &export_vars.innodb_buffer_pool_bytes_dirty, SHOW_LONG},
{"buffer_pool_pages_flushed",
(char*) &export_vars.innodb_buffer_pool_pages_flushed, SHOW_LONG},
{"buffer_pool_pages_LRU_flushed",
@@ -891,6 +916,12 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &export_vars.innodb_x_lock_spin_rounds, SHOW_LONGLONG},
{"x_lock_spin_waits",
(char*) &export_vars.innodb_x_lock_spin_waits, SHOW_LONGLONG},
+#ifdef UNIV_DEBUG
+ {"purge_trx_id_age",
+ (char*) &export_vars.innodb_purge_trx_id_age, SHOW_LONG},
+ {"purge_view_trx_id_age",
+ (char*) &export_vars.innodb_purge_view_trx_id_age, SHOW_LONG},
+#endif /* UNIV_DEBUG */
{NullS, NullS, SHOW_LONG}
};
@@ -1256,11 +1287,23 @@ convert_error_code_to_mysql(
case DB_TABLE_NOT_FOUND:
return(HA_ERR_NO_SUCH_TABLE);
- case DB_TOO_BIG_RECORD:
- my_error(ER_TOO_BIG_ROWSIZE, MYF(0),
- page_get_free_space_of_empty(flags
- & DICT_TF_COMPACT) / 2);
+ case DB_TOO_BIG_RECORD: {
+ /* If prefix is true then a 768-byte prefix is stored
+ locally for BLOB fields. Refer to dict_table_get_format() */
+ bool prefix = ((flags & DICT_TF_FORMAT_MASK)
+ >> DICT_TF_FORMAT_SHIFT) < UNIV_FORMAT_B;
+ my_printf_error(ER_TOO_BIG_ROWSIZE,
+ "Row size too large (> %lu). Changing some columns "
+ "to TEXT or BLOB %smay help. In current row "
+ "format, BLOB prefix of %d bytes is stored inline.",
+ MYF(0),
+ page_get_free_space_of_empty(flags &
+ DICT_TF_COMPACT) / 2,
+ prefix ? "or using ROW_FORMAT=DYNAMIC "
+ "or ROW_FORMAT=COMPRESSED ": "",
+ prefix ? DICT_MAX_FIXED_COL_LEN : 0);
return(HA_ERR_TO_BIG_ROW);
+ }
case DB_TOO_BIG_INDEX_COL:
my_error(ER_INDEX_COLUMN_TOO_LONG, MYF(0),
@@ -1299,6 +1342,8 @@ convert_error_code_to_mysql(
return(HA_ERR_INDEX_CORRUPT);
case DB_UNDO_RECORD_TOO_BIG:
return(HA_ERR_UNDO_REC_TOO_BIG);
+ case DB_OUT_OF_MEMORY:
+ return(HA_ERR_OUT_OF_MEM);
}
}
@@ -1476,100 +1521,6 @@ innobase_get_lower_case_table_names(void)
return(lower_case_table_names);
}
-#if defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN)
-extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list;
-/*******************************************************************//**
-Map an OS error to an errno value. The OS error number is stored in
-_doserrno and the mapped value is stored in errno) */
-extern "C"
-void __cdecl
-_dosmaperr(
- unsigned long); /*!< in: OS error value */
-
-/*********************************************************************//**
-Creates a temporary file.
-@return temporary file descriptor, or < 0 on error */
-extern "C" UNIV_INTERN
-int
-innobase_mysql_tmpfile(void)
-/*========================*/
-{
- int fd; /* handle of opened file */
- HANDLE osfh; /* OS handle of opened file */
- char* tmpdir; /* point to the directory
- where to create file */
- TCHAR path_buf[MAX_PATH - 14]; /* buffer for tmp file path.
- The length cannot be longer
- than MAX_PATH - 14, or
- GetTempFileName will fail. */
- char filename[MAX_PATH]; /* name of the tmpfile */
- DWORD fileaccess = GENERIC_READ /* OS file access */
- | GENERIC_WRITE
- | DELETE;
- DWORD fileshare = FILE_SHARE_READ /* OS file sharing mode */
- | FILE_SHARE_WRITE
- | FILE_SHARE_DELETE;
- DWORD filecreate = CREATE_ALWAYS; /* OS method of open/create */
- DWORD fileattrib = /* OS file attribute flags */
- FILE_ATTRIBUTE_NORMAL
- | FILE_FLAG_DELETE_ON_CLOSE
- | FILE_ATTRIBUTE_TEMPORARY
- | FILE_FLAG_SEQUENTIAL_SCAN;
-
- DBUG_ENTER("innobase_mysql_tmpfile");
-
- tmpdir = my_tmpdir(&mysql_tmpdir_list);
-
- /* The tmpdir parameter can not be NULL for GetTempFileName. */
- if (!tmpdir) {
- uint ret;
-
- /* Use GetTempPath to determine path for temporary files. */
- ret = GetTempPath(sizeof(path_buf), path_buf);
- if (ret > sizeof(path_buf) || (ret == 0)) {
-
- _dosmaperr(GetLastError()); /* map error */
- DBUG_RETURN(-1);
- }
-
- tmpdir = path_buf;
- }
-
- /* Use GetTempFileName to generate a unique filename. */
- if (!GetTempFileName(tmpdir, "ib", 0, filename)) {
-
- _dosmaperr(GetLastError()); /* map error */
- DBUG_RETURN(-1);
- }
-
- DBUG_PRINT("info", ("filename: %s", filename));
-
- /* Open/Create the file. */
- osfh = CreateFile(filename, fileaccess, fileshare, NULL,
- filecreate, fileattrib, NULL);
- if (osfh == INVALID_HANDLE_VALUE) {
-
- /* open/create file failed! */
- _dosmaperr(GetLastError()); /* map error */
- DBUG_RETURN(-1);
- }
-
- do {
- /* Associates a CRT file descriptor with the OS file handle. */
- fd = _open_osfhandle((intptr_t) osfh, 0);
- } while (fd == -1 && errno == EINTR);
-
- if (fd == -1) {
- /* Open failed, close the file handle. */
-
- _dosmaperr(GetLastError()); /* map error */
- CloseHandle(osfh); /* no need to check if
- CloseHandle fails */
- }
-
- DBUG_RETURN(fd);
-}
-#else
/*********************************************************************//**
Creates a temporary file.
@return temporary file descriptor, or < 0 on error */
@@ -1582,7 +1533,15 @@ innobase_mysql_tmpfile(void)
os_event_wait(srv_allow_writes_event);
#endif /* WITH_INNODB_DISALLOW_WRITES */
int fd2 = -1;
- File fd = mysql_tmpfile("ib");
+ File fd;
+
+ DBUG_EXECUTE_IF(
+ "innobase_tmpfile_creation_failure",
+ return(-1);
+ );
+
+ fd = mysql_tmpfile("ib");
+
if (fd >= 0) {
/* Copy the file descriptor, so that the additional resources
allocated by create_temp_file() can be freed by invoking
@@ -1626,7 +1585,6 @@ innobase_mysql_tmpfile(void)
}
return(fd2);
}
-#endif /* defined (__WIN__) && defined (MYSQL_DYNAMIC_PLUGIN) */
/*********************************************************************//**
Wrapper around MySQL's copy_and_convert function.
@@ -1742,10 +1700,13 @@ innobase_next_autoinc(
offset = 0;
}
- /* Check for overflow. */
+ /* Check for overflow. Current can be > max_value if the value is
+ in reality a negative value.The visual studio compilers converts
+ large double values automatically into unsigned long long datatype
+ maximum value */
if (block >= max_value
|| offset > max_value
- || current == max_value
+ || current >= max_value
|| max_value - offset <= offset) {
next_value = max_value;
@@ -1818,7 +1779,7 @@ innobase_trx_init(
trx->fake_changes = THDVAR(thd, fake_changes);
#ifdef EXTENDED_SLOWLOG
- if (thd_log_slow_verbosity(thd) & SLOG_V_INNODB) {
+ if (thd_log_slow_verbosity(thd) & (1ULL << SLOG_V_INNODB)) {
trx->take_stats = TRUE;
} else {
trx->take_stats = FALSE;
@@ -2761,6 +2722,7 @@ innobase_init(
} else {
srv_log_block_size = 512;
}
+ ut_ad (srv_log_block_size >= OS_MIN_LOG_BLOCK_SIZE);
if (!srv_log_block_size) {
fprintf(stderr,
@@ -3307,6 +3269,36 @@ innobase_alter_table_flags(
| HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE);
}
+/************************************************************//**
+Synchronously read and parse the redo log up to the last
+checkpoint to write the changed page bitmap.
+@return 0 to indicate success. Current implementation cannot fail. */
+static
+my_bool
+innobase_flush_changed_page_bitmaps()
+/*=================================*/
+{
+ if (srv_track_changed_pages) {
+ os_event_reset(srv_checkpoint_completed_event);
+ log_online_follow_redo_log();
+ }
+ return FALSE;
+}
+
+/************************************************************//**
+Delete all the bitmap files for data less than the specified LSN.
+If called with lsn == IB_ULONGLONG_MAX (i.e. set by RESET request),
+restart the bitmap file sequence, otherwise continue it.
+@return 0 to indicate success, 1 for failure. */
+static
+my_bool
+innobase_purge_changed_page_bitmaps(
+/*================================*/
+ ulonglong lsn) /*!< in: LSN to purge files up to */
+{
+ return (my_bool)log_online_purge_changed_page_bitmaps(lsn);
+}
+
/****************************************************************//**
Copy the current replication position from MySQL to a transaction. */
static
@@ -3347,7 +3339,7 @@ innobase_commit_low(
header for undo purposes, see the comment at corresponding call
at innobase_xa_prepare(). */
- innobase_copy_repl_coords_to_trx(current_thd, trx);
+ innobase_copy_repl_coords_to_trx((THD *) trx->mysql_thd, trx);
trx_commit_for_mysql(trx);
}
@@ -11462,23 +11454,26 @@ ha_innobase::external_lock(
if (trx->n_mysql_tables_in_use == 0) {
#ifdef EXTENDED_SLOWLOG
- increment_thd_innodb_stats(thd,
- (unsigned long long) trx->id,
- trx->io_reads,
- trx->io_read,
- trx->io_reads_wait_timer,
- trx->lock_que_wait_timer,
- trx->innodb_que_wait_timer,
- trx->distinct_page_access);
-
- trx->io_reads = 0;
- trx->io_read = 0;
- trx->io_reads_wait_timer = 0;
- trx->lock_que_wait_timer = 0;
- trx->innodb_que_wait_timer = 0;
- trx->distinct_page_access = 0;
- if (trx->distinct_page_access_hash)
- memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
+ if (UNIV_UNLIKELY(trx->take_stats)) {
+ increment_thd_innodb_stats(thd,
+ (unsigned long long) trx->id,
+ trx->io_reads,
+ trx->io_read,
+ trx->io_reads_wait_timer,
+ trx->lock_que_wait_timer,
+ trx->innodb_que_wait_timer,
+ trx->distinct_page_access);
+
+ trx->io_reads = 0;
+ trx->io_read = 0;
+ trx->io_reads_wait_timer = 0;
+ trx->lock_que_wait_timer = 0;
+ trx->innodb_que_wait_timer = 0;
+ trx->distinct_page_access = 0;
+ if (trx->distinct_page_access_hash)
+ memset(trx->distinct_page_access_hash, 0,
+ DPAH_SIZE);
+ }
#endif
trx->mysql_n_tables_locked = 0;
@@ -13812,7 +13807,8 @@ static MYSQL_SYSVAR_ULONG(page_size, innobase_page_size,
static MYSQL_SYSVAR_ULONG(log_block_size, innobase_log_block_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
"###EXPERIMENTAL###: The log block size of the transaction log file. Changing for created log file is not supported. Use on your own risk!",
- NULL, NULL, (1 << 9)/*512*/, (1 << 9)/*512*/, (1 << UNIV_PAGE_SIZE_SHIFT_MAX), 0);
+ NULL, NULL, (1 << 9)/*512*/, OS_MIN_LOG_BLOCK_SIZE,
+ (1 << UNIV_PAGE_SIZE_SHIFT_MAX), 0);
static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
PLUGIN_VAR_READONLY,
@@ -14235,7 +14231,7 @@ static MYSQL_SYSVAR_ULONGLONG(max_bitmap_file_size, srv_max_bitmap_file_size,
"The maximum size of changed page bitmap files",
NULL, NULL, 100*1024*1024ULL, 4096ULL, ULONGLONG_MAX, 0);
-static MYSQL_SYSVAR_ULONGLONG(changed_pages_limit, srv_changed_pages_limit,
+static MYSQL_SYSVAR_ULONGLONG(max_changed_pages, srv_max_changed_pages,
PLUGIN_VAR_RQCMDARG,
"The maximum number of rows for "
"INFORMATION_SCHEMA.INNODB_CHANGED_PAGES table, "
@@ -14245,8 +14241,8 @@ static MYSQL_SYSVAR_ULONGLONG(changed_pages_limit, srv_changed_pages_limit,
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug,
PLUGIN_VAR_RQCMDARG,
- "Debug flags for InnoDB change buffering (0=none)",
- NULL, NULL, 0, 0, 1, 0);
+ "Debug flags for InnoDB change buffering (0=none, 2=crash at merge)",
+ NULL, NULL, 0, 0, 2, 0);
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
#ifdef WITH_INNODB_DISALLOW_WRITES
@@ -14294,11 +14290,23 @@ static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
"trigger a readahead.",
NULL, NULL, 56, 0, 64, 0);
-#ifdef UNIV_DEBUG_never
+#ifdef UNIV_DEBUG
static MYSQL_SYSVAR_UINT(trx_rseg_n_slots_debug, trx_rseg_n_slots_debug,
- PLUGIN_VAR_RQCMDARG,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_NOCMDOPT,
"Debug flags for InnoDB to limit TRX_RSEG_N_SLOTS for trx_rsegf_undo_find_free()",
NULL, NULL, 0, 0, 1024, 0);
+
+static MYSQL_SYSVAR_UINT(limit_optimistic_insert_debug,
+ btr_cur_limit_optimistic_insert_debug, PLUGIN_VAR_RQCMDARG,
+ "Artificially limit the number of records per B-tree page (0=unlimited).",
+ NULL, NULL, 0, 0, UINT_MAX32, 0);
+
+static MYSQL_SYSVAR_BOOL(trx_purge_view_update_only_debug,
+ srv_purge_view_update_only_debug, PLUGIN_VAR_NOCMDOPT,
+ "Pause actual purging any delete-marked records, but merely update the purge view. "
+ "It is to create artificially the situation the purge view have been updated "
+ "but the each purges were not done yet.",
+ NULL, NULL, FALSE);
#endif /* UNIV_DEBUG */
static MYSQL_SYSVAR_LONGLONG(ibuf_max_size, srv_ibuf_max_size,
@@ -14478,6 +14486,11 @@ static MYSQL_SYSVAR_BOOL(locking_fake_changes, srv_fake_changes_locks,
"not take any locks at all.",
NULL, NULL, TRUE);
+static MYSQL_SYSVAR_BOOL(print_all_deadlocks, srv_print_all_deadlocks,
+ PLUGIN_VAR_OPCMDARG,
+ "Print all deadlocks to MySQL error log (off by default)",
+ NULL, NULL, FALSE);
+
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(page_size),
MYSQL_SYSVAR(log_block_size),
@@ -14570,7 +14583,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(change_buffering),
MYSQL_SYSVAR(track_changed_pages),
MYSQL_SYSVAR(max_bitmap_file_size),
- MYSQL_SYSVAR(changed_pages_limit),
+ MYSQL_SYSVAR(max_changed_pages),
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
MYSQL_SYSVAR(change_buffering_debug),
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
@@ -14585,14 +14598,17 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(purge_threads),
MYSQL_SYSVAR(purge_batch_size),
MYSQL_SYSVAR(rollback_segments),
-#ifdef UNIV_DEBUG_never /* disable this flag. --innodb-trx becomes ambiguous */
+#ifdef UNIV_DEBUG
MYSQL_SYSVAR(trx_rseg_n_slots_debug),
+ MYSQL_SYSVAR(limit_optimistic_insert_debug),
+ MYSQL_SYSVAR(trx_purge_view_update_only_debug),
#endif /* UNIV_DEBUG */
MYSQL_SYSVAR(corrupt_table_action),
MYSQL_SYSVAR(lazy_drop_table),
MYSQL_SYSVAR(fake_changes),
MYSQL_SYSVAR(locking_fake_changes),
MYSQL_SYSVAR(merge_sort_block_size),
+ MYSQL_SYSVAR(print_all_deadlocks),
NULL
};
diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h
index 851fbb828e4..33062438207 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -81,12 +81,13 @@ class ha_innobase: public handler
uchar* upd_buf; /*!< buffer used in updates */
ulint upd_buf_size; /*!< the size of upd_buf in bytes */
- uchar srch_key_val1[REC_VERSION_56_MAX_INDEX_COL_LEN + 2];
- uchar srch_key_val2[REC_VERSION_56_MAX_INDEX_COL_LEN + 2];
+ uchar srch_key_val1[MAX_KEY_LENGTH + MAX_REF_PARTS*2];
+ uchar srch_key_val2[MAX_KEY_LENGTH + MAX_REF_PARTS*2];
/*!< buffers used in converting
search key values from MySQL format
- to InnoDB format. "+ 2" for the two
- bytes where the length is stored */
+ to InnoDB format. For each column
+ 2 bytes are used to store length,
+ hence MAX_REF_PARTS*2. */
Table_flags int_table_flags;
uint primary_key;
ulong start_of_scan; /*!< this is set to 1 when we are
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 823f1c56313..3251da6acdd 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -106,8 +106,6 @@ innobase_col_to_mysql(
ut_ad(flen >= len);
ut_ad(DATA_MBMAXLEN(col->mbminmaxlen)
>= DATA_MBMINLEN(col->mbminmaxlen));
- ut_ad(DATA_MBMAXLEN(col->mbminmaxlen)
- > DATA_MBMINLEN(col->mbminmaxlen) || flen == len);
memcpy(dest, data, len);
break;
@@ -117,13 +115,17 @@ innobase_col_to_mysql(
/* These column types should never be shipped to MySQL. */
ut_ad(0);
- case DATA_CHAR:
case DATA_FIXBINARY:
case DATA_FLOAT:
case DATA_DOUBLE:
case DATA_DECIMAL:
/* Above are the valid column types for MySQL data. */
ut_ad(flen == len);
+ /* fall through */
+ case DATA_CHAR:
+ /* We may have flen > len when there is a shorter
+ prefix on a CHAR column. */
+ ut_ad(flen >= len);
#else /* UNIV_DEBUG */
default:
#endif /* UNIV_DEBUG */
@@ -156,7 +158,7 @@ innobase_rec_to_mysql(
field->reset();
- ipos = dict_index_get_nth_col_pos(index, i);
+ ipos = dict_index_get_nth_col_or_prefix_pos(index, i, TRUE);
if (UNIV_UNLIKELY(ipos == ULINT_UNDEFINED)) {
null_field:
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index 4b33d6a780c..e868fb322a7 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -169,7 +169,8 @@ do { \
} \
} while (0)
-#if !defined __STRICT_ANSI__ && defined __GNUC__ && (__GNUC__) > 2 && !defined __INTEL_COMPILER
+#if !defined __STRICT_ANSI__ && defined __GNUC__ && (__GNUC__) > 2 && \
+ !defined __INTEL_COMPILER && !defined __clang__
#define STRUCT_FLD(name, value) name: value
#else
#define STRUCT_FLD(name, value) value
@@ -7356,8 +7357,8 @@ i_s_innodb_changed_pages_fill(
}
while(log_online_bitmap_iterator_next(&i) &&
- (!srv_changed_pages_limit ||
- output_rows_num < srv_changed_pages_limit) &&
+ (!srv_max_changed_pages ||
+ output_rows_num < srv_max_changed_pages) &&
/*
There is no need to compare both start LSN and end LSN fields
with maximum value. It's enough to compare only start LSN.
diff --git a/storage/xtradb/ibuf/ibuf0ibuf.c b/storage/xtradb/ibuf/ibuf0ibuf.c
index 77305e42fb1..96c264b32b4 100644
--- a/storage/xtradb/ibuf/ibuf0ibuf.c
+++ b/storage/xtradb/ibuf/ibuf0ibuf.c
@@ -2912,6 +2912,14 @@ ibuf_get_volume_buffered_count_func(
ut_a(len == 1);
ut_ad(trx_sys_multiple_tablespace_format);
+ if (rec_get_deleted_flag(rec, 0)) {
+ /* This record has been merged already,
+ but apparently the system crashed before
+ the change was discarded from the buffer.
+ Pretend that the record does not exist. */
+ return(0);
+ }
+
types = rec_get_nth_field_old(rec, IBUF_REC_FIELD_METADATA, &len);
switch (UNIV_EXPECT(len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE,
@@ -4224,11 +4232,11 @@ ibuf_delete(
page, 1);
}
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
page_cur_delete_rec(&page_cur, index, offsets, mtr);
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
if (page_zip) {
@@ -4333,6 +4341,22 @@ ibuf_delete_rec(
ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no);
ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space);
+#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
+ if (ibuf_debug == 2) {
+ /* Inject a fault (crash). We do this before trying
+ optimistic delete, because a pessimistic delete in the
+ change buffer would require a larger test case. */
+
+ /* Flag the buffered record as processed, to avoid
+ an assertion failure after crash recovery. */
+ btr_cur_set_deleted_flag_for_ibuf(
+ btr_pcur_get_rec(pcur), NULL, TRUE, mtr);
+ ibuf_mtr_commit(mtr);
+ log_make_checkpoint_at(IB_ULONGLONG_MAX, TRUE);
+ DBUG_SUICIDE();
+ }
+#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
+
success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur), mtr);
if (success) {
@@ -4367,7 +4391,13 @@ ibuf_delete_rec(
ut_ad(ibuf_rec_get_page_no(mtr, btr_pcur_get_rec(pcur)) == page_no);
ut_ad(ibuf_rec_get_space(mtr, btr_pcur_get_rec(pcur)) == space);
- /* We have to resort to a pessimistic delete from ibuf */
+ /* We have to resort to a pessimistic delete from ibuf.
+ Delete-mark the record so that it will not be applied again,
+ in case the server crashes before the pessimistic delete is
+ made persistent. */
+ btr_cur_set_deleted_flag_for_ibuf(
+ btr_pcur_get_rec(pcur), NULL, TRUE, mtr);
+
btr_pcur_store_position(pcur, mtr);
ibuf_btr_pcur_commit_specify_mtr(pcur, mtr);
@@ -4448,7 +4478,7 @@ ibuf_merge_or_delete_for_page(
ut_ad(!block || buf_block_get_space(block) == space);
ut_ad(!block || buf_block_get_page_no(block) == page_no);
ut_ad(!block || buf_block_get_zip_size(block) == zip_size);
- ut_ad(!block || buf_block_get_io_fix(block) == BUF_IO_READ);
+ ut_ad(!block || buf_block_get_io_fix_unlocked(block) == BUF_IO_READ);
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE
|| trx_sys_hdr_page(space, page_no)) {
@@ -4648,7 +4678,7 @@ loop:
fputs("InnoDB: Discarding record\n ", stderr);
rec_print_old(stderr, rec);
fputs("\nInnoDB: from the insert buffer!\n\n", stderr);
- } else if (block) {
+ } else if (block && !rec_get_deleted_flag(rec, 0)) {
/* Now we have at pcur a record which should be
applied on the index page; NOTE that the call below
copies pointers to fields in rec, and we must
diff --git a/storage/xtradb/include/btr0cur.h b/storage/xtradb/include/btr0cur.h
index cb44129aeb5..97929d44159 100644
--- a/storage/xtradb/include/btr0cur.h
+++ b/storage/xtradb/include/btr0cur.h
@@ -636,7 +636,7 @@ btr_cur_set_deleted_flag_for_ibuf(
when the tablespace is
uncompressed */
ibool val, /*!< in: value to set */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr); /*!< in/out: mini-transaction */
/*######################################################################*/
/** In the pessimistic delete, if the page data size drops below this
@@ -806,6 +806,11 @@ srv_printf_innodb_monitor(). */
extern ulint btr_cur_n_sea_old;
#endif /* !UNIV_HOTBACKUP */
+#ifdef UNIV_DEBUG
+/* Flag to limit optimistic insert records */
+extern uint btr_cur_limit_optimistic_insert_debug;
+#endif /* UNIV_DEBUG */
+
#ifndef UNIV_NONINL
#include "btr0cur.ic"
#endif
diff --git a/storage/xtradb/include/btr0cur.ic b/storage/xtradb/include/btr0cur.ic
index e31f77c77eb..5fc4651ca13 100644
--- a/storage/xtradb/include/btr0cur.ic
+++ b/storage/xtradb/include/btr0cur.ic
@@ -27,6 +27,16 @@ Created 10/16/1994 Heikki Tuuri
#include "btr0btr.h"
#ifdef UNIV_DEBUG
+# define LIMIT_OPTIMISTIC_INSERT_DEBUG(NREC, CODE)\
+if (btr_cur_limit_optimistic_insert_debug\
+ && (NREC) >= (ulint)btr_cur_limit_optimistic_insert_debug) {\
+ CODE;\
+}
+#else
+# define LIMIT_OPTIMISTIC_INSERT_DEBUG(NREC, CODE)
+#endif /* UNIV_DEBUG */
+
+#ifdef UNIV_DEBUG
/*********************************************************//**
Returns the page cursor component of a tree cursor.
@return pointer to page cursor component */
@@ -146,6 +156,9 @@ btr_cur_compress_recommendation(
page = btr_cur_get_page(cursor);
+ LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page) * 2,
+ return(FALSE));
+
if ((page_get_data_size(page) < BTR_CUR_PAGE_COMPRESS_LIMIT)
|| ((btr_page_get_next(page, mtr) == FIL_NULL)
&& (btr_page_get_prev(page, mtr) == FIL_NULL))) {
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index d48c7f0212f..e0d7a974fc3 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -199,6 +199,15 @@ struct buf_pool_info_struct{
typedef struct buf_pool_info_struct buf_pool_info_t;
+/** The occupied bytes of lists in all buffer pools */
+struct buf_pools_list_size_struct {
+ ulint LRU_bytes; /*!< LRU size in bytes */
+ ulint unzip_LRU_bytes; /*!< unzip_LRU size in bytes */
+ ulint flush_list_bytes; /*!< flush_list size in bytes */
+};
+
+typedef struct buf_pools_list_size_struct buf_pools_list_size_t;
+
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Acquire mutex on all buffer pool instances */
@@ -958,7 +967,7 @@ buf_block_set_file_page(
ulint space, /*!< in: tablespace id */
ulint page_no);/*!< in: page number */
/*********************************************************************//**
-Gets the io_fix state of a block.
+Gets the io_fix state of a block. Requires that the block mutex is held.
@return io_fix state */
UNIV_INLINE
enum buf_io_fix
@@ -967,7 +976,17 @@ buf_page_get_io_fix(
const buf_page_t* bpage) /*!< in: pointer to the control block */
__attribute__((pure));
/*********************************************************************//**
-Gets the io_fix state of a block.
+Gets the io_fix state of a block. Does not assert that the block mutex is
+held, to be used in the cases where it is safe not to hold it.
+@return io_fix state */
+UNIV_INLINE
+enum buf_io_fix
+buf_page_get_io_fix_unlocked(
+/*=========================*/
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
+ __attribute__((pure));
+/*********************************************************************//**
+Gets the io_fix state of a block. Requires that the block mutex is held.
@return io_fix state */
UNIV_INLINE
enum buf_io_fix
@@ -976,6 +995,16 @@ buf_block_get_io_fix(
const buf_block_t* block) /*!< in: pointer to the control block */
__attribute__((pure));
/*********************************************************************//**
+Gets the io_fix state of a block. Does not assert that the block mutex is
+held, to be used in the cases where it is safe not to hold it.
+@return io_fix state */
+UNIV_INLINE
+enum buf_io_fix
+buf_block_get_io_fix_unlocked(
+/*==========================*/
+ const buf_block_t* block) /*!< in: pointer to the control block */
+ __attribute__((pure));
+/*********************************************************************//**
Sets the io_fix state of a block. */
UNIV_INLINE
void
@@ -1054,8 +1083,7 @@ UNIV_INLINE
void
buf_page_set_accessed(
/*==================*/
- buf_page_t* bpage, /*!< in/out: control block */
- ulint time_ms) /*!< in: ut_time_ms() */
+ buf_page_t* bpage) /*!< in/out: control block */
__attribute__((nonnull));
/*********************************************************************//**
Gets the buf_block_t handle of a buffered file block if an uncompressed
@@ -1374,6 +1402,14 @@ buf_get_total_list_len(
ulint* free_len, /*!< out: length of all free lists */
ulint* flush_list_len);/*!< out: length of all flush lists */
/********************************************************************//**
+Get total list size in bytes from all buffer pools. */
+UNIV_INTERN
+void
+buf_get_total_list_size_in_bytes(
+/*=============================*/
+ buf_pools_list_size_t* buf_pools_list_size); /*!< out: list sizes
+ in all buffer pools */
+/********************************************************************//**
Get total buffer pool statistics. */
UNIV_INTERN
void
@@ -1548,10 +1584,11 @@ struct buf_page_struct{
to read this for heuristic
purposes without holding any
mutex or latch */
- unsigned access_time:32; /*!< time of first access, or
- 0 if the block was never accessed
- in the buffer pool */
/* @} */
+ unsigned access_time; /*!< time of first access, or
+ 0 if the block was never accessed
+ in the buffer pool. Protected by
+ block mutex */
ibool space_was_being_deleted;
ibool is_corrupt;
# if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
@@ -1741,6 +1778,8 @@ struct buf_pool_stat_struct{
young because the first access
was not long enough ago, in
buf_page_peek_if_too_old() */
+ ulint LRU_bytes; /*!< LRU size in bytes */
+ ulint flush_list_bytes;/*!< flush_list size in bytes */
};
/** Statistics of buddy blocks of a given size. */
diff --git a/storage/xtradb/include/buf0buf.ic b/storage/xtradb/include/buf0buf.ic
index 221f86d9d62..8d5c3edeef8 100644
--- a/storage/xtradb/include/buf0buf.ic
+++ b/storage/xtradb/include/buf0buf.ic
@@ -434,7 +434,7 @@ buf_block_set_file_page(
}
/*********************************************************************//**
-Gets the io_fix state of a block.
+Gets the io_fix state of a block. Requires that the block mutex is held.
@return io_fix state */
UNIV_INLINE
enum buf_io_fix
@@ -442,6 +442,20 @@ buf_page_get_io_fix(
/*================*/
const buf_page_t* bpage) /*!< in: pointer to the control block */
{
+ ut_ad(mutex_own(buf_page_get_mutex(bpage)));
+ return buf_page_get_io_fix_unlocked(bpage);
+}
+
+/*********************************************************************//**
+Gets the io_fix state of a block. Does not assert that the block mutex is
+held, to be used in the cases where it is safe not to hold it.
+@return io_fix state */
+UNIV_INLINE
+enum buf_io_fix
+buf_page_get_io_fix_unlocked(
+/*=========================*/
+ const buf_page_t* bpage) /*!< in: pointer to the control block */
+{
enum buf_io_fix io_fix = (enum buf_io_fix) bpage->io_fix;
#ifdef UNIV_DEBUG
switch (io_fix) {
@@ -457,7 +471,7 @@ buf_page_get_io_fix(
}
/*********************************************************************//**
-Gets the io_fix state of a block.
+Gets the io_fix state of a block. Requires that the block mutex is held.
@return io_fix state */
UNIV_INLINE
enum buf_io_fix
@@ -469,6 +483,19 @@ buf_block_get_io_fix(
}
/*********************************************************************//**
+Gets the io_fix state of a block. Does not assert that the block mutex is
+held, to be used in the cases where it is safe not to hold it.
+@return io_fix state */
+UNIV_INLINE
+enum buf_io_fix
+buf_block_get_io_fix_unlocked(
+/*==========================*/
+ const buf_block_t* block) /*!< in: pointer to the control block */
+{
+ return(buf_page_get_io_fix_unlocked(&block->page));
+}
+
+/*********************************************************************//**
Sets the io_fix state of a block. */
UNIV_INLINE
void
@@ -638,19 +665,18 @@ UNIV_INLINE
void
buf_page_set_accessed(
/*==================*/
- buf_page_t* bpage, /*!< in/out: control block */
- ulint time_ms) /*!< in: ut_time_ms() */
+ buf_page_t* bpage) /*!< in/out: control block */
{
#ifdef UNIV_DEBUG
- //buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
- //ut_ad(buf_pool_mutex_own(buf_pool));
-#endif
+ buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
+ ut_ad(!buf_pool_mutex_own(buf_pool));
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
+#endif
ut_a(buf_page_in_file(bpage));
if (!bpage->access_time) {
/* Make this the time of the first access. */
- bpage->access_time = time_ms;
+ bpage->access_time = ut_time_ms();
}
}
diff --git a/storage/xtradb/include/buf0lru.h b/storage/xtradb/include/buf0lru.h
index efaa758f27a..2ea4f9b1ecf 100644
--- a/storage/xtradb/include/buf0lru.h
+++ b/storage/xtradb/include/buf0lru.h
@@ -158,7 +158,10 @@ buf_LRU_block_free_non_file_page(
buf_block_t* block, /*!< in: block, must not contain a file page */
ibool have_page_hash_mutex);
/******************************************************************//**
-Adds a block to the LRU list. */
+Adds a block to the LRU list. Please make sure that the zip_size is
+already set into the page zip when invoking the function, so that we
+can get correct zip_size from the buffer page when adding a block
+into LRU */
UNIV_INTERN
void
buf_LRU_add_block(
diff --git a/storage/xtradb/include/data0type.ic b/storage/xtradb/include/data0type.ic
index 757dd815c5e..7ec2cb6cf36 100644
--- a/storage/xtradb/include/data0type.ic
+++ b/storage/xtradb/include/data0type.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -459,36 +459,18 @@ dtype_get_fixed_size_low(
} else if (!comp) {
return(len);
} else {
- /* We play it safe here and ask MySQL for
- mbminlen and mbmaxlen. Although
- mbminlen and mbmaxlen are
- initialized if and only if prtype
- is (in one of the 3 functions in this file),
- it could be that none of these functions
- has been called. */
-
+#ifdef UNIV_DEBUG
ulint i_mbminlen, i_mbmaxlen;
innobase_get_cset_width(
dtype_get_charset_coll(prtype),
&i_mbminlen, &i_mbmaxlen);
- if (UNIV_UNLIKELY
- (DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen)
- != mbminmaxlen)) {
-
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: "
- "mbminlen=%lu, "
- "mbmaxlen=%lu, "
- "type->mbminlen=%lu, "
- "type->mbmaxlen=%lu\n",
- (ulong) i_mbminlen,
- (ulong) i_mbmaxlen,
- (ulong) DATA_MBMINLEN(mbminmaxlen),
- (ulong) DATA_MBMAXLEN(mbminmaxlen));
- }
- if (i_mbminlen == i_mbmaxlen) {
+ ut_ad(DATA_MBMINMAXLEN(i_mbminlen, i_mbmaxlen)
+ == mbminmaxlen);
+#endif /* UNIV_DEBUG */
+ if (DATA_MBMINLEN(mbminmaxlen)
+ == DATA_MBMAXLEN(mbminmaxlen)) {
return(len);
}
}
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index de3605b1dfb..1dd0b3f5082 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -903,7 +903,7 @@ dict_index_get_nth_col_no(
Looks for column n in an index.
@return position in internal representation of the index;
ULINT_UNDEFINED if not contained */
-UNIV_INLINE
+UNIV_INTERN
ulint
dict_index_get_nth_col_pos(
/*=======================*/
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index 02eafcc5d9c..eeb916fe181 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -697,20 +697,6 @@ dict_index_get_nth_col_no(
return(dict_col_get_no(dict_index_get_nth_col(index, pos)));
}
-/********************************************************************//**
-Looks for column n in an index.
-@return position in internal representation of the index;
-ULINT_UNDEFINED if not contained */
-UNIV_INLINE
-ulint
-dict_index_get_nth_col_pos(
-/*=======================*/
- const dict_index_t* index, /*!< in: index */
- ulint n) /*!< in: column number */
-{
- return(dict_index_get_nth_col_or_prefix_pos(index, n, FALSE));
-}
-
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Returns the minimum data size of an index record.
diff --git a/storage/xtradb/include/dict0mem.h b/storage/xtradb/include/dict0mem.h
index 50c6e1ee142..4ba09caae7f 100644
--- a/storage/xtradb/include/dict0mem.h
+++ b/storage/xtradb/include/dict0mem.h
@@ -380,10 +380,15 @@ struct dict_index_struct{
unsigned type:DICT_IT_BITS;
/*!< index type (DICT_CLUSTERED, DICT_UNIQUE,
DICT_UNIVERSAL, DICT_IBUF, DICT_CORRUPT) */
- unsigned trx_id_offset:10;/*!< position of the trx id column
+#define MAX_KEY_LENGTH_BITS 12
+ unsigned trx_id_offset:MAX_KEY_LENGTH_BITS;
+ /*!< position of the trx id column
in a clustered index record, if the fields
before it are known to be of a fixed size,
0 otherwise */
+#if (1<<MAX_KEY_LENGTH_BITS) < MAX_KEY_LENGTH
+# error (1<<MAX_KEY_LENGTH_BITS) < MAX_KEY_LENGTH
+#endif
unsigned n_user_defined_cols:10;
/*!< number of columns the user defined to
be in the index: in the internal
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 7da62e68e56..2149d0aadca 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -776,6 +776,21 @@ fil_space_set_corrupt(
/*==================*/
ulint space_id);
+/****************************************************************//**
+Generate redo logs for swapping two .ibd files */
+UNIV_INTERN
+void
+fil_mtr_rename_log(
+/*===============*/
+ ulint old_space_id, /*!< in: tablespace id of the old
+ table. */
+ const char* old_name, /*!< in: old table name */
+ ulint new_space_id, /*!< in: tablespace id of the new
+ table */
+ const char* new_name, /*!< in: new table name */
+ const char* tmp_name); /*!< in: temp table name used while
+ swapping */
+
typedef struct fil_space_struct fil_space_t;
#endif
diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h
index f7c3d82e495..67a4cc2eb68 100644
--- a/storage/xtradb/include/lock0lock.h
+++ b/storage/xtradb/include/lock0lock.h
@@ -798,15 +798,20 @@ lock_rec_get_page_no(
remains set when the waiting lock is granted,
or if the lock is inherited to a neighboring
record */
-#define WSREP_BF 4096
-#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_MODE_MASK
-# error
-#endif
-#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_TYPE_MASK
+#define LOCK_CONV_BY_OTHER 4096 /*!< this bit is set when the lock is created
+ by other transaction */
+#define WSREP_BF 8192
+#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_CONV_BY_OTHER)&LOCK_TYPE_MASK
# error
#endif
/* @} */
+/** Checks if this is a waiting lock created by lock->trx itself.
+@param type_mode lock->type_mode
+@return whether it is a waiting lock belonging to lock->trx */
+#define lock_is_wait_not_by_other(type_mode) \
+ ((type_mode & (LOCK_CONV_BY_OTHER | LOCK_WAIT)) == LOCK_WAIT)
+
/** Lock operation struct */
typedef struct lock_op_struct lock_op_t;
/** Lock operation struct */
diff --git a/storage/xtradb/include/log0online.h b/storage/xtradb/include/log0online.h
index e7c3f301e45..999a317780e 100644
--- a/storage/xtradb/include/log0online.h
+++ b/storage/xtradb/include/log0online.h
@@ -41,23 +41,51 @@ typedef struct log_bitmap_iterator_struct log_bitmap_iterator_t;
Initializes the online log following subsytem. */
UNIV_INTERN
void
-log_online_read_init();
-/*===================*/
+log_online_read_init(void);
+/*=======================*/
/*********************************************************************//**
Shuts down the online log following subsystem. */
UNIV_INTERN
void
-log_online_read_shutdown();
-/*=======================*/
+log_online_read_shutdown(void);
+/*===========================*/
/*********************************************************************//**
Reads and parses the redo log up to last checkpoint LSN to build the changed
-page bitmap which is then written to disk. */
+page bitmap which is then written to disk.
+
+@return TRUE if log tracking succeeded, FALSE if bitmap write I/O error */
UNIV_INTERN
-void
-log_online_follow_redo_log();
-/*=========================*/
+ibool
+log_online_follow_redo_log(void);
+/*=============================*/
+
+/************************************************************//**
+Delete all the bitmap files for data less than the specified LSN.
+If called with lsn == 0 (i.e. set by RESET request) or
+IB_ULONGLONG_MAX, restart the bitmap file sequence, otherwise
+continue it.
+
+@return FALSE to indicate success, TRUE for failure. */
+UNIV_INTERN
+ibool
+log_online_purge_changed_page_bitmaps(
+/*==================================*/
+ ib_uint64_t lsn); /*!<in: LSN to purge files up to */
+
+/************************************************************//**
+Delete all the bitmap files for data less than the specified LSN.
+If called with lsn == 0 (i.e. set by RESET request) or
+IB_ULONGLONG_MAX, restart the bitmap file sequence, otherwise
+continue it.
+
+@return FALSE to indicate success, TRUE for failure. */
+UNIV_INTERN
+ibool
+log_online_purge_changed_page_bitmaps(
+/*==================================*/
+ ib_uint64_t lsn); /*!<in: LSN to purge files up to */
#define LOG_BITMAP_ITERATOR_START_LSN(i) \
((i).start_lsn)
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index 4c795d93141..05403a8e752 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -190,6 +190,8 @@ extern ulint os_n_file_reads;
extern ulint os_n_file_writes;
extern ulint os_n_fsyncs;
+#define OS_MIN_LOG_BLOCK_SIZE 512
+
extern ulint srv_log_block_size;
#ifdef UNIV_PFS_IO
diff --git a/storage/xtradb/include/page0zip.h b/storage/xtradb/include/page0zip.h
index fe3d2e52e0b..23a2cac618b 100644
--- a/storage/xtradb/include/page0zip.h
+++ b/storage/xtradb/include/page0zip.h
@@ -156,9 +156,10 @@ page_zip_validate_low(
/*==================*/
const page_zip_des_t* page_zip,/*!< in: compressed page */
const page_t* page, /*!< in: uncompressed page */
+ const dict_index_t* index, /*!< in: index of the page, if known */
ibool sloppy) /*!< in: FALSE=strict,
TRUE=ignore the MIN_REC_FLAG */
- __attribute__((nonnull));
+ __attribute__((nonnull(1,2)));
/**********************************************************************//**
Check that the compressed and decompressed pages match. */
UNIV_INTERN
@@ -166,8 +167,9 @@ ibool
page_zip_validate(
/*==============*/
const page_zip_des_t* page_zip,/*!< in: compressed page */
- const page_t* page) /*!< in: uncompressed page */
- __attribute__((nonnull));
+ const page_t* page, /*!< in: uncompressed page */
+ const dict_index_t* index) /*!< in: index of the page, if known */
+ __attribute__((nonnull(1,2)));
#endif /* UNIV_ZIP_DEBUG */
/**********************************************************************//**
diff --git a/storage/xtradb/include/rem0rec.h b/storage/xtradb/include/rem0rec.h
index e2af5998899..5687f51d985 100644
--- a/storage/xtradb/include/rem0rec.h
+++ b/storage/xtradb/include/rem0rec.h
@@ -362,24 +362,6 @@ rec_get_offsets_func(
rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__)
/******************************************************//**
-Determine the offset to each field in a leaf-page record
-in ROW_FORMAT=COMPACT. This is a special case of
-rec_init_offsets() and rec_get_offsets_func(). */
-UNIV_INTERN
-void
-rec_init_offsets_comp_ordinary(
-/*===========================*/
- const rec_t* rec, /*!< in: physical record in
- ROW_FORMAT=COMPACT */
- ulint extra, /*!< in: number of bytes to reserve
- between the record header and
- the data payload
- (usually REC_N_NEW_EXTRA_BYTES) */
- const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets);/*!< in/out: array of offsets;
- in: n=rec_offs_n_fields(offsets) */
-
-/******************************************************//**
The following function determines the offsets to each field
in the record. It can reuse a previously allocated array. */
UNIV_INTERN
@@ -644,8 +626,48 @@ rec_copy(
/*=====*/
void* buf, /*!< in: buffer */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets);/*!< in: array returned by rec_get_offsets() */
+ const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ __attribute__((nonnull));
#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
+Determines the size of a data tuple prefix in a temporary file.
+@return total size */
+UNIV_INTERN
+ulint
+rec_get_converted_size_temp(
+/*========================*/
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra) /*!< out: extra size */
+ __attribute__((warn_unused_result, nonnull));
+
+/******************************************************//**
+Determine the offset to each field in temporary file.
+@see rec_convert_dtuple_to_temp() */
+UNIV_INTERN
+void
+rec_init_offsets_temp(
+/*==================*/
+ const rec_t* rec, /*!< in: temporary file record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets)/*!< in/out: array of offsets;
+ in: n=rec_offs_n_fields(offsets) */
+ __attribute__((nonnull));
+
+/*********************************************************//**
+Builds a temporary file record out of a data tuple.
+@see rec_init_offsets_temp() */
+UNIV_INTERN
+void
+rec_convert_dtuple_to_temp(
+/*=======================*/
+ rec_t* rec, /*!< out: record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields) /*!< in: number of fields */
+ __attribute__((nonnull));
+
/**************************************************************//**
Copies the first n fields of a physical record to a new physical record in
a buffer.
@@ -680,21 +702,6 @@ rec_fold(
__attribute__((pure));
#endif /* !UNIV_HOTBACKUP */
/*********************************************************//**
-Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
-UNIV_INTERN
-void
-rec_convert_dtuple_to_rec_comp(
-/*===========================*/
- rec_t* rec, /*!< in: origin of record */
- ulint extra, /*!< in: number of bytes to
- reserve between the record
- header and the data payload
- (normally REC_N_NEW_EXTRA_BYTES) */
- const dict_index_t* index, /*!< in: record descriptor */
- ulint status, /*!< in: status bits of the record */
- const dfield_t* fields, /*!< in: array of data fields */
- ulint n_fields);/*!< in: number of data fields */
-/*********************************************************//**
Builds a physical record out of a data tuple and
stores it into the given buffer.
@return pointer to the origin of physical record */
@@ -727,10 +734,7 @@ UNIV_INTERN
ulint
rec_get_converted_size_comp_prefix(
/*===============================*/
- const dict_index_t* index, /*!< in: record descriptor;
- dict_table_is_comp() is
- assumed to hold, even if
- it does not */
+ const dict_index_t* index, /*!< in: record descriptor */
const dfield_t* fields, /*!< in: array of data fields */
ulint n_fields,/*!< in: number of data fields */
ulint* extra); /*!< out: extra size */
diff --git a/storage/xtradb/include/row0undo.h b/storage/xtradb/include/row0undo.h
index 6eb4ca448b3..9420d022e3b 100644
--- a/storage/xtradb/include/row0undo.h
+++ b/storage/xtradb/include/row0undo.h
@@ -87,10 +87,6 @@ that index record. */
enum undo_exec {
UNDO_NODE_FETCH_NEXT = 1, /*!< we should fetch the next
undo log record */
- UNDO_NODE_PREV_VERS, /*!< the roll ptr to previous
- version of a row is stored in
- node, and undo should be done
- based on it */
UNDO_NODE_INSERT, /*!< undo a fresh insert of a
row to a table */
UNDO_NODE_MODIFY /*!< undo a modify operation
@@ -108,9 +104,6 @@ struct undo_node_struct{
undo_no_t undo_no;/*!< undo number of the record */
ulint rec_type;/*!< undo log record type: TRX_UNDO_INSERT_REC,
... */
- roll_ptr_t new_roll_ptr;
- /*!< roll ptr to restore to clustered index
- record */
trx_id_t new_trx_id; /*!< trx id to restore to clustered index
record */
btr_pcur_t pcur; /*!< persistent cursor used in searching the
diff --git a/storage/xtradb/include/row0upd.ic b/storage/xtradb/include/row0upd.ic
index 10646241125..6706c9f8c69 100644
--- a/storage/xtradb/include/row0upd.ic
+++ b/storage/xtradb/include/row0upd.ic
@@ -28,6 +28,7 @@ Created 12/27/1996 Heikki Tuuri
# include "trx0trx.h"
# include "trx0undo.h"
# include "row0row.h"
+# include "lock0lock.h"
#endif /* !UNIV_HOTBACKUP */
#include "page0zip.h"
@@ -171,6 +172,8 @@ row_upd_rec_sys_fields(
#if DATA_TRX_ID + 1 != DATA_ROLL_PTR
# error "DATA_TRX_ID + 1 != DATA_ROLL_PTR"
#endif
+ ut_ad(lock_check_trx_id_sanity(trx_read_trx_id(rec + offset),
+ rec, index, offsets, FALSE));
trx_write_trx_id(rec + offset, trx->id);
trx_write_roll_ptr(rec + offset + DATA_TRX_ID_LEN, roll_ptr);
}
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 6f0b53ef2ba..f5573c64f75 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -148,7 +148,7 @@ extern my_bool srv_track_changed_pages;
extern ib_uint64_t srv_max_bitmap_file_size;
extern
-ulonglong srv_changed_pages_limit;
+ulonglong srv_max_changed_pages;
extern ibool srv_auto_extend_last_data_file;
extern ulint srv_last_file_size_max;
@@ -324,6 +324,10 @@ extern ulint srv_fatal_semaphore_wait_threshold;
extern ulint srv_dml_needed_delay;
extern long long srv_kill_idle_transaction;
+#ifdef UNIV_DEBUG
+extern my_bool srv_purge_view_update_only_debug;
+#endif /* UNIV_DEBUG */
+
extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs,
query threads, and lock table: we allocate
it from dynamic memory to get it to the
@@ -404,6 +408,9 @@ extern ibool srv_blocking_lru_restore;
When FALSE, row locks are not taken at all. */
extern my_bool srv_fake_changes_locks;
+/** print all user-level transactions deadlocks to mysqld stderr */
+extern my_bool srv_print_all_deadlocks;
+
/** Status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
@@ -806,7 +813,9 @@ struct export_var_struct{
ulint innodb_dict_tables;
ulint innodb_buffer_pool_pages_total; /*!< Buffer pool size */
ulint innodb_buffer_pool_pages_data; /*!< Data pages */
+ ulint innodb_buffer_pool_bytes_data; /*!< File bytes used */
ulint innodb_buffer_pool_pages_dirty; /*!< Dirty data pages */
+ ulint innodb_buffer_pool_bytes_dirty; /*!< File bytes modified */
ulint innodb_buffer_pool_pages_misc; /*!< Miscellanous pages */
ulint innodb_buffer_pool_pages_free; /*!< Free pages */
#ifdef UNIV_DEBUG
@@ -892,6 +901,11 @@ struct export_var_struct{
ib_int64_t innodb_x_lock_os_waits;
ib_int64_t innodb_x_lock_spin_rounds;
ib_int64_t innodb_x_lock_spin_waits;
+#ifdef UNIV_DEBUG
+ ulint innodb_purge_trx_id_age; /*!< max_trx_id - purged trx_id */
+ ulint innodb_purge_view_trx_id_age; /*!< rw_max_trx_id
+ - purged view's min trx_id */
+#endif /* UNIV_DEBUG */
};
/** Thread slot in the thread table */
diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h
index 4a2f55d90ff..b3b99b10630 100644
--- a/storage/xtradb/include/sync0sync.h
+++ b/storage/xtradb/include/sync0sync.h
@@ -89,6 +89,7 @@ extern mysql_pfs_key_t hash_table_mutex_key;
extern mysql_pfs_key_t ibuf_bitmap_mutex_key;
extern mysql_pfs_key_t ibuf_mutex_key;
extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key;
+extern mysql_pfs_key_t log_bmp_sys_mutex_key;
extern mysql_pfs_key_t log_sys_mutex_key;
extern mysql_pfs_key_t log_flush_order_mutex_key;
extern mysql_pfs_key_t kernel_mutex_key;
@@ -672,6 +673,7 @@ or row lock! */
#define SYNC_TRX_LOCK_HEAP 298
#define SYNC_TRX_SYS_HEADER 290
#define SYNC_PURGE_QUEUE 200
+#define SYNC_LOG_ONLINE 175
#define SYNC_LOG 170
#define SYNC_LOG_FLUSH_ORDER 156
#define SYNC_RECV 168
diff --git a/storage/xtradb/include/trx0purge.h b/storage/xtradb/include/trx0purge.h
index 2bd9e64476b..1e8acd65e01 100644
--- a/storage/xtradb/include/trx0purge.h
+++ b/storage/xtradb/include/trx0purge.h
@@ -156,6 +156,10 @@ struct trx_purge_struct{
than this */
undo_no_t purge_undo_no; /*!< Purge has advanced past all records
whose undo number is less than this */
+#ifdef UNIV_DEBUG
+ trx_id_t done_trx_no; /* Indicate 'purge pointer' which have
+ purged already accurately. */
+#endif /* UNIV_DEBUG */
/*-----------------------------*/
ibool next_stored; /*!< TRUE if the info of the next record
to purge is stored below: if yes, then
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index 77acf54d8dc..60c5cc79852 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -49,13 +49,10 @@ Created 1/20/1994 Heikki Tuuri
#define _IB_TO_STR(s) #s
#define IB_TO_STR(s) _IB_TO_STR(s)
-#define INNODB_VERSION_MAJOR 1
-#define INNODB_VERSION_MINOR 1
-#define INNODB_VERSION_BUGFIX 8
+#include <mysql_version.h>
-#ifndef PERCONA_INNODB_VERSION
-#define PERCONA_INNODB_VERSION 29.3
-#endif
+#define INNODB_VERSION_MAJOR MYSQL_MAJOR_VERSION
+#define INNODB_VERSION_MINOR MYSQL_MINOR_VERSION
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
@@ -66,11 +63,11 @@ component, i.e. we show M.N.P as M.N */
#define INNODB_VERSION_SHORT \
(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
-#define INNODB_VERSION_STR \
- IB_TO_STR(INNODB_VERSION_MAJOR) "." \
- IB_TO_STR(INNODB_VERSION_MINOR) "." \
- IB_TO_STR(INNODB_VERSION_BUGFIX) "-" \
- IB_TO_STR(PERCONA_INNODB_VERSION)
+#ifndef PERCONA_INNODB_VERSION
+#define PERCONA_INNODB_VERSION 30.1
+#endif
+
+#define INNODB_VERSION_STR MYSQL_SERVER_VERSION "-" IB_TO_STR(PERCONA_INNODB_VERSION)
#define REFMAN "http://dev.mysql.com/doc/refman/" \
IB_TO_STR(MYSQL_MAJOR_VERSION) "." \
@@ -300,6 +297,24 @@ management to ensure correct alignment for doubles etc. */
========================
*/
+/** There are currently two InnoDB file formats which are used to group
+features with similar restrictions and dependencies. Using an enum allows
+switch statements to give a compiler warning when a new one is introduced. */
+enum innodb_file_formats_enum {
+ /** Antelope File Format: InnoDB/MySQL up to 5.1.
+ This format includes REDUNDANT and COMPACT row formats */
+ UNIV_FORMAT_A = 0,
+
+ /** Barracuda File Format: Introduced in InnoDB plugin for 5.1:
+ This format includes COMPRESSED and DYNAMIC row formats. It
+ includes the ability to create secondary indexes from data that
+ is not on the clustered index page and the ability to store more
+ data off the clustered index page. */
+ UNIV_FORMAT_B = 1
+};
+
+typedef enum innodb_file_formats_enum innodb_file_formats_t;
+
/* The 2-logarithm of UNIV_PAGE_SIZE: */
/* #define UNIV_PAGE_SIZE_SHIFT 14 */
#define UNIV_PAGE_SIZE_SHIFT_MAX 14
diff --git a/storage/xtradb/lock/lock0lock.c b/storage/xtradb/lock/lock0lock.c
index 1dea0acdf59..3d97def3750 100644
--- a/storage/xtradb/lock/lock0lock.c
+++ b/storage/xtradb/lock/lock0lock.c
@@ -793,12 +793,16 @@ lock_reset_lock_and_trx_wait(
/*=========================*/
lock_t* lock) /*!< in: record lock */
{
- ut_ad((lock->trx)->wait_lock == lock);
ut_ad(lock_get_wait(lock));
/* Reset the back pointer in trx to this waiting lock request */
- (lock->trx)->wait_lock = NULL;
+ if (!(lock->type_mode & LOCK_CONV_BY_OTHER)) {
+ ut_ad((lock->trx)->wait_lock == lock);
+ (lock->trx)->wait_lock = NULL;
+ } else {
+ ut_ad(lock_get_type_low(lock) == LOCK_REC);
+ }
lock->type_mode &= ~LOCK_WAIT;
}
@@ -1439,9 +1443,9 @@ lock_rec_has_expl(
while (lock) {
if (lock->trx == trx
+ && !lock_is_wait_not_by_other(lock->type_mode)
&& lock_mode_stronger_or_eq(lock_get_mode(lock),
precise_mode & LOCK_MODE_MASK)
- && !lock_get_wait(lock)
&& (!lock_rec_get_rec_not_gap(lock)
|| (precise_mode & LOCK_REC_NOT_GAP)
|| heap_no == PAGE_HEAP_NO_SUPREMUM)
@@ -1835,9 +1839,9 @@ lock_rec_create(
HASH_INSERT(lock_t, hash, lock_sys->rec_hash,
lock_rec_fold(space, page_no), lock);
#endif
- lock_sys->rec_num++;
- if (UNIV_UNLIKELY(type_mode & LOCK_WAIT)) {
+ lock_sys->rec_num++;
+ if (lock_is_wait_not_by_other(type_mode)) {
lock_set_lock_and_trx_wait(lock, trx);
}
@@ -1870,10 +1874,11 @@ lock_rec_enqueue_waiting(
const buf_block_t* block, /*!< in: buffer block containing
the record */
ulint heap_no,/*!< in: heap number of the record */
+ lock_t* lock, /*!< in: lock object; NULL if a new
+ one should be created. */
dict_index_t* index, /*!< in: index of record */
que_thr_t* thr) /*!< in: query thread */
{
- lock_t* lock;
trx_t* trx;
ulint sec;
ulint ms;
@@ -1910,17 +1915,26 @@ lock_rec_enqueue_waiting(
ut_ad(0);
}
- /* Enqueue the lock request that will wait to be granted */
+ if (lock == NULL) {
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) && trx->was_chosen_as_deadlock_victim) {
- return(DB_DEADLOCK);
- }
- lock = lock_rec_create(c_lock, type_mode | LOCK_WAIT,
- block, heap_no, index, trx);
+ if (wsrep_on(trx->mysql_thd) && trx->was_chosen_as_deadlock_victim) {
+ return(DB_DEADLOCK);
+ }
+ /* Enqueue the lock request that will wait to be granted */
+ lock = lock_rec_create(c_lock, type_mode | LOCK_WAIT,
+ block, heap_no, index, trx);
#else
- lock = lock_rec_create(type_mode | LOCK_WAIT,
- block, heap_no, index, trx);
-#endif
+ /* Enqueue the lock request that will wait to be granted */
+ lock = lock_rec_create(type_mode | LOCK_WAIT,
+ block, heap_no, index, trx);
+#endif /*WITH_WSREP */
+ } else {
+ ut_ad(lock->type_mode & LOCK_WAIT);
+ ut_ad(lock->type_mode & LOCK_CONV_BY_OTHER);
+
+ lock->type_mode &= ~LOCK_CONV_BY_OTHER;
+ lock_set_lock_and_trx_wait(lock, trx);
+ }
/* Check if a deadlock occurs: if yes, remove the lock request and
return an error code */
@@ -1944,7 +1958,7 @@ lock_rec_enqueue_waiting(
trx->que_state = TRX_QUE_LOCK_WAIT;
trx->was_chosen_as_deadlock_victim = FALSE;
trx->wait_started = time(NULL);
- if (innobase_get_slow_log() && trx->take_stats) {
+ if (UNIV_UNLIKELY(trx->take_stats)) {
ut_usectime(&sec, &ms);
trx->lock_que_wait_ustarted = (ib_uint64_t)sec * 1000000 + ms;
}
@@ -2197,6 +2211,7 @@ lock_rec_lock_slow(
#ifdef WITH_WSREP
lock_t *c_lock;
#endif
+ lock_t* lock;
ut_ad(mutex_own(&kernel_mutex));
ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
@@ -2216,7 +2231,27 @@ lock_rec_lock_slow(
trx = thr_get_trx(thr);
- if (lock_rec_has_expl(mode, block, heap_no, trx)) {
+ lock = lock_rec_has_expl(mode, block, heap_no, trx);
+ if (lock) {
+ if (lock->type_mode & LOCK_CONV_BY_OTHER) {
+ /* This lock or lock waiting was created by the other
+ transaction, not by the transaction (trx) itself.
+ So, the transaction (trx) should treat it collectly
+ according as whether granted or not. */
+
+ if (lock->type_mode & LOCK_WAIT) {
+ /* This lock request was not granted yet.
+ Should wait for granted. */
+
+ goto enqueue_waiting;
+ } else {
+ /* This lock request was already granted.
+ Just clearing the flag. */
+
+ lock->type_mode &= ~LOCK_CONV_BY_OTHER;
+ }
+ }
+
/* The trx already has a strong enough lock on rec: do
nothing */
@@ -2231,12 +2266,14 @@ lock_rec_lock_slow(
the queue, as this transaction does not have a lock strong
enough already granted on the record, we have to wait. */
+ ut_ad(lock == NULL);
+enqueue_waiting:
#ifdef WITH_WSREP
return(lock_rec_enqueue_waiting(c_lock,mode, block, heap_no,
- index, thr));
+ lock, index, thr));
#else
return(lock_rec_enqueue_waiting(mode, block, heap_no,
- index, thr));
+ lock, index, thr));
#endif
} else if (!impl) {
/* Set the requested lock on the record */
@@ -2388,7 +2425,8 @@ lock_grant(
TRX_QUE_LOCK_WAIT state, and there is no need to end the lock wait
for it */
- if (lock->trx->que_state == TRX_QUE_LOCK_WAIT) {
+ if (!(lock->type_mode & LOCK_CONV_BY_OTHER)
+ && lock->trx->que_state == TRX_QUE_LOCK_WAIT) {
trx_end_lock_wait(lock->trx);
}
}
@@ -2405,6 +2443,7 @@ lock_rec_cancel(
{
ut_ad(mutex_own(&kernel_mutex));
ut_ad(lock_get_type_low(lock) == LOCK_REC);
+ ut_ad(!(lock->type_mode & LOCK_CONV_BY_OTHER));
/* Reset the bit (there can be only one set bit) in the lock bitmap */
lock_rec_reset_nth_bit(lock, lock_rec_find_set_bit(lock));
@@ -2549,8 +2588,12 @@ lock_rec_reset_and_release_wait(
lock = lock_rec_get_first(block, heap_no);
while (lock != NULL) {
- if (lock_get_wait(lock)) {
+ if (lock_is_wait_not_by_other(lock->type_mode)) {
lock_rec_cancel(lock);
+ } else if (lock_get_wait(lock)) {
+ /* just reset LOCK_WAIT */
+ lock_rec_reset_nth_bit(lock, heap_no);
+ lock_reset_lock_and_trx_wait(lock);
} else {
lock_rec_reset_nth_bit(lock, heap_no);
}
@@ -3438,6 +3481,80 @@ lock_rec_restore_from_page_infimum(
/*=========== DEADLOCK CHECKING ======================================*/
+/*********************************************************************//**
+rewind(3) the file used for storing the latest detected deadlock and
+print a heading message to stderr if printing of all deadlocks to stderr
+is enabled. */
+UNIV_INLINE
+void
+lock_deadlock_start_print()
+/*=======================*/
+{
+ rewind(lock_latest_err_file);
+ ut_print_timestamp(lock_latest_err_file);
+
+ if (srv_print_all_deadlocks) {
+ fprintf(stderr, "InnoDB: transactions deadlock detected, "
+ "dumping detailed information.\n");
+ ut_print_timestamp(stderr);
+ }
+}
+
+/*********************************************************************//**
+Print a message to the deadlock file and possibly to stderr. */
+UNIV_INLINE
+void
+lock_deadlock_fputs(
+/*================*/
+ const char* msg) /*!< in: message to print */
+{
+ fputs(msg, lock_latest_err_file);
+
+ if (srv_print_all_deadlocks) {
+ fputs(msg, stderr);
+ }
+}
+
+/*********************************************************************//**
+Print transaction data to the deadlock file and possibly to stderr. */
+UNIV_INLINE
+void
+lock_deadlock_trx_print(
+/*====================*/
+ trx_t* trx, /*!< in: transaction */
+ ulint max_query_len) /*!< in: max query length to print, or 0 to
+ use the default max length */
+{
+ trx_print(lock_latest_err_file, trx, max_query_len);
+
+ if (srv_print_all_deadlocks) {
+ trx_print(stderr, trx, max_query_len);
+ }
+}
+
+/*********************************************************************//**
+Print lock data to the deadlock file and possibly to stderr. */
+UNIV_INLINE
+void
+lock_deadlock_lock_print(
+/*=====================*/
+ const lock_t* lock) /*!< in: record or table type lock */
+{
+ if (lock_get_type_low(lock) == LOCK_REC) {
+ lock_rec_print(lock_latest_err_file, lock);
+
+ if (srv_print_all_deadlocks) {
+ lock_rec_print(stderr, lock);
+ }
+ } else {
+ lock_table_print(lock_latest_err_file, lock);
+
+ if (srv_print_all_deadlocks) {
+ lock_table_print(stderr, lock);
+ }
+ }
+}
+
/********************************************************************//**
Checks if a lock request results in a deadlock.
@return TRUE if a deadlock was detected and we chose trx as a victim;
@@ -3481,31 +3598,26 @@ retry:
/* If the lock search exceeds the max step
or the max depth, the current trx will be
the victim. Print its information. */
- rewind(lock_latest_err_file);
- ut_print_timestamp(lock_latest_err_file);
+ lock_deadlock_start_print();
- fputs("TOO DEEP OR LONG SEARCH IN THE LOCK TABLE"
- " WAITS-FOR GRAPH, WE WILL ROLL BACK"
- " FOLLOWING TRANSACTION \n",
- lock_latest_err_file);
+ lock_deadlock_fputs(
+ "TOO DEEP OR LONG SEARCH IN THE LOCK TABLE"
+ " WAITS-FOR GRAPH, WE WILL ROLL BACK"
+ " FOLLOWING TRANSACTION \n\n"
+ "*** TRANSACTION:\n");
- fputs("\n*** TRANSACTION:\n", lock_latest_err_file);
- trx_print(lock_latest_err_file, trx, 3000);
+ lock_deadlock_trx_print(trx, 3000);
- fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n",
- lock_latest_err_file);
+ lock_deadlock_fputs(
+ "*** WAITING FOR THIS LOCK TO BE GRANTED:\n");
+
+ lock_deadlock_lock_print(lock);
- if (lock_get_type(lock) == LOCK_REC) {
- lock_rec_print(lock_latest_err_file, lock);
- } else {
- lock_table_print(lock_latest_err_file, lock);
- }
break;
case LOCK_VICTIM_IS_START:
srv_n_lock_deadlock_count++;
- fputs("*** WE ROLL BACK TRANSACTION (2)\n",
- lock_latest_err_file);
+ lock_deadlock_fputs("*** WE ROLL BACK TRANSACTION (2)\n");
break;
default:
@@ -3620,45 +3732,33 @@ lock_deadlock_recursive(
point: a deadlock detected; or we have
searched the waits-for graph too long */
- FILE* ef = lock_latest_err_file;
+ lock_deadlock_start_print();
- rewind(ef);
- ut_print_timestamp(ef);
+ lock_deadlock_fputs("\n*** (1) TRANSACTION:\n");
- fputs("\n*** (1) TRANSACTION:\n", ef);
+ lock_deadlock_trx_print(wait_lock->trx, 3000);
- trx_print(ef, wait_lock->trx, 3000);
+ lock_deadlock_fputs(
+ "*** (1) WAITING FOR THIS LOCK"
+ " TO BE GRANTED:\n");
- fputs("*** (1) WAITING FOR THIS LOCK"
- " TO BE GRANTED:\n", ef);
+ lock_deadlock_lock_print(wait_lock);
- if (lock_get_type_low(wait_lock) == LOCK_REC) {
- lock_rec_print(ef, wait_lock);
- } else {
- lock_table_print(ef, wait_lock);
- }
+ lock_deadlock_fputs("*** (2) TRANSACTION:\n");
- fputs("*** (2) TRANSACTION:\n", ef);
+ lock_deadlock_trx_print(lock->trx, 3000);
- trx_print(ef, lock->trx, 3000);
+ lock_deadlock_fputs(
+ "*** (2) HOLDS THE LOCK(S):\n");
- fputs("*** (2) HOLDS THE LOCK(S):\n", ef);
+ lock_deadlock_lock_print(lock);
- if (lock_get_type_low(lock) == LOCK_REC) {
- lock_rec_print(ef, lock);
- } else {
- lock_table_print(ef, lock);
- }
+ lock_deadlock_fputs(
+ "*** (2) WAITING FOR THIS LOCK"
+ " TO BE GRANTED:\n");
- fputs("*** (2) WAITING FOR THIS LOCK"
- " TO BE GRANTED:\n", ef);
+ lock_deadlock_lock_print(start->wait_lock);
- if (lock_get_type_low(start->wait_lock)
- == LOCK_REC) {
- lock_rec_print(ef, start->wait_lock);
- } else {
- lock_table_print(ef, start->wait_lock);
- }
#ifdef UNIV_DEBUG
if (lock_print_waits) {
fputs("Deadlock detected\n",
@@ -3667,7 +3767,7 @@ lock_deadlock_recursive(
#endif /* UNIV_DEBUG */
#ifdef WITH_WSREP
if (wsrep_debug)
- fputs("WSREP: Deadlock detected\n", ef);
+ fputs("WSREP: Deadlock detected\n", stderr);
if (wsrep_thd_is_brute_force(start->mysql_thd) &&
wsrep_thd_is_brute_force(
wait_lock->trx->mysql_thd) &&
@@ -3685,14 +3785,6 @@ lock_deadlock_recursive(
}
}
#endif
- if (too_far) {
-
- fputs("TOO DEEP OR LONG SEARCH"
- " IN THE LOCK TABLE"
- " WAITS-FOR GRAPH\n", ef);
-
- return(LOCK_VICTIM_IS_START);
- }
if (trx_weight_ge(wait_lock->trx, start)) {
/* Our recursion starting point
@@ -3722,8 +3814,8 @@ lock_deadlock_recursive(
as a victim to try to avoid deadlocking our
recursion starting point transaction */
- fputs("*** WE ROLL BACK TRANSACTION (1)\n",
- ef);
+ lock_deadlock_fputs(
+ "*** WE ROLL BACK TRANSACTION (1)\n");
wait_lock->trx->was_chosen_as_deadlock_victim
= TRUE;
@@ -3811,6 +3903,7 @@ lock_table_create(
ut_ad(table && trx);
ut_ad(mutex_own(&kernel_mutex));
+ ut_ad(!(type_mode & LOCK_CONV_BY_OTHER));
if ((type_mode & LOCK_MODE_MASK) == LOCK_AUTO_INC) {
++table->n_waiting_or_granted_auto_inc_locks;
@@ -4076,7 +4169,7 @@ lock_table_enqueue_waiting(
return(DB_SUCCESS);
}
- if (innobase_get_slow_log() && trx->take_stats) {
+ if (UNIV_UNLIKELY(trx->take_stats)) {
ut_usectime(&sec, &ms);
trx->lock_que_wait_ustarted = (ib_uint64_t)sec * 1000000 + ms;
}
@@ -4443,6 +4536,7 @@ lock_cancel_waiting_and_release(
lock_t* lock) /*!< in: waiting lock request */
{
ut_ad(mutex_own(&kernel_mutex));
+ ut_ad(!(lock->type_mode & LOCK_CONV_BY_OTHER));
if (lock_get_type_low(lock) == LOCK_REC) {
@@ -4938,12 +5032,16 @@ loop:
lock_mutex_exit_kernel();
- mtr_start(&mtr);
+ if (srv_show_verbose_locks) {
+ mtr_start(&mtr);
- buf_page_get_with_no_latch(space, zip_size,
- page_no, &mtr);
+ buf_page_get_gen(space, zip_size, page_no,
+ RW_NO_LATCH, NULL,
+ BUF_GET_POSSIBLY_FREED,
+ __FILE__, __LINE__, &mtr);
- mtr_commit(&mtr);
+ mtr_commit(&mtr);
+ }
load_page_first = FALSE;
@@ -5503,13 +5601,13 @@ lock_rec_insert_check_and_lock(
err = lock_rec_enqueue_waiting(c_lock, LOCK_X | LOCK_GAP
| LOCK_INSERT_INTENTION,
block, next_rec_heap_no,
- index, thr);
+ NULL, index, thr);
#else
err = lock_rec_enqueue_waiting(LOCK_X | LOCK_GAP
| LOCK_INSERT_INTENTION,
block, next_rec_heap_no,
- index, thr);
-#endif
+ NULL, index, thr);
+#endif /* WITH_WSREP */
} else {
err = DB_SUCCESS;
}
@@ -5585,10 +5683,23 @@ lock_rec_convert_impl_to_expl(
if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, block,
heap_no, impl_trx)) {
+ ulint type_mode = (LOCK_REC | LOCK_X
+ | LOCK_REC_NOT_GAP);
+
+ /* If the delete-marked record was locked already,
+ we should reserve lock waiting for impl_trx as
+ implicit lock. Because cannot lock at this moment.*/
+
+ if (rec_get_deleted_flag(rec, rec_offs_comp(offsets))
+ && lock_rec_other_has_conflicting(
+ LOCK_X | LOCK_REC_NOT_GAP, block,
+ heap_no, impl_trx)) {
+
+ type_mode |= (LOCK_WAIT | LOCK_CONV_BY_OTHER);
+ }
lock_rec_add_to_queue(
- LOCK_REC | LOCK_X | LOCK_REC_NOT_GAP,
- block, heap_no, index, impl_trx);
+ type_mode, block, heap_no, index, impl_trx);
}
}
}
diff --git a/storage/xtradb/log/log0online.c b/storage/xtradb/log/log0online.c
index 55eb9d17c46..be0a9708b8c 100644
--- a/storage/xtradb/log/log0online.c
+++ b/storage/xtradb/log/log0online.c
@@ -36,6 +36,11 @@ Online database log parsing for changed page tracking
enum { FOLLOW_SCAN_SIZE = 4 * (UNIV_PAGE_SIZE_MAX) };
+#ifdef UNIV_PFS_MUTEX
+/* Key to register log_bmp_sys->mutex with PFS */
+UNIV_INTERN mysql_pfs_key_t log_bmp_sys_mutex_key;
+#endif /* UNIV_PFS_MUTEX */
+
/** Log parsing and bitmap output data structure */
struct log_bitmap_struct {
byte read_buf[FOLLOW_SCAN_SIZE];
@@ -69,6 +74,7 @@ struct log_bitmap_struct {
both the correct type and the tree does
not mind its overwrite during
rbt_next() tree traversal. */
+ mutex_t mutex; /*!< mutex protecting all the fields.*/
};
/* The log parsing and bitmap output struct instance */
@@ -172,6 +178,8 @@ log_online_set_page_bit(
byte search_page[MODIFIED_PAGE_BLOCK_SIZE];
byte *page_ptr;
+ ut_ad(mutex_own(&log_bmp_sys->mutex));
+
ut_a(space != ULINT_UNDEFINED);
ut_a(page_no != ULINT_UNDEFINED);
@@ -312,8 +320,8 @@ its name is correct and use it for (re-)tracking start.
@return the last fully tracked LSN */
static
ib_uint64_t
-log_online_read_last_tracked_lsn()
-/*==============================*/
+log_online_read_last_tracked_lsn(void)
+/*==================================*/
{
byte page[MODIFIED_PAGE_BLOCK_SIZE];
ibool is_last_page = FALSE;
@@ -405,8 +413,10 @@ log_online_can_track_missing(
if (last_tracked_lsn > tracking_start_lsn) {
fprintf(stderr,
- "InnoDB: Error: last tracked LSN is in future. This "
- "can be caused by mismatched bitmap files.\n");
+ "InnoDB: Error: last tracked LSN %llu is ahead of "
+ "tracking start LSN %llu. This can be caused by "
+ "mismatched bitmap files.\n", last_tracked_lsn,
+ tracking_start_lsn);
exit(1);
}
@@ -431,10 +441,10 @@ log_online_track_missing_on_startup(
{
ut_ad(last_tracked_lsn != tracking_start_lsn);
- fprintf(stderr, "InnoDB: last tracked LSN is %llu, but the last "
- "checkpoint LSN is %llu. This might be due to a server "
- "crash or a very fast shutdown. ", last_tracked_lsn,
- tracking_start_lsn);
+ fprintf(stderr, "InnoDB: last tracked LSN in \'%s\' is %llu, but the "
+ "last checkpoint LSN is %llu. This might be due to a server "
+ "crash or a very fast shutdown. ", log_bmp_sys->out.name,
+ last_tracked_lsn, tracking_start_lsn);
/* See if we can fully recover the missing interval */
if (log_online_can_track_missing(last_tracked_lsn,
@@ -446,7 +456,9 @@ log_online_track_missing_on_startup(
log_bmp_sys->start_lsn = ut_max_uint64(last_tracked_lsn,
MIN_TRACKED_LSN);
log_set_tracked_lsn(log_bmp_sys->start_lsn);
- log_online_follow_redo_log();
+ if (!log_online_follow_redo_log()) {
+ exit(1);
+ }
ut_ad(log_bmp_sys->end_lsn >= tracking_start_lsn);
fprintf(stderr,
@@ -484,18 +496,47 @@ log_online_make_bitmap_name(
}
/*********************************************************************//**
-Create a new empty bitmap output file. */
+Check if an old file that has the name of a new bitmap file we are about to
+create should be overwritten. */
static
-void
-log_online_start_bitmap_file()
-/*==========================*/
+ibool
+log_online_should_overwrite(
+/*========================*/
+ const char *path) /*!< in: path to file */
{
- ibool success;
+ ibool success;
+ os_file_stat_t file_info;
- log_bmp_sys->out.file
- = os_file_create(innodb_file_bmp_key, log_bmp_sys->out.name,
- OS_FILE_OVERWRITE, OS_FILE_NORMAL,
- OS_DATA_FILE, &success);
+ /* Currently, it's OK to overwrite 0-sized files only */
+ success = os_file_get_status(path, &file_info);
+ return success && file_info.size == 0LL;
+}
+
+/*********************************************************************//**
+Create a new empty bitmap output file.
+
+@return TRUE if operation succeeded, FALSE if I/O error */
+static
+ibool
+log_online_start_bitmap_file(void)
+/*==============================*/
+{
+ ibool success = TRUE;
+
+ /* Check for an old file that should be deleted first */
+ if (log_online_should_overwrite(log_bmp_sys->out.name)) {
+ success = os_file_delete(log_bmp_sys->out.name);
+ }
+
+ if (UNIV_LIKELY(success)) {
+ log_bmp_sys->out.file
+ = os_file_create_simple_no_error_handling(
+ innodb_file_bmp_key,
+ log_bmp_sys->out.name,
+ OS_FILE_CREATE,
+ OS_FILE_READ_WRITE,
+ &success);
+ }
if (UNIV_UNLIKELY(!success)) {
/* The following call prints an error message */
@@ -503,25 +544,32 @@ log_online_start_bitmap_file()
fprintf(stderr,
"InnoDB: Error: Cannot create \'%s\'\n",
log_bmp_sys->out.name);
- exit(1);
+ log_bmp_sys->out.file = -1;
+ return FALSE;
}
log_bmp_sys->out.offset = 0;
+ return TRUE;
}
/*********************************************************************//**
-Close the current bitmap output file and create the next one. */
+Close the current bitmap output file and create the next one.
+
+@return TRUE if operation succeeded, FALSE if I/O error */
static
-void
+ibool
log_online_rotate_bitmap_file(
/*===========================*/
ib_uint64_t next_file_start_lsn) /*!<in: the start LSN name
part */
{
- os_file_close(log_bmp_sys->out.file);
+ if (log_bmp_sys->out.file != -1) {
+ os_file_close(log_bmp_sys->out.file);
+ log_bmp_sys->out.file = -1;
+ }
log_bmp_sys->out_seq_num++;
log_online_make_bitmap_name(next_file_start_lsn);
- log_online_start_bitmap_file();
+ return log_online_start_bitmap_file();
}
/*********************************************************************//**
@@ -556,8 +604,8 @@ log_online_is_bitmap_file(
Initialize the online log following subsytem. */
UNIV_INTERN
void
-log_online_read_init()
-/*==================*/
+log_online_read_init(void)
+/*======================*/
{
ibool success;
ib_uint64_t tracking_start_lsn
@@ -566,13 +614,16 @@ log_online_read_init()
os_file_stat_t bitmap_dir_file_info;
ib_uint64_t last_file_start_lsn = MIN_TRACKED_LSN;
- /* Assert (could be compile-time assert) that bitmap data start and end
- in a bitmap block is 8-byte aligned */
- ut_a(MODIFIED_PAGE_BLOCK_BITMAP % 8 == 0);
- ut_a(MODIFIED_PAGE_BLOCK_BITMAP_LEN % 8 == 0);
+ /* Bitmap data start and end in a bitmap block must be 8-byte
+ aligned. */
+ compile_time_assert(MODIFIED_PAGE_BLOCK_BITMAP % 8 == 0);
+ compile_time_assert(MODIFIED_PAGE_BLOCK_BITMAP_LEN % 8 == 0);
log_bmp_sys = ut_malloc(sizeof(*log_bmp_sys));
+ mutex_create(log_bmp_sys_mutex_key, &log_bmp_sys->mutex,
+ SYNC_LOG_ONLINE);
+
/* Enumerate existing bitmap files to either open the last one to get
the last tracked LSN either to find that there are none and start
tracking from scratch. */
@@ -629,7 +680,9 @@ log_online_read_init()
if (!success) {
/* New file, tracking from scratch */
- log_online_start_bitmap_file();
+ if (!log_online_start_bitmap_file()) {
+ exit(1);
+ }
}
else {
@@ -637,6 +690,7 @@ log_online_read_init()
ulint size_low;
ulint size_high;
ib_uint64_t last_tracked_lsn;
+ ib_uint64_t file_start_lsn;
success = os_file_get_size(log_bmp_sys->out.file, &size_low,
&size_high);
@@ -667,10 +721,12 @@ log_online_read_init()
if we can retrack any missing data. */
if (log_online_can_track_missing(last_tracked_lsn,
tracking_start_lsn)) {
- log_online_rotate_bitmap_file(last_tracked_lsn);
+ file_start_lsn = last_tracked_lsn;
+ } else {
+ file_start_lsn = tracking_start_lsn;
}
- else {
- log_online_rotate_bitmap_file(tracking_start_lsn);
+ if (!log_online_rotate_bitmap_file(file_start_lsn)) {
+ exit(1);
}
if (last_tracked_lsn < tracking_start_lsn) {
@@ -701,12 +757,15 @@ log_online_read_init()
Shut down the online log following subsystem. */
UNIV_INTERN
void
-log_online_read_shutdown()
-/*======================*/
+log_online_read_shutdown(void)
+/*==========================*/
{
ib_rbt_node_t *free_list_node = log_bmp_sys->page_free_list;
- os_file_close(log_bmp_sys->out.file);
+ if (log_bmp_sys->out.file != -1) {
+ os_file_close(log_bmp_sys->out.file);
+ log_bmp_sys->out.file = -1;
+ }
rbt_free(log_bmp_sys->modified_pages);
@@ -716,6 +775,8 @@ log_online_read_shutdown()
free_list_node = next;
}
+ mutex_free(&log_bmp_sys->mutex);
+
ut_free(log_bmp_sys);
}
@@ -759,14 +820,16 @@ from the buffer. If an incomplete record is found, moves it to the end of the
buffer. */
static
void
-log_online_parse_redo_log()
-/*=======================*/
+log_online_parse_redo_log(void)
+/*===========================*/
{
byte *ptr = log_bmp_sys->parse_buf;
byte *end = log_bmp_sys->parse_buf_end;
ulint len = 0;
+ ut_ad(mutex_own(&log_bmp_sys->mutex));
+
while (ptr != end
&& log_bmp_sys->next_parse_lsn < log_bmp_sys->end_lsn) {
@@ -857,6 +920,8 @@ log_online_add_to_parse_buf(
ulint actual_data_len = (end_offset >= start_offset)
? end_offset - start_offset : 0;
+ ut_ad(mutex_own(&log_bmp_sys->mutex));
+
ut_memcpy(log_bmp_sys->parse_buf_end, log_block + start_offset,
actual_data_len);
@@ -881,6 +946,8 @@ log_online_parse_redo_log_block(
{
ulint block_data_len;
+ ut_ad(mutex_own(&log_bmp_sys->mutex));
+
block_data_len = log_block_get_data_len(log_block);
ut_ad(block_data_len % OS_FILE_LOG_BLOCK_SIZE == 0
@@ -907,6 +974,8 @@ log_online_follow_log_seg(
byte* log_block_end = log_bmp_sys->read_buf
+ (block_end_lsn - block_start_lsn);
+ ut_ad(mutex_own(&log_bmp_sys->mutex));
+
mutex_enter(&log_sys->mutex);
log_group_read_log_seg(LOG_RECOVER, log_bmp_sys->read_buf,
group, block_start_lsn, block_end_lsn);
@@ -969,6 +1038,8 @@ log_online_follow_log_group(
ib_uint64_t block_start_lsn = contiguous_lsn;
ib_uint64_t block_end_lsn;
+ ut_ad(mutex_own(&log_bmp_sys->mutex));
+
log_bmp_sys->next_parse_lsn = log_bmp_sys->start_lsn;
log_bmp_sys->parse_buf_end = log_bmp_sys->parse_buf;
@@ -996,19 +1067,26 @@ log_online_follow_log_group(
/*********************************************************************//**
Write, flush one bitmap block to disk and advance the output position if
-successful. */
+successful.
+
+@return TRUE if page written OK, FALSE if I/O error */
static
-void
+ibool
log_online_write_bitmap_page(
/*=========================*/
const byte *block) /*!< in: block to write */
{
ibool success;
+ ut_ad(mutex_own(&log_bmp_sys->mutex));
+
+ /* Simulate a write error */
+ DBUG_EXECUTE_IF("bitmap_page_write_error", return FALSE;);
+
success = os_file_write(log_bmp_sys->out.name, log_bmp_sys->out.file,
block,
(ulint)(log_bmp_sys->out.offset & 0xFFFFFFFF),
- (ulint)(log_bmp_sys->out.offset << 32),
+ (ulint)(log_bmp_sys->out.offset >> 32),
MODIFIED_PAGE_BLOCK_SIZE);
if (UNIV_UNLIKELY(!success)) {
@@ -1016,7 +1094,7 @@ log_online_write_bitmap_page(
os_file_get_last_error(TRUE);
fprintf(stderr, "InnoDB: Error: failed writing changed page "
"bitmap file \'%s\'\n", log_bmp_sys->out.name);
- return;
+ return FALSE;
}
success = os_file_flush(log_bmp_sys->out.file, FALSE);
@@ -1027,25 +1105,38 @@ log_online_write_bitmap_page(
fprintf(stderr, "InnoDB: Error: failed flushing "
"changed page bitmap file \'%s\'\n",
log_bmp_sys->out.name);
- return;
+ return FALSE;
}
+#ifdef UNIV_LINUX
+ posix_fadvise(log_bmp_sys->out.file, log_bmp_sys->out.offset,
+ MODIFIED_PAGE_BLOCK_SIZE, POSIX_FADV_DONTNEED);
+#endif
+
log_bmp_sys->out.offset += MODIFIED_PAGE_BLOCK_SIZE;
+ return TRUE;
}
/*********************************************************************//**
Append the current changed page bitmap to the bitmap file. Clears the
-bitmap tree and recycles its nodes to the free list. */
+bitmap tree and recycles its nodes to the free list.
+
+@return TRUE if bitmap written OK, FALSE if I/O error*/
static
-void
-log_online_write_bitmap()
-/*=====================*/
+ibool
+log_online_write_bitmap(void)
+/*=========================*/
{
ib_rbt_node_t *bmp_tree_node;
const ib_rbt_node_t *last_bmp_tree_node;
+ ibool success = TRUE;
+
+ ut_ad(mutex_own(&log_bmp_sys->mutex));
if (log_bmp_sys->out.offset >= srv_max_bitmap_file_size) {
- log_online_rotate_bitmap_file(log_bmp_sys->start_lsn);
+ if (!log_online_rotate_bitmap_file(log_bmp_sys->start_lsn)) {
+ return FALSE;
+ }
}
bmp_tree_node = (ib_rbt_node_t *)
@@ -1056,18 +1147,25 @@ log_online_write_bitmap()
byte *page = rbt_value(byte, bmp_tree_node);
- if (bmp_tree_node == last_bmp_tree_node) {
- mach_write_to_4(page + MODIFIED_PAGE_IS_LAST_BLOCK, 1);
- }
+ /* In case of a bitmap page write error keep on looping over
+ the tree to reclaim its memory through the free list instead of
+ returning immediatelly. */
+ if (UNIV_LIKELY(success)) {
+ if (bmp_tree_node == last_bmp_tree_node) {
+ mach_write_to_4(page
+ + MODIFIED_PAGE_IS_LAST_BLOCK,
+ 1);
+ }
- mach_write_to_8(page + MODIFIED_PAGE_START_LSN,
- log_bmp_sys->start_lsn);
- mach_write_to_8(page + MODIFIED_PAGE_END_LSN,
- log_bmp_sys->end_lsn);
- mach_write_to_4(page + MODIFIED_PAGE_BLOCK_CHECKSUM,
- log_online_calc_checksum(page));
+ mach_write_to_8(page + MODIFIED_PAGE_START_LSN,
+ log_bmp_sys->start_lsn);
+ mach_write_to_8(page + MODIFIED_PAGE_END_LSN,
+ log_bmp_sys->end_lsn);
+ mach_write_to_4(page + MODIFIED_PAGE_BLOCK_CHECKSUM,
+ log_online_calc_checksum(page));
- log_online_write_bitmap_page(page);
+ success = log_online_write_bitmap_page(page);
+ }
bmp_tree_node->left = log_bmp_sys->page_free_list;
log_bmp_sys->page_free_list = bmp_tree_node;
@@ -1077,18 +1175,29 @@ log_online_write_bitmap()
}
rbt_reset(log_bmp_sys->modified_pages);
+ return success;
}
/*********************************************************************//**
Read and parse the redo log up to last checkpoint LSN to build the changed
-page bitmap which is then written to disk. */
+page bitmap which is then written to disk.
+
+@return TRUE if log tracking succeeded, FALSE if bitmap write I/O error */
UNIV_INTERN
-void
-log_online_follow_redo_log()
-/*========================*/
+ibool
+log_online_follow_redo_log(void)
+/*============================*/
{
ib_uint64_t contiguous_start_lsn;
log_group_t* group;
+ ibool result;
+
+ mutex_enter(&log_bmp_sys->mutex);
+
+ if (!srv_track_changed_pages) {
+ mutex_exit(&log_bmp_sys->mutex);
+ return FALSE;
+ }
/* Grab the LSN of the last checkpoint, we will parse up to it */
mutex_enter(&(log_sys->mutex));
@@ -1096,7 +1205,8 @@ log_online_follow_redo_log()
mutex_exit(&(log_sys->mutex));
if (log_bmp_sys->end_lsn == log_bmp_sys->start_lsn) {
- return;
+ mutex_exit(&log_bmp_sys->mutex);
+ return TRUE;
}
group = UT_LIST_GET_FIRST(log_sys->log_groups);
@@ -1114,9 +1224,12 @@ log_online_follow_redo_log()
tracked LSN, so that LSN tracking for this interval is tested. */
DBUG_EXECUTE_IF("crash_before_bitmap_write", DBUG_SUICIDE(););
- log_online_write_bitmap();
+ result = log_online_write_bitmap();
log_bmp_sys->start_lsn = log_bmp_sys->end_lsn;
log_set_tracked_lsn(log_bmp_sys->start_lsn);
+
+ mutex_exit(&log_bmp_sys->mutex);
+ return result;
}
/*********************************************************************//**
@@ -1514,3 +1627,81 @@ log_online_bitmap_iterator_next(
return TRUE;
}
+
+/************************************************************//**
+Delete all the bitmap files for data less than the specified LSN.
+If called with lsn == 0 (i.e. set by RESET request) or
+IB_ULONGLONG_MAX, restart the bitmap file sequence, otherwise
+continue it.
+
+@return FALSE to indicate success, TRUE for failure. */
+UNIV_INTERN
+ibool
+log_online_purge_changed_page_bitmaps(
+/*==================================*/
+ ib_uint64_t lsn) /*!< in: LSN to purge files up to */
+{
+ log_online_bitmap_file_range_t bitmap_files;
+ size_t i;
+ ibool result = FALSE;
+
+ if (lsn == 0) {
+ lsn = IB_ULONGLONG_MAX;
+ }
+
+ if (srv_track_changed_pages) {
+ /* User requests might happen with both enabled and disabled
+ tracking */
+ mutex_enter(&log_bmp_sys->mutex);
+ }
+
+ if (!log_online_setup_bitmap_file_range(&bitmap_files, 0, lsn)) {
+ if (srv_track_changed_pages) {
+ mutex_exit(&log_bmp_sys->mutex);
+ }
+ return TRUE;
+ }
+
+ if (srv_track_changed_pages && lsn >= log_bmp_sys->end_lsn) {
+ /* If we have to delete the current output file, close it
+ first. */
+ os_file_close(log_bmp_sys->out.file);
+ log_bmp_sys->out.file = -1;
+ }
+
+ for (i = 0; i < bitmap_files.count; i++) {
+ if (bitmap_files.files[i].seq_num == 0
+ || bitmap_files.files[i].start_lsn >= lsn) {
+ break;
+ }
+ if (!os_file_delete_if_exists(bitmap_files.files[i].name)) {
+ os_file_get_last_error(TRUE);
+ result = TRUE;
+ break;
+ }
+ }
+
+ if (srv_track_changed_pages) {
+ if (lsn > log_bmp_sys->end_lsn) {
+ ib_uint64_t new_file_lsn;
+ if (lsn == IB_ULONGLONG_MAX) {
+ /* RESET restarts the sequence */
+ log_bmp_sys->out_seq_num = 0;
+ new_file_lsn = 0;
+ } else {
+ new_file_lsn = log_bmp_sys->end_lsn;
+ }
+ if (!log_online_rotate_bitmap_file(new_file_lsn)) {
+ /* If file create failed, signal the log
+ tracking thread to quit next time it wakes
+ up. */
+ srv_track_changed_pages = FALSE;
+ }
+ }
+
+ mutex_exit(&log_bmp_sys->mutex);
+ }
+
+ free(bitmap_files.files);
+ return result;
+}
diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c
index 5ab8c14ae2e..4e179afd50c 100644
--- a/storage/xtradb/log/log0recv.c
+++ b/storage/xtradb/log/log0recv.c
@@ -994,8 +994,11 @@ recv_parse_or_apply_log_rec_body(
not NULL, then the log record is
applied to the page, and the log
record should be complete then */
- mtr_t* mtr) /*!< in: mtr or NULL; should be non-NULL
+ mtr_t* mtr, /*!< in: mtr or NULL; should be non-NULL
if and only if block is non-NULL */
+ ulint space_id)
+ /*!< in: tablespace id obtained by
+ parsing initial log record */
{
dict_index_t* index = NULL;
page_t* page;
@@ -1267,8 +1270,11 @@ recv_parse_or_apply_log_rec_body(
ut_ad(!page || page_type != FIL_PAGE_TYPE_ALLOCATED);
ptr = mlog_parse_string(ptr, end_ptr, page, page_zip);
break;
- case MLOG_FILE_CREATE:
case MLOG_FILE_RENAME:
+ ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type,
+ space_id, 0);
+ break;
+ case MLOG_FILE_CREATE:
case MLOG_FILE_DELETE:
case MLOG_FILE_CREATE2:
ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0, 0);
@@ -1672,7 +1678,8 @@ recv_recover_page_func(
recv_parse_or_apply_log_rec_body(recv->type, buf,
buf + recv->len,
- block, &mtr);
+ block, &mtr,
+ recv_addr->space);
if (srv_recovery_stats) {
mutex_enter(&(recv_sys->mutex));
@@ -1704,9 +1711,8 @@ recv_recover_page_func(
if (fil_page_get_type(page) == FIL_PAGE_INDEX) {
page_zip_des_t* page_zip = buf_block_get_page_zip(block);
- if (page_zip) {
- ut_a(page_zip_validate_low(page_zip, page, FALSE));
- }
+ ut_a(!page_zip
+ || page_zip_validate_low(page_zip, page, NULL, FALSE));
}
#endif /* UNIV_ZIP_DEBUG */
@@ -2158,7 +2164,7 @@ recv_parse_log_rec(
#endif /* UNIV_LOG_LSN_DEBUG */
new_ptr = recv_parse_or_apply_log_rec_body(*type, new_ptr, end_ptr,
- NULL, NULL);
+ NULL, NULL, *space);
if (UNIV_UNLIKELY(new_ptr == NULL)) {
return(0);
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index 34de6daba99..97777e21df8 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -1503,6 +1503,13 @@ os_file_create_func(
DWORD create_flag;
DWORD attributes;
ibool retry;
+
+ DBUG_EXECUTE_IF(
+ "ib_create_table_fail_disk_full",
+ *success = FALSE;
+ SetLastError(ERROR_DISK_FULL);
+ return((os_file_t) -1);
+ );
try_again:
ut_a(name);
@@ -1633,6 +1640,12 @@ try_again:
if (create_mode != OS_FILE_OPEN && create_mode != OS_FILE_OPEN_RAW)
WAIT_ALLOW_WRITES();
+ DBUG_EXECUTE_IF(
+ "ib_create_table_fail_disk_full",
+ *success = FALSE;
+ errno = ENOSPC;
+ return((os_file_t) -1);
+ );
try_again:
ut_a(name);
@@ -2397,7 +2410,7 @@ os_file_pread(
os_n_file_reads++;
- if (innobase_get_slow_log() && trx && trx->take_stats)
+ if (UNIV_UNLIKELY(trx && trx->take_stats))
{
trx->io_reads++;
trx->io_read += n;
@@ -2430,7 +2443,7 @@ os_file_pread(
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
- if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ if (UNIV_UNLIKELY(start_time != 0))
{
ut_usectime(&sec, &ms);
finish_time = (ib_uint64_t)sec * 1000000 + ms;
@@ -2484,7 +2497,7 @@ os_file_pread(
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
- if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
+ if (UNIV_UNLIKELY(start_time != 0)
{
ut_usectime(&sec, &ms);
finish_time = (ib_uint64_t)sec * 1000000 + ms;
@@ -4266,8 +4279,8 @@ os_aio_func(
ut_ad(file);
ut_ad(buf);
ut_ad(n > 0);
- ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0);
- ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0);
+ ut_ad(n % OS_MIN_LOG_BLOCK_SIZE == 0);
+ ut_ad(offset % OS_MIN_LOG_BLOCK_SIZE == 0);
ut_ad(os_aio_validate_skip());
#ifdef WIN_ASYNC_IO
ut_ad((n & 0xFFFFFFFFUL) == n);
diff --git a/storage/xtradb/page/page0cur.c b/storage/xtradb/page/page0cur.c
index d49b121afab..a722f5b188d 100644
--- a/storage/xtradb/page/page0cur.c
+++ b/storage/xtradb/page/page0cur.c
@@ -310,7 +310,7 @@ page_cur_search_with_match(
#endif /* UNIV_DEBUG */
page = buf_block_get_frame(block);
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
page_check_dir(page);
@@ -1248,7 +1248,7 @@ page_cur_insert_rec_zip(
ut_ad(!page_rec_is_supremum(*current_rec));
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
/* 1. Get the size of the physical record in the page */
@@ -1902,6 +1902,7 @@ page_cur_delete_rec(
/* Save to local variables some data associated with current_rec */
cur_slot_no = page_dir_find_owner_slot(current_rec);
+ ut_ad(cur_slot_no > 0);
cur_dir_slot = page_dir_get_nth_slot(page, cur_slot_no);
cur_n_owned = page_dir_slot_get_n_owned(cur_dir_slot);
@@ -1972,7 +1973,7 @@ page_cur_delete_rec(
}
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
}
diff --git a/storage/xtradb/page/page0page.c b/storage/xtradb/page/page0page.c
index e29fa2eb1e5..f2ce6c9fe16 100644
--- a/storage/xtradb/page/page0page.c
+++ b/storage/xtradb/page/page0page.c
@@ -626,7 +626,7 @@ page_copy_rec_list_end(
Furthermore, btr_compress() may set FIL_PAGE_PREV to
FIL_NULL on new_page while leaving it intact on
new_page_zip. So, we cannot validate new_page_zip. */
- ut_a(page_zip_validate_low(page_zip, page, TRUE));
+ ut_a(page_zip_validate_low(page_zip, page, index, TRUE));
}
#endif /* UNIV_ZIP_DEBUG */
ut_ad(buf_block_get_frame(block) == page);
@@ -796,8 +796,8 @@ zip_reorganize:
/* Before copying, "ret" was the predecessor
of the predefined supremum record. If it was
the predefined infimum record, then it would
- still be the infimum. Thus, the assertion
- ut_a(ret_pos > 0) would fail here. */
+ still be the infimum, and we would have
+ ret_pos == 0. */
if (UNIV_UNLIKELY
(!page_zip_reorganize(new_block, index, mtr))) {
@@ -946,7 +946,7 @@ page_delete_rec_list_end(
ut_ad(size == ULINT_UNDEFINED || size < UNIV_PAGE_SIZE);
ut_ad(!page_zip || page_rec_is_comp(rec));
#ifdef UNIV_ZIP_DEBUG
- ut_a(!page_zip || page_zip_validate(page_zip, page));
+ ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
if (page_rec_is_infimum(rec)) {
@@ -988,7 +988,7 @@ page_delete_rec_list_end(
ULINT_UNDEFINED, &heap);
rec = rec_get_next_ptr(rec, TRUE);
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
page_cur_delete_rec(&cur, index, offsets, mtr);
} while (page_offset(rec) != PAGE_NEW_SUPREMUM);
@@ -1052,6 +1052,7 @@ page_delete_rec_list_end(
n_owned = rec_get_n_owned_new(rec2) - count;
slot_index = page_dir_find_owner_slot(rec2);
+ ut_ad(slot_index > 0);
slot = page_dir_get_nth_slot(page, slot_index);
} else {
rec_t* rec2 = rec;
@@ -1067,6 +1068,7 @@ page_delete_rec_list_end(
n_owned = rec_get_n_owned_old(rec2) - count;
slot_index = page_dir_find_owner_slot(rec2);
+ ut_ad(slot_index > 0);
slot = page_dir_get_nth_slot(page, slot_index);
}
@@ -1126,7 +1128,8 @@ page_delete_rec_list_start(
between btr_attach_half_pages() and insert_page = ...
when btr_page_get_split_rec_to_left() holds
(direction == FSP_DOWN). */
- ut_a(!page_zip || page_zip_validate_low(page_zip, page, TRUE));
+ ut_a(!page_zip
+ || page_zip_validate_low(page_zip, page, index, TRUE));
}
#endif /* UNIV_ZIP_DEBUG */
@@ -1197,9 +1200,10 @@ page_move_rec_list_end(
= buf_block_get_page_zip(block);
ut_a(!new_page_zip == !page_zip);
ut_a(!new_page_zip
- || page_zip_validate(new_page_zip, new_page));
+ || page_zip_validate(new_page_zip, new_page, index));
ut_a(!page_zip
- || page_zip_validate(page_zip, page_align(split_rec)));
+ || page_zip_validate(page_zip, page_align(split_rec),
+ index));
}
#endif /* UNIV_ZIP_DEBUG */
@@ -1471,6 +1475,10 @@ page_rec_get_nth_const(
ulint n_owned;
const rec_t* rec;
+ if (nth == 0) {
+ return(page_get_infimum_rec(page));
+ }
+
ut_ad(nth < UNIV_PAGE_SIZE / (REC_N_NEW_EXTRA_BYTES + 1));
for (i = 0;; i++) {
diff --git a/storage/xtradb/page/page0zip.c b/storage/xtradb/page/page0zip.c
index 4751f4816a9..5357479908f 100644
--- a/storage/xtradb/page/page0zip.c
+++ b/storage/xtradb/page/page0zip.c
@@ -1437,7 +1437,7 @@ err_exit:
page_zip_get_size(page_zip) - PAGE_DATA);
mem_heap_free(heap);
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
if (mtr) {
@@ -3123,6 +3123,7 @@ page_zip_validate_low(
/*==================*/
const page_zip_des_t* page_zip,/*!< in: compressed page */
const page_t* page, /*!< in: uncompressed page */
+ const dict_index_t* index, /*!< in: index of the page, if known */
ibool sloppy) /*!< in: FALSE=strict,
TRUE=ignore the MIN_REC_FLAG */
{
@@ -3210,39 +3211,102 @@ page_zip_validate_low(
committed. Let us tolerate that difference when we
are performing a sloppy validation. */
- if (sloppy) {
- byte info_bits_diff;
- ulint offset
- = rec_get_next_offs(page + PAGE_NEW_INFIMUM,
- TRUE);
- ut_a(offset >= PAGE_NEW_SUPREMUM);
- offset -= 5 /* REC_NEW_INFO_BITS */;
-
- info_bits_diff = page[offset] ^ temp_page[offset];
-
- if (info_bits_diff == REC_INFO_MIN_REC_FLAG) {
- temp_page[offset] = page[offset];
-
- if (!memcmp(page + PAGE_HEADER,
- temp_page + PAGE_HEADER,
- UNIV_PAGE_SIZE - PAGE_HEADER
- - FIL_PAGE_DATA_END)) {
-
- /* Only the minimum record flag
- differed. Let us ignore it. */
- page_zip_fail(("page_zip_validate: "
- "min_rec_flag "
- "(ignored, "
- "%lu,%lu,0x%02lx)\n",
- page_get_space_id(page),
- page_get_page_no(page),
- (ulong) page[offset]));
- goto func_exit;
+ ulint* offsets;
+ mem_heap_t* heap;
+ const rec_t* rec;
+ const rec_t* trec;
+ byte info_bits_diff;
+ ulint offset
+ = rec_get_next_offs(page + PAGE_NEW_INFIMUM, TRUE);
+ ut_a(offset >= PAGE_NEW_SUPREMUM);
+ offset -= 5/*REC_NEW_INFO_BITS*/;
+
+ info_bits_diff = page[offset] ^ temp_page[offset];
+
+ if (info_bits_diff == REC_INFO_MIN_REC_FLAG) {
+ temp_page[offset] = page[offset];
+
+ if (!memcmp(page + PAGE_HEADER,
+ temp_page + PAGE_HEADER,
+ UNIV_PAGE_SIZE - PAGE_HEADER
+ - FIL_PAGE_DATA_END)) {
+
+ /* Only the minimum record flag
+ differed. Let us ignore it. */
+ page_zip_fail(("page_zip_validate: "
+ "min_rec_flag "
+ "(%s"
+ "%lu,%lu,0x%02lx)\n",
+ sloppy ? "ignored, " : "",
+ page_get_space_id(page),
+ page_get_page_no(page),
+ (ulong) page[offset]));
+ valid = sloppy;
+ goto func_exit;
+ }
+ }
+
+ /* Compare the pointers in the PAGE_FREE list. */
+ rec = page_header_get_ptr(page, PAGE_FREE);
+ trec = page_header_get_ptr(temp_page, PAGE_FREE);
+
+ while (rec || trec) {
+ if (page_offset(rec) != page_offset(trec)) {
+ page_zip_fail(("page_zip_validate: "
+ "PAGE_FREE list: %u!=%u\n",
+ (unsigned) page_offset(rec),
+ (unsigned) page_offset(trec)));
+ valid = FALSE;
+ goto func_exit;
+ }
+
+ rec = page_rec_get_next_low(rec, TRUE);
+ trec = page_rec_get_next_low(trec, TRUE);
+ }
+
+ /* Compare the records. */
+ heap = NULL;
+ offsets = NULL;
+ rec = page_rec_get_next_low(
+ page + PAGE_NEW_INFIMUM, TRUE);
+ trec = page_rec_get_next_low(
+ temp_page + PAGE_NEW_INFIMUM, TRUE);
+
+ do {
+ if (page_offset(rec) != page_offset(trec)) {
+ page_zip_fail(("page_zip_validate: "
+ "record list: 0x%02x!=0x%02x\n",
+ (unsigned) page_offset(rec),
+ (unsigned) page_offset(trec)));
+ valid = FALSE;
+ break;
+ }
+
+ if (index) {
+ /* Compare the data. */
+ offsets = rec_get_offsets(
+ rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+
+ if (memcmp(rec - rec_offs_extra_size(offsets),
+ trec - rec_offs_extra_size(offsets),
+ rec_offs_size(offsets))) {
+ page_zip_fail(
+ ("page_zip_validate: "
+ "record content: 0x%02x",
+ (unsigned) page_offset(rec)));
+ valid = FALSE;
+ break;
}
}
+
+ rec = page_rec_get_next_low(rec, TRUE);
+ trec = page_rec_get_next_low(trec, TRUE);
+ } while (rec || trec);
+
+ if (heap) {
+ mem_heap_free(heap);
}
- page_zip_fail(("page_zip_validate: content\n"));
- valid = FALSE;
}
func_exit:
@@ -3264,9 +3328,10 @@ ibool
page_zip_validate(
/*==============*/
const page_zip_des_t* page_zip,/*!< in: compressed page */
- const page_t* page) /*!< in: uncompressed page */
+ const page_t* page, /*!< in: uncompressed page */
+ const dict_index_t* index) /*!< in: index of the page, if known */
{
- return(page_zip_validate_low(page_zip, page,
+ return(page_zip_validate_low(page_zip, page, index,
recv_recovery_is_on()));
}
#endif /* UNIV_ZIP_DEBUG */
@@ -3597,7 +3662,7 @@ page_zip_write_rec(
page_zip->m_nonempty = TRUE;
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page_align(rec)));
+ ut_a(page_zip_validate(page_zip, page_align(rec), index));
#endif /* UNIV_ZIP_DEBUG */
}
@@ -3644,7 +3709,7 @@ corrupt:
}
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(page_zip, page, NULL));
#endif /* UNIV_ZIP_DEBUG */
memcpy(page + offset,
@@ -3653,7 +3718,7 @@ corrupt:
ptr + 4, BTR_EXTERN_FIELD_REF_SIZE);
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(page_zip, page, NULL));
#endif /* UNIV_ZIP_DEBUG */
}
@@ -3720,7 +3785,7 @@ page_zip_write_blob_ptr(
memcpy(externs, field, BTR_EXTERN_FIELD_REF_SIZE);
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
if (mtr) {
@@ -3791,7 +3856,7 @@ corrupt:
}
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(page_zip, page, NULL));
#endif /* UNIV_ZIP_DEBUG */
field = page + offset;
@@ -3812,7 +3877,7 @@ corrupt:
memcpy(storage, ptr + 4, REC_NODE_PTR_SIZE);
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(page_zip, page, NULL));
#endif /* UNIV_ZIP_DEBUG */
}
@@ -4039,7 +4104,7 @@ page_zip_clear_rec(
}
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
}
@@ -4063,7 +4128,7 @@ page_zip_rec_set_deleted(
*slot &= ~(PAGE_ZIP_DIR_SLOT_DEL >> 8);
}
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page_align(rec)));
+ ut_a(page_zip_validate(page_zip, page_align(rec), NULL));
#endif /* UNIV_ZIP_DEBUG */
}
@@ -4364,14 +4429,14 @@ corrupt:
goto corrupt;
}
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(page_zip, page, NULL));
#endif /* UNIV_ZIP_DEBUG */
memcpy(page + offset, ptr, len);
memcpy(page_zip->data + offset, ptr, len);
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(page_zip, page, NULL));
#endif /* UNIV_ZIP_DEBUG */
}
@@ -4449,7 +4514,7 @@ page_zip_reorganize(
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
ut_ad(page_is_comp(page));
ut_ad(!dict_index_is_ibuf(index));
- /* Note that page_zip_validate(page_zip, page) may fail here. */
+ /* Note that page_zip_validate(page_zip, page, index) may fail here. */
UNIV_MEM_ASSERT_RW(page, UNIV_PAGE_SIZE);
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
@@ -4536,7 +4601,7 @@ page_zip_copy_recs(
FIL_PAGE_PREV or PAGE_LEVEL, causing a temporary min_rec_flag
mismatch. A strict page_zip_validate() will be executed later
during the B-tree operations. */
- ut_a(page_zip_validate_low(src_zip, src, TRUE));
+ ut_a(page_zip_validate_low(src_zip, src, index, TRUE));
#endif /* UNIV_ZIP_DEBUG */
ut_a(page_zip_get_size(page_zip) == page_zip_get_size(src_zip));
if (UNIV_UNLIKELY(src_zip->n_blobs)) {
@@ -4597,7 +4662,7 @@ page_zip_copy_recs(
}
#ifdef UNIV_ZIP_DEBUG
- ut_a(page_zip_validate(page_zip, page));
+ ut_a(page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
btr_blob_dbg_add(page, index, "page_zip_copy_recs");
diff --git a/storage/xtradb/rem/rem0rec.c b/storage/xtradb/rem/rem0rec.c
index 0e8f606c311..8ea62c32113 100644
--- a/storage/xtradb/rem/rem0rec.c
+++ b/storage/xtradb/rem/rem0rec.c
@@ -170,7 +170,6 @@ rec_get_n_extern_new(
{
const byte* nulls;
const byte* lens;
- dict_field_t* field;
ulint null_mask;
ulint n_extern;
ulint i;
@@ -191,10 +190,13 @@ rec_get_n_extern_new(
/* read the lengths of fields 0..n */
do {
- ulint len;
+ const dict_field_t* field
+ = dict_index_get_nth_field(index, i);
+ const dict_col_t* col
+ = dict_field_get_col(field);
+ ulint len;
- field = dict_index_get_nth_field(index, i);
- if (!(dict_field_get_col(field)->prtype & DATA_NOT_NULL)) {
+ if (!(col->prtype & DATA_NOT_NULL)) {
/* nullable field => read the null flag */
if (UNIV_UNLIKELY(!(byte) null_mask)) {
@@ -212,8 +214,6 @@ rec_get_n_extern_new(
if (UNIV_UNLIKELY(!field->fixed_len)) {
/* Variable-length field: read the length */
- const dict_col_t* col
- = dict_field_get_col(field);
len = *lens--;
/* If the maximum length of the field is up
to 255 bytes, the actual length is always
@@ -242,16 +242,15 @@ rec_get_n_extern_new(
Determine the offset to each field in a leaf-page record
in ROW_FORMAT=COMPACT. This is a special case of
rec_init_offsets() and rec_get_offsets_func(). */
-UNIV_INTERN
+UNIV_INLINE __attribute__((nonnull))
void
rec_init_offsets_comp_ordinary(
/*===========================*/
const rec_t* rec, /*!< in: physical record in
ROW_FORMAT=COMPACT */
- ulint extra, /*!< in: number of bytes to reserve
- between the record header and
- the data payload
- (usually REC_N_NEW_EXTRA_BYTES) */
+ ibool temp, /*!< in: whether to use the
+ format for temporary files in
+ index creation */
const dict_index_t* index, /*!< in: record descriptor */
ulint* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
@@ -259,27 +258,38 @@ rec_init_offsets_comp_ordinary(
ulint i = 0;
ulint offs = 0;
ulint any_ext = 0;
- const byte* nulls = rec - (extra + 1);
+ const byte* nulls = temp
+ ? rec - 1
+ : rec - (1 + REC_N_NEW_EXTRA_BYTES);
const byte* lens = nulls
- UT_BITS_IN_BYTES(index->n_nullable);
- dict_field_t* field;
ulint null_mask = 1;
#ifdef UNIV_DEBUG
- /* We cannot invoke rec_offs_make_valid() here, because it can hold
- that extra != REC_N_NEW_EXTRA_BYTES. Similarly, rec_offs_validate()
- will fail in that case, because it invokes rec_get_status(). */
+ /* We cannot invoke rec_offs_make_valid() here if temp=TRUE.
+ Similarly, rec_offs_validate() will fail in that case, because
+ it invokes rec_get_status(). */
offsets[2] = (ulint) rec;
offsets[3] = (ulint) index;
#endif /* UNIV_DEBUG */
+ ut_ad(temp || dict_table_is_comp(index->table));
+
+ if (temp && dict_table_is_comp(index->table)) {
+ /* No need to do adjust fixed_len=0. We only need to
+ adjust it for ROW_FORMAT=REDUNDANT. */
+ temp = FALSE;
+ }
+
/* read the lengths of fields 0..n */
do {
- ulint len;
+ const dict_field_t* field
+ = dict_index_get_nth_field(index, i);
+ const dict_col_t* col
+ = dict_field_get_col(field);
+ ulint len;
- field = dict_index_get_nth_field(index, i);
- if (!(dict_field_get_col(field)->prtype
- & DATA_NOT_NULL)) {
+ if (!(col->prtype & DATA_NOT_NULL)) {
/* nullable field => read the null flag */
if (UNIV_UNLIKELY(!(byte) null_mask)) {
@@ -299,10 +309,9 @@ rec_init_offsets_comp_ordinary(
null_mask <<= 1;
}
- if (UNIV_UNLIKELY(!field->fixed_len)) {
+ if (!field->fixed_len
+ || (temp && !dict_col_get_fixed_size(col, temp))) {
/* Variable-length field: read the length */
- const dict_col_t* col
- = dict_field_get_col(field);
len = *lens--;
/* If the maximum length of the field is up
to 255 bytes, the actual length is always
@@ -396,9 +405,8 @@ rec_init_offsets(
= dict_index_get_n_unique_in_tree(index);
break;
case REC_STATUS_ORDINARY:
- rec_init_offsets_comp_ordinary(rec,
- REC_N_NEW_EXTRA_BYTES,
- index, offsets);
+ rec_init_offsets_comp_ordinary(
+ rec, FALSE, index, offsets);
return;
}
@@ -769,17 +777,19 @@ rec_get_nth_field_offs_old(
/**********************************************************//**
Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
@return total size */
-UNIV_INTERN
+UNIV_INLINE __attribute__((warn_unused_result, nonnull(1,2)))
ulint
-rec_get_converted_size_comp_prefix(
-/*===============================*/
+rec_get_converted_size_comp_prefix_low(
+/*===================================*/
const dict_index_t* index, /*!< in: record descriptor;
dict_table_is_comp() is
assumed to hold, even if
it does not */
const dfield_t* fields, /*!< in: array of data fields */
ulint n_fields,/*!< in: number of data fields */
- ulint* extra) /*!< out: extra size */
+ ulint* extra, /*!< out: extra size */
+ ibool temp) /*!< in: whether this is a
+ temporary file record */
{
ulint extra_size;
ulint data_size;
@@ -788,15 +798,25 @@ rec_get_converted_size_comp_prefix(
ut_ad(fields);
ut_ad(n_fields > 0);
ut_ad(n_fields <= dict_index_get_n_fields(index));
+ ut_ad(!temp || extra);
- extra_size = REC_N_NEW_EXTRA_BYTES
+ extra_size = temp
+ ? UT_BITS_IN_BYTES(index->n_nullable)
+ : REC_N_NEW_EXTRA_BYTES
+ UT_BITS_IN_BYTES(index->n_nullable);
data_size = 0;
+ if (temp && dict_table_is_comp(index->table)) {
+ /* No need to do adjust fixed_len=0. We only need to
+ adjust it for ROW_FORMAT=REDUNDANT. */
+ temp = FALSE;
+ }
+
/* read the lengths of fields 0..n */
for (i = 0; i < n_fields; i++) {
const dict_field_t* field;
ulint len;
+ ulint fixed_len;
const dict_col_t* col;
field = dict_index_get_nth_field(index, i);
@@ -812,8 +832,14 @@ rec_get_converted_size_comp_prefix(
continue;
}
- ut_ad(len <= col->len || col->mtype == DATA_BLOB);
+ ut_ad(len <= col->len || col->mtype == DATA_BLOB
+ || (col->len == 0 && col->mtype == DATA_VARCHAR));
+ fixed_len = field->fixed_len;
+ if (temp && fixed_len
+ && !dict_col_get_fixed_size(col, temp)) {
+ fixed_len = 0;
+ }
/* If the maximum length of a variable-length field
is up to 255 bytes, the actual length is always stored
in one byte. If the maximum length is more than 255
@@ -821,11 +847,20 @@ rec_get_converted_size_comp_prefix(
0..127. The length will be encoded in two bytes when
it is 128 or more, or when the field is stored externally. */
- if (field->fixed_len) {
- ut_ad(len == field->fixed_len);
+ if (fixed_len) {
+#ifdef UNIV_DEBUG
+ ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
+ ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
+
+ ut_ad(len <= fixed_len);
+
+ ut_ad(!mbmaxlen || len >= mbminlen
+ * (fixed_len / mbmaxlen));
+
/* dict_index_add_col() should guarantee this */
ut_ad(!field->prefix_len
- || field->fixed_len == field->prefix_len);
+ || fixed_len == field->prefix_len);
+#endif /* UNIV_DEBUG */
} else if (dfield_is_ext(&fields[i])) {
ut_ad(col->len >= 256 || col->mtype == DATA_BLOB);
extra_size += 2;
@@ -842,7 +877,7 @@ rec_get_converted_size_comp_prefix(
data_size += len;
}
- if (UNIV_LIKELY_NULL(extra)) {
+ if (extra) {
*extra = extra_size;
}
@@ -850,6 +885,23 @@ rec_get_converted_size_comp_prefix(
}
/**********************************************************//**
+Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
+@return total size */
+UNIV_INTERN
+ulint
+rec_get_converted_size_comp_prefix(
+/*===============================*/
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra) /*!< out: extra size */
+{
+ ut_ad(dict_table_is_comp(index->table));
+ return(rec_get_converted_size_comp_prefix_low(
+ index, fields, n_fields, extra, FALSE));
+}
+
+/**********************************************************//**
Determines the size of a data tuple in ROW_FORMAT=COMPACT.
@return total size */
UNIV_INTERN
@@ -893,8 +945,8 @@ rec_get_converted_size_comp(
return(ULINT_UNDEFINED);
}
- return(size + rec_get_converted_size_comp_prefix(index, fields,
- n_fields, extra));
+ return(size + rec_get_converted_size_comp_prefix_low(
+ index, fields, n_fields, extra, FALSE));
}
/***********************************************************//**
@@ -1071,19 +1123,18 @@ rec_convert_dtuple_to_rec_old(
/*********************************************************//**
Builds a ROW_FORMAT=COMPACT record out of a data tuple. */
-UNIV_INTERN
+UNIV_INLINE __attribute__((nonnull))
void
rec_convert_dtuple_to_rec_comp(
/*===========================*/
rec_t* rec, /*!< in: origin of record */
- ulint extra, /*!< in: number of bytes to
- reserve between the record
- header and the data payload
- (normally REC_N_NEW_EXTRA_BYTES) */
const dict_index_t* index, /*!< in: record descriptor */
- ulint status, /*!< in: status bits of the record */
const dfield_t* fields, /*!< in: array of data fields */
- ulint n_fields)/*!< in: number of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint status, /*!< in: status bits of the record */
+ ibool temp) /*!< in: whether to use the
+ format for temporary files in
+ index creation */
{
const dfield_t* field;
const dtype_t* type;
@@ -1095,31 +1146,44 @@ rec_convert_dtuple_to_rec_comp(
ulint n_node_ptr_field;
ulint fixed_len;
ulint null_mask = 1;
- ut_ad(extra == 0 || dict_table_is_comp(index->table));
- ut_ad(extra == 0 || extra == REC_N_NEW_EXTRA_BYTES);
+ ut_ad(temp || dict_table_is_comp(index->table));
ut_ad(n_fields > 0);
- switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
- case REC_STATUS_ORDINARY:
+ if (temp) {
+ ut_ad(status == REC_STATUS_ORDINARY);
ut_ad(n_fields <= dict_index_get_n_fields(index));
n_node_ptr_field = ULINT_UNDEFINED;
- break;
- case REC_STATUS_NODE_PTR:
- ut_ad(n_fields == dict_index_get_n_unique_in_tree(index) + 1);
- n_node_ptr_field = n_fields - 1;
- break;
- case REC_STATUS_INFIMUM:
- case REC_STATUS_SUPREMUM:
- ut_ad(n_fields == 1);
- n_node_ptr_field = ULINT_UNDEFINED;
- break;
- default:
- ut_error;
- return;
+ nulls = rec - 1;
+ if (dict_table_is_comp(index->table)) {
+ /* No need to do adjust fixed_len=0. We only
+ need to adjust it for ROW_FORMAT=REDUNDANT. */
+ temp = FALSE;
+ }
+ } else {
+ nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
+
+ switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
+ case REC_STATUS_ORDINARY:
+ ut_ad(n_fields <= dict_index_get_n_fields(index));
+ n_node_ptr_field = ULINT_UNDEFINED;
+ break;
+ case REC_STATUS_NODE_PTR:
+ ut_ad(n_fields
+ == dict_index_get_n_unique_in_tree(index) + 1);
+ n_node_ptr_field = n_fields - 1;
+ break;
+ case REC_STATUS_INFIMUM:
+ case REC_STATUS_SUPREMUM:
+ ut_ad(n_fields == 1);
+ n_node_ptr_field = ULINT_UNDEFINED;
+ break;
+ default:
+ ut_error;
+ return;
+ }
}
end = rec;
- nulls = rec - (extra + 1);
lens = nulls - UT_BITS_IN_BYTES(index->n_nullable);
/* clear the SQL-null flags */
memset(lens + 1, 0, nulls - lens);
@@ -1165,6 +1229,10 @@ rec_convert_dtuple_to_rec_comp(
ifield = dict_index_get_nth_field(index, i);
fixed_len = ifield->fixed_len;
+ if (temp && fixed_len
+ && !dict_col_get_fixed_size(ifield->col, temp)) {
+ fixed_len = 0;
+ }
/* If the maximum length of a variable-length field
is up to 255 bytes, the actual length is always stored
in one byte. If the maximum length is more than 255
@@ -1172,8 +1240,17 @@ rec_convert_dtuple_to_rec_comp(
0..127. The length will be encoded in two bytes when
it is 128 or more, or when the field is stored externally. */
if (fixed_len) {
- ut_ad(len == fixed_len);
+#ifdef UNIV_DEBUG
+ ulint mbminlen = DATA_MBMINLEN(
+ ifield->col->mbminmaxlen);
+ ulint mbmaxlen = DATA_MBMAXLEN(
+ ifield->col->mbminmaxlen);
+
+ ut_ad(len <= fixed_len);
+ ut_ad(!mbmaxlen || len >= mbminlen
+ * (fixed_len / mbmaxlen));
ut_ad(!dfield_is_ext(field));
+#endif /* UNIV_DEBUG */
} else if (dfield_is_ext(field)) {
ut_ad(ifield->col->len >= 256
|| ifield->col->mtype == DATA_BLOB);
@@ -1225,8 +1302,7 @@ rec_convert_dtuple_to_rec_new(
rec = buf + extra_size;
rec_convert_dtuple_to_rec_comp(
- rec, REC_N_NEW_EXTRA_BYTES, index, status,
- dtuple->fields, dtuple->n_fields);
+ rec, index, dtuple->fields, dtuple->n_fields, status, FALSE);
/* Set the info bits of the record */
rec_set_info_and_status_bits(rec, dtuple_get_info_bits(dtuple));
@@ -1288,6 +1364,54 @@ rec_convert_dtuple_to_rec(
return(rec);
}
+#ifndef UNIV_HOTBACKUP
+/**********************************************************//**
+Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT.
+@return total size */
+UNIV_INTERN
+ulint
+rec_get_converted_size_temp(
+/*========================*/
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields,/*!< in: number of data fields */
+ ulint* extra) /*!< out: extra size */
+{
+ return(rec_get_converted_size_comp_prefix_low(
+ index, fields, n_fields, extra, TRUE));
+}
+
+/******************************************************//**
+Determine the offset to each field in temporary file.
+@see rec_convert_dtuple_to_temp() */
+UNIV_INTERN
+void
+rec_init_offsets_temp(
+/*==================*/
+ const rec_t* rec, /*!< in: temporary file record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ ulint* offsets)/*!< in/out: array of offsets;
+ in: n=rec_offs_n_fields(offsets) */
+{
+ rec_init_offsets_comp_ordinary(rec, TRUE, index, offsets);
+}
+
+/*********************************************************//**
+Builds a temporary file record out of a data tuple.
+@see rec_init_offsets_temp() */
+UNIV_INTERN
+void
+rec_convert_dtuple_to_temp(
+/*=======================*/
+ rec_t* rec, /*!< out: record */
+ const dict_index_t* index, /*!< in: record descriptor */
+ const dfield_t* fields, /*!< in: array of data fields */
+ ulint n_fields) /*!< in: number of fields */
+{
+ rec_convert_dtuple_to_rec_comp(rec, index, fields, n_fields,
+ REC_STATUS_ORDINARY, TRUE);
+}
+
/**************************************************************//**
Copies the first n fields of a physical record to a data tuple. The fields
are copied to the memory heap. */
@@ -1498,6 +1622,7 @@ rec_copy_prefix_to_buf(
return(*buf + (rec - (lens + 1)));
}
+#endif /* UNIV_HOTBACKUP */
/***************************************************************//**
Validates the consistency of an old-style physical record.
diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c
index 89422dd3fc1..b459019a257 100644
--- a/storage/xtradb/row/row0ins.c
+++ b/storage/xtradb/row/row0ins.c
@@ -2335,7 +2335,10 @@ row_ins_index_entry(
err = row_ins_index_entry_low(BTR_MODIFY_LEAF, index, entry,
n_ext, thr);
if (err != DB_FAIL) {
-
+ if (index == dict_table_get_first_index(index->table)
+ && thr_get_trx(thr)->mysql_thd != 0) {
+ DEBUG_SYNC_C("row_ins_clust_index_entry_leaf_after");
+ }
return(err);
}
diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c
index 0fd13f5339c..0b6a6302854 100644
--- a/storage/xtradb/row/row0merge.c
+++ b/storage/xtradb/row/row0merge.c
@@ -301,6 +301,7 @@ row_merge_buf_add(
for (i = 0; i < n_fields; i++, field++, ifield++) {
const dict_col_t* col;
ulint col_no;
+ ulint fixed_len;
const dfield_t* row_field;
ulint len;
@@ -349,9 +350,30 @@ row_merge_buf_add(
ut_ad(len <= col->len || col->mtype == DATA_BLOB);
- if (ifield->fixed_len) {
- ut_ad(len == ifield->fixed_len);
+ fixed_len = ifield->fixed_len;
+ if (fixed_len && !dict_table_is_comp(index->table)
+ && DATA_MBMINLEN(col->mbminmaxlen)
+ != DATA_MBMAXLEN(col->mbminmaxlen)) {
+ /* CHAR in ROW_FORMAT=REDUNDANT is always
+ fixed-length, but in the temporary file it is
+ variable-length for variable-length character
+ sets. */
+ fixed_len = 0;
+ }
+
+ if (fixed_len) {
+#ifdef UNIV_DEBUG
+ ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen);
+ ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
+
+ /* len should be between size calcualted base on
+ mbmaxlen and mbminlen */
+ ut_ad(len <= fixed_len);
+ ut_ad(!mbmaxlen || len >= mbminlen
+ * (fixed_len / mbmaxlen));
+
ut_ad(!dfield_is_ext(field));
+#endif /* UNIV_DEBUG */
} else if (dfield_is_ext(field)) {
extra_size += 2;
} else if (len < 128
@@ -372,12 +394,11 @@ row_merge_buf_add(
ulint size;
ulint extra;
- size = rec_get_converted_size_comp(index,
- REC_STATUS_ORDINARY,
- entry, n_fields, &extra);
+ size = rec_get_converted_size_temp(
+ index, entry, n_fields, &extra);
- ut_ad(data_size + extra_size + REC_N_NEW_EXTRA_BYTES == size);
- ut_ad(extra_size + REC_N_NEW_EXTRA_BYTES == extra);
+ ut_ad(data_size + extra_size == size);
+ ut_ad(extra_size == extra);
}
#endif /* UNIV_DEBUG */
@@ -581,14 +602,9 @@ row_merge_buf_write(
ulint extra_size;
const dfield_t* entry = buf->tuples[i];
- size = rec_get_converted_size_comp(index,
- REC_STATUS_ORDINARY,
- entry, n_fields,
- &extra_size);
+ size = rec_get_converted_size_temp(
+ index, entry, n_fields, &extra_size);
ut_ad(size >= extra_size);
- ut_ad(extra_size >= REC_N_NEW_EXTRA_BYTES);
- extra_size -= REC_N_NEW_EXTRA_BYTES;
- size -= REC_N_NEW_EXTRA_BYTES;
/* Encode extra_size + 1 */
if (extra_size + 1 < 0x80) {
@@ -601,9 +617,8 @@ row_merge_buf_write(
ut_ad(b + size < block[1]);
- rec_convert_dtuple_to_rec_comp(b + extra_size, 0, index,
- REC_STATUS_ORDINARY,
- entry, n_fields);
+ rec_convert_dtuple_to_temp(b + extra_size, index,
+ entry, n_fields);
b += size;
@@ -709,6 +724,8 @@ row_merge_read(
ib_uint64_t ofs = ((ib_uint64_t) offset) * block_size;
ibool success;
+ DBUG_EXECUTE_IF("row_merge_read_failure", return(FALSE););
+
#ifdef UNIV_DEBUG
if (row_merge_print_block_read) {
fprintf(stderr, "row_merge_read fd=%d ofs=%lu\n",
@@ -756,6 +773,8 @@ row_merge_write(
(ulint) (ofs >> 32),
block_size);
+ DBUG_EXECUTE_IF("row_merge_write_failure", return(FALSE););
+
#ifdef UNIV_DEBUG
if (row_merge_print_block_write) {
fprintf(stderr, "row_merge_write fd=%d ofs=%lu\n",
@@ -872,7 +891,7 @@ err_exit:
*mrec = *buf + extra_size;
- rec_init_offsets_comp_ordinary(*mrec, 0, index, offsets);
+ rec_init_offsets_temp(*mrec, index, offsets);
data_size = rec_offs_data_size(offsets);
@@ -891,7 +910,7 @@ err_exit:
*mrec = b + extra_size;
- rec_init_offsets_comp_ordinary(*mrec, 0, index, offsets);
+ rec_init_offsets_temp(*mrec, index, offsets);
data_size = rec_offs_data_size(offsets);
ut_ad(extra_size + data_size < block_size);
@@ -2261,7 +2280,7 @@ row_merge_drop_temp_indexes(void)
/*********************************************************************//**
Creates temperary merge files, and if UNIV_PFS_IO defined, register
the file descriptor with Performance Schema.
-@return File descriptor */
+@return file descriptor, or -1 on failure */
UNIV_INLINE
int
row_merge_file_create_low(void)
@@ -2283,12 +2302,19 @@ row_merge_file_create_low(void)
#ifdef UNIV_PFS_IO
register_pfs_file_open_end(locker, fd);
#endif
+ if (fd < 0) {
+ fprintf(stderr,
+ "InnoDB: Error: Cannot create temporary merge file\n");
+ return(-1);
+ }
return(fd);
}
+
/*********************************************************************//**
-Create a merge file. */
-static
-void
+Create a merge file.
+@return file descriptor, or -1 on failure */
+static __attribute__((nonnull, warn_unused_result))
+int
row_merge_file_create(
/*==================*/
merge_file_t* merge_file) /*!< out: merge file structure */
@@ -2296,6 +2322,7 @@ row_merge_file_create(
merge_file->fd = row_merge_file_create_low();
merge_file->offset = 0;
merge_file->n_rec = 0;
+ return(merge_file->fd);
}
/*********************************************************************//**
@@ -2541,6 +2568,28 @@ row_merge_rename_tables(
goto err_exit;
}
+ /* Generate the redo logs for file operations */
+ fil_mtr_rename_log(old_table->space, old_name,
+ new_table->space, new_table->name, tmp_name);
+
+ /* What if the redo logs are flushed to disk here? This is
+ tested with following crash point */
+ DBUG_EXECUTE_IF("bug14669848_precommit", log_buffer_flush_to_disk();
+ DBUG_SUICIDE(););
+
+ /* File operations cannot be rolled back. So, before proceeding
+ with file operations, commit the dictionary changes.*/
+ trx_commit_for_mysql(trx);
+
+ /* If server crashes here, the dictionary in InnoDB and MySQL
+ will differ. The .ibd files and the .frm files must be swapped
+ manually by the administrator. No loss of data. */
+ DBUG_EXECUTE_IF("bug14669848", DBUG_SUICIDE(););
+
+ /* Ensure that the redo logs are flushed to disk. The config
+ innodb_flush_log_at_trx_commit must not affect this. */
+ log_buffer_flush_to_disk();
+
/* The following calls will also rename the .ibd data files if
the tables are stored in a single-table tablespace */
@@ -2715,7 +2764,7 @@ row_merge_build_indexes(
ulint block_size;
ulint i;
ulint error;
- int tmpfd;
+ int tmpfd = -1;
ulint merge_sort_block_size;
void* block_mem;
@@ -2741,13 +2790,31 @@ row_merge_build_indexes(
i * merge_sort_block_size);
}
+ /* Initialize all the merge file descriptors, so that we
+ don't call row_merge_file_destroy() on uninitialized
+ merge file descriptor */
+
+ for (i = 0; i < n_indexes; i++) {
+ merge_files[i].fd = -1;
+ }
+
for (i = 0; i < n_indexes; i++) {
- row_merge_file_create(&merge_files[i]);
+ if (row_merge_file_create(&merge_files[i]) < 0)
+ {
+ error = DB_OUT_OF_MEMORY;
+ goto func_exit;
+ }
}
tmpfd = row_merge_file_create_low();
+ if (tmpfd < 0)
+ {
+ error = DB_OUT_OF_MEMORY;
+ goto func_exit;
+ }
+
/* Reset the MySQL row buffer that is used when reporting
duplicate keys. */
innobase_rec_reset(table);
diff --git a/storage/xtradb/row/row0mysql.c b/storage/xtradb/row/row0mysql.c
index 9ab85940760..3a18cfc679e 100644
--- a/storage/xtradb/row/row0mysql.c
+++ b/storage/xtradb/row/row0mysql.c
@@ -1879,7 +1879,8 @@ Creates a table for MySQL. If the name of the table ends in
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
"innodb_table_monitor", then this will also start the printing of monitor
output by the master thread. If the table name ends in "innodb_mem_validate",
-InnoDB will try to invoke mem_validate().
+InnoDB will try to invoke mem_validate(). On failure the transaction will
+be rolled back and the 'table' object will be freed.
@return error code or DB_SUCCESS */
UNIV_INTERN
int
@@ -2017,6 +2018,8 @@ err_exit:
row_drop_table_for_mysql(table->name, trx, FALSE);
trx_commit_for_mysql(trx);
+ } else {
+ dict_mem_table_free(table);
}
break;
@@ -4270,6 +4273,13 @@ end:
trx->error_state = DB_SUCCESS;
trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
+ } else {
+ if (old_is_tmp && !new_is_tmp) {
+ /* After ALTER TABLE the table statistics
+ needs to be rebuilt. It will be rebuilt
+ when the table is loaded again. */
+ table->stat_initialized = FALSE;
+ }
}
}
diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c
index ec3603f2550..858d50fd5a6 100644
--- a/storage/xtradb/row/row0sel.c
+++ b/storage/xtradb/row/row0sel.c
@@ -2489,6 +2489,9 @@ row_sel_convert_mysql_key_to_innobase(
dfield++;
}
+ DBUG_EXECUTE_IF("innodb_srch_key_buffer_full",
+ ut_a(buf == (original_buf + buf_len)););
+
ut_a(buf <= original_buf + buf_len);
/* We set the length of tuple to n_fields: we assume that the memory
@@ -3641,13 +3644,13 @@ row_search_for_mysql(
should_release = 0;
for (i = 0; i < btr_search_index_num; i++) {
/* we should check all latches (fix Bug#791030) */
- if (rw_lock_get_writer(btr_search_latch_part[i])
- != RW_LOCK_NOT_LOCKED) {
+ if (UNIV_UNLIKELY(rw_lock_get_writer(btr_search_latch_part[i])
+ != RW_LOCK_NOT_LOCKED)) {
should_release |= ((ulint)1 << i);
}
}
- if (should_release) {
+ if (UNIV_UNLIKELY(should_release)) {
/* There is an x-latch request on the adaptive hash index:
release the s-latch to reduce starvation and wait for
@@ -4124,6 +4127,11 @@ wait_table_again:
}
rec_loop:
+ if (trx_is_interrupted(trx)) {
+ err = DB_INTERRUPTED;
+ goto normal_return;
+ }
+
/*-------------------------------------------------------------*/
/* PHASE 4: Look for matching records in a loop */
@@ -5118,11 +5126,15 @@ row_search_autoinc_read_column(
rec_offs_init(offsets_);
- offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
+ offsets = rec_get_offsets(rec, index, offsets, col_no + 1, &heap);
- data = rec_get_nth_field(rec, offsets, col_no, &len);
+ if (rec_offs_nth_sql_null(offsets, col_no)) {
+ /* There is no non-NULL value in the auto-increment column. */
+ value = 0;
+ goto func_exit;
+ }
- ut_a(len != UNIV_SQL_NULL);
+ data = rec_get_nth_field(rec, offsets, col_no, &len);
switch (mtype) {
case DATA_INT:
@@ -5144,14 +5156,15 @@ row_search_autoinc_read_column(
ut_error;
}
- if (UNIV_LIKELY_NULL(heap)) {
- mem_heap_free(heap);
- }
-
if (!unsigned_type && (ib_int64_t) value < 0) {
value = 0;
}
+func_exit:
+ if (UNIV_LIKELY_NULL(heap)) {
+ mem_heap_free(heap);
+ }
+
return(value);
}
diff --git a/storage/xtradb/row/row0umod.c b/storage/xtradb/row/row0umod.c
index 9597c476125..3c933c87b27 100644
--- a/storage/xtradb/row/row0umod.c
+++ b/storage/xtradb/row/row0umod.c
@@ -69,36 +69,6 @@ If you make a change in this module make sure that no codepath is
introduced where a call to log_free_check() is bypassed. */
/***********************************************************//**
-Checks if also the previous version of the clustered index record was
-modified or inserted by the same transaction, and its undo number is such
-that it should be undone in the same rollback.
-@return TRUE if also previous modify or insert of this row should be undone */
-static
-ibool
-row_undo_mod_undo_also_prev_vers(
-/*=============================*/
- undo_node_t* node, /*!< in: row undo node */
- undo_no_t* undo_no)/*!< out: the undo number */
-{
- trx_undo_rec_t* undo_rec;
- trx_t* trx;
-
- trx = node->trx;
-
- if (node->new_trx_id != trx->id) {
-
- *undo_no = 0;
- return(FALSE);
- }
-
- undo_rec = trx_undo_get_undo_rec_low(node->new_roll_ptr, node->heap);
-
- *undo_no = trx_undo_rec_get_undo_no(undo_rec);
-
- return(trx->roll_limit <= *undo_no);
-}
-
-/***********************************************************//**
Undoes a modify in a clustered index record.
@return DB_SUCCESS, DB_FAIL, or error code: we may run out of file space */
static
@@ -226,19 +196,11 @@ row_undo_mod_clust(
btr_pcur_t* pcur;
mtr_t mtr;
ulint err;
- ibool success;
- ibool more_vers;
- undo_no_t new_undo_no;
ut_ad(node && thr);
log_free_check();
- /* Check if also the previous version of the clustered index record
- should be undone in this same rollback operation */
-
- more_vers = row_undo_mod_undo_also_prev_vers(node, &new_undo_no);
-
pcur = &(node->pcur);
mtr_start(&mtr);
@@ -286,20 +248,6 @@ row_undo_mod_clust(
trx_undo_rec_release(node->trx, node->undo_no);
- if (more_vers && err == DB_SUCCESS) {
-
- /* Reserve the undo log record to the prior version after
- committing &mtr: this is necessary to comply with the latching
- order, as &mtr may contain the fsp latch which is lower in
- the latch hierarchy than trx->undo_mutex. */
-
- success = trx_undo_rec_reserve(node->trx, new_undo_no);
-
- if (success) {
- node->state = UNDO_NODE_PREV_VERS;
- }
- }
-
return(err);
}
@@ -571,6 +519,7 @@ row_undo_mod_upd_del_sec(
ulint err = DB_SUCCESS;
ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
+ ut_ad(!node->undo_row);
heap = mem_heap_create(1024);
while (node->index != NULL) {
@@ -632,6 +581,8 @@ row_undo_mod_del_mark_sec(
dict_index_t* index;
ulint err;
+ ut_ad(!node->undo_row);
+
heap = mem_heap_create(1024);
while (node->index != NULL) {
@@ -847,7 +798,6 @@ row_undo_mod_parse_undo_rec(
trx_undo_update_rec_get_update(ptr, clust_index, type, trx_id,
roll_ptr, info_bits, trx,
node->heap, &(node->update));
- node->new_roll_ptr = roll_ptr;
node->new_trx_id = trx_id;
node->cmpl_info = cmpl_info;
}
diff --git a/storage/xtradb/row/row0undo.c b/storage/xtradb/row/row0undo.c
index 09970b7fe21..74fc1baf1d2 100644
--- a/storage/xtradb/row/row0undo.c
+++ b/storage/xtradb/row/row0undo.c
@@ -216,7 +216,7 @@ row_undo_search_clust_to_pcur(
node->row = row_build(ROW_COPY_DATA, clust_index, rec,
offsets, NULL, ext, node->heap);
- if (node->update) {
+ if (node->rec_type == TRX_UNDO_UPD_EXIST_REC) {
node->undo_row = dtuple_copy(node->row, node->heap);
row_upd_replace(node->undo_row, &node->undo_ext,
clust_index, node->update, node->heap);
@@ -282,25 +282,6 @@ row_undo(
} else {
node->state = UNDO_NODE_MODIFY;
}
-
- } else if (node->state == UNDO_NODE_PREV_VERS) {
-
- /* Undo should be done to the same clustered index record
- again in this same rollback, restoring the previous version */
-
- roll_ptr = node->new_roll_ptr;
-
- node->undo_rec = trx_undo_get_undo_rec_low(roll_ptr,
- node->heap);
- node->roll_ptr = roll_ptr;
- node->undo_no = trx_undo_rec_get_undo_no(node->undo_rec);
-
- if (trx_undo_roll_ptr_is_insert(roll_ptr)) {
-
- node->state = UNDO_NODE_INSERT;
- } else {
- node->state = UNDO_NODE_MODIFY;
- }
}
/* Prevent DROP TABLE etc. while we are rolling back this row.
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index ee03c6b050d..4ddb03f671d 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -58,6 +58,8 @@ Created 10/8/1995 Heikki Tuuri
*******************************************************/
/* Dummy comment */
+#include "m_string.h" /* for my_sys.h */
+#include "my_sys.h" /* DEBUG_SYNC_C */
#include "srv0srv.h"
#include "ut0mem.h"
@@ -185,7 +187,7 @@ UNIV_INTERN my_bool srv_track_changed_pages = TRUE;
UNIV_INTERN ib_uint64_t srv_max_bitmap_file_size = 100 * 1024 * 1024;
-UNIV_INTERN ulonglong srv_changed_pages_limit = 0;
+UNIV_INTERN ulonglong srv_max_changed_pages = 0;
/** When TRUE, fake change transcations take S rather than X row locks.
When FALSE, row locks are not taken at all. */
@@ -320,58 +322,11 @@ UNIV_INTERN ulong srv_purge_batch_size = 20;
/* the number of rollback segments to use */
UNIV_INTERN ulong srv_rollback_segments = TRX_SYS_N_RSEGS;
-/* variable counts amount of data read in total (in bytes) */
-UNIV_INTERN ulint srv_data_read = 0;
-
/* Internal setting for "innodb_stats_method". Decides how InnoDB treats
NULL value when collecting statistics. By default, it is set to
SRV_STATS_NULLS_EQUAL(0), ie. all NULL value are treated equal */
ulong srv_innodb_stats_method = SRV_STATS_NULLS_EQUAL;
-/* here we count the amount of data written in total (in bytes) */
-UNIV_INTERN ulint srv_data_written = 0;
-
-/* the number of the log write requests done */
-UNIV_INTERN ulint srv_log_write_requests = 0;
-
-/* the number of physical writes to the log performed */
-UNIV_INTERN ulint srv_log_writes = 0;
-
-/* amount of data written to the log files in bytes */
-UNIV_INTERN ulint srv_os_log_written = 0;
-
-/* amount of writes being done to the log files */
-UNIV_INTERN ulint srv_os_log_pending_writes = 0;
-
-/* we increase this counter, when there we don't have enough space in the
-log buffer and have to flush it */
-UNIV_INTERN ulint srv_log_waits = 0;
-
-/* this variable counts the amount of times, when the doublewrite buffer
-was flushed */
-UNIV_INTERN ulint srv_dblwr_writes = 0;
-
-/* here we store the number of pages that have been flushed to the
-doublewrite buffer */
-UNIV_INTERN ulint srv_dblwr_pages_written = 0;
-
-/* in this variable we store the number of write requests issued */
-UNIV_INTERN ulint srv_buf_pool_write_requests = 0;
-
-/* here we store the number of times when we had to wait for a free page
-in the buffer pool. It happens when the buffer pool is full and we need
-to make a flush, in order to be able to read or create a page. */
-UNIV_INTERN ulint srv_buf_pool_wait_free = 0;
-
-/* variable to count the number of pages that were written from buffer
-pool to the disk */
-UNIV_INTERN ulint srv_buf_pool_flushed = 0;
-UNIV_INTERN ulint buf_lru_flush_page_count = 0;
-
-/** Number of buffer pool reads that led to the
-reading of a disk page */
-UNIV_INTERN ulint srv_buf_pool_reads = 0;
-
/** Time in seconds between automatic buffer pool dumps */
UNIV_INTERN uint srv_auto_lru_dump = 0;
@@ -414,6 +369,9 @@ UNIV_INTERN lint srv_conc_n_threads = 0;
InnoDB */
UNIV_INTERN ulint srv_conc_n_waiting_threads = 0;
+/* print all user-level transactions deadlocks to mysqld stderr */
+UNIV_INTERN my_bool srv_print_all_deadlocks = FALSE;
+
typedef struct srv_conc_slot_struct srv_conc_slot_t;
struct srv_conc_slot_struct{
os_event_t event; /*!< event to wait */
@@ -500,23 +458,83 @@ UNIV_INTERN ibool srv_print_log_io = FALSE;
UNIV_INTERN ibool srv_print_latch_waits = FALSE;
#endif /* UNIV_DEBUG */
-UNIV_INTERN ulint srv_n_rows_inserted = 0;
-UNIV_INTERN ulint srv_n_rows_updated = 0;
-UNIV_INTERN ulint srv_n_rows_deleted = 0;
-UNIV_INTERN ulint srv_n_rows_read = 0;
-
static ulint srv_n_rows_inserted_old = 0;
static ulint srv_n_rows_updated_old = 0;
static ulint srv_n_rows_deleted_old = 0;
static ulint srv_n_rows_read_old = 0;
-UNIV_INTERN ulint srv_n_lock_deadlock_count = 0;
-UNIV_INTERN ulint srv_n_lock_wait_count = 0;
-UNIV_INTERN ulint srv_n_lock_wait_current_count = 0;
-UNIV_INTERN ib_int64_t srv_n_lock_wait_time = 0;
-UNIV_INTERN ulint srv_n_lock_max_wait_time = 0;
+/* Ensure counters are on separate cache lines */
+
+#define CACHE_LINE_SIZE 64
+#define CACHE_ALIGNED __attribute__ ((aligned (CACHE_LINE_SIZE)))
+
+UNIV_INTERN byte
+counters_pad_start[CACHE_LINE_SIZE] __attribute__((unused)) = {0};
+
+UNIV_INTERN ulint srv_n_rows_inserted CACHE_ALIGNED = 0;
+UNIV_INTERN ulint srv_n_rows_updated CACHE_ALIGNED = 0;
+UNIV_INTERN ulint srv_n_rows_deleted CACHE_ALIGNED = 0;
+UNIV_INTERN ulint srv_n_rows_read CACHE_ALIGNED = 0;
+
+UNIV_INTERN ulint srv_n_lock_deadlock_count CACHE_ALIGNED = 0;
+UNIV_INTERN ulint srv_n_lock_wait_count CACHE_ALIGNED = 0;
+UNIV_INTERN ulint srv_n_lock_wait_current_count CACHE_ALIGNED = 0;
+UNIV_INTERN ib_int64_t srv_n_lock_wait_time CACHE_ALIGNED = 0;
+UNIV_INTERN ulint srv_n_lock_max_wait_time CACHE_ALIGNED = 0;
+
+UNIV_INTERN ulint srv_truncated_status_writes CACHE_ALIGNED = 0;
+
+/* variable counts amount of data read in total (in bytes) */
+UNIV_INTERN ulint srv_data_read CACHE_ALIGNED = 0;
+
+/* here we count the amount of data written in total (in bytes) */
+UNIV_INTERN ulint srv_data_written CACHE_ALIGNED = 0;
+
+/* the number of the log write requests done */
+UNIV_INTERN ulint srv_log_write_requests CACHE_ALIGNED = 0;
+
+/* the number of physical writes to the log performed */
+UNIV_INTERN ulint srv_log_writes CACHE_ALIGNED = 0;
+
+/* amount of data written to the log files in bytes */
+UNIV_INTERN ulint srv_os_log_written CACHE_ALIGNED = 0;
+
+/* amount of writes being done to the log files */
+UNIV_INTERN ulint srv_os_log_pending_writes CACHE_ALIGNED = 0;
+
+/* we increase this counter, when there we don't have enough space in the
+log buffer and have to flush it */
+UNIV_INTERN ulint srv_log_waits CACHE_ALIGNED = 0;
+
+/* this variable counts the amount of times, when the doublewrite buffer
+was flushed */
+UNIV_INTERN ulint srv_dblwr_writes CACHE_ALIGNED = 0;
+
+/* here we store the number of pages that have been flushed to the
+doublewrite buffer */
+UNIV_INTERN ulint srv_dblwr_pages_written CACHE_ALIGNED = 0;
+
+/* in this variable we store the number of write requests issued */
+UNIV_INTERN ulint srv_buf_pool_write_requests CACHE_ALIGNED = 0;
+
+/* here we store the number of times when we had to wait for a free page
+in the buffer pool. It happens when the buffer pool is full and we need
+to make a flush, in order to be able to read or create a page. */
+UNIV_INTERN ulint srv_buf_pool_wait_free CACHE_ALIGNED = 0;
+
+/** Number of buffer pool reads that led to the
+reading of a disk page */
+UNIV_INTERN ulint srv_buf_pool_reads CACHE_ALIGNED = 0;
-UNIV_INTERN ulint srv_truncated_status_writes = 0;
+/* variable to count the number of pages that were written from buffer
+pool to the disk */
+UNIV_INTERN ulint srv_buf_pool_flushed CACHE_ALIGNED = 0;
+
+/* variable to count the number of LRU flushed pages */
+UNIV_INTERN ulint buf_lru_flush_page_count CACHE_ALIGNED = 0;
+
+UNIV_INTERN byte
+counters_pad_end[CACHE_LINE_SIZE] __attribute__((unused)) = {0};
/*
Set the following to 0 if you want InnoDB to write messages on
@@ -1506,7 +1524,7 @@ retry:
ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
#endif /* UNIV_SYNC_DEBUG */
- if (innobase_get_slow_log() && trx->take_stats) {
+ if (UNIV_UNLIKELY(trx->take_stats)) {
ut_usectime(&sec, &ms);
start_time = (ib_uint64_t)sec * 1000000 + ms;
} else {
@@ -1524,7 +1542,7 @@ retry:
trx->op_info = "";
- if (innobase_get_slow_log() && trx->take_stats && start_time) {
+ if (UNIV_UNLIKELY(start_time != 0)) {
ut_usectime(&sec, &ms);
finish_time = (ib_uint64_t)sec * 1000000 + ms;
trx->innodb_que_wait_timer += (ulint)(finish_time - start_time);
@@ -1854,6 +1872,10 @@ srv_suspend_mysql_thread(
trx = thr_get_trx(thr);
+ if (trx->mysql_thd != 0) {
+ DEBUG_SYNC_C("srv_suspend_mysql_thread_enter");
+ }
+
os_event_set(srv_lock_timeout_thread_event);
mutex_enter(&kernel_mutex);
@@ -2296,6 +2318,8 @@ srv_printf_innodb_monitor(
(long) srv_conc_n_threads,
(ulong) srv_conc_n_waiting_threads);
+ mutex_enter(&kernel_mutex);
+
fprintf(file, "%lu read views open inside InnoDB\n",
UT_LIST_GET_LEN(trx_sys->view_list));
@@ -2309,6 +2333,8 @@ srv_printf_innodb_monitor(
}
}
+ mutex_exit(&kernel_mutex);
+
n_reserved = fil_space_get_n_reserved_extents(0);
if (n_reserved > 0) {
fprintf(file,
@@ -2393,16 +2419,18 @@ void
srv_export_innodb_status(void)
/*==========================*/
{
- buf_pool_stat_t stat;
- ulint LRU_len;
- ulint free_len;
- ulint flush_list_len;
- ulint mem_adaptive_hash, mem_dictionary;
- read_view_t* oldest_view;
- ulint i;
+ buf_pool_stat_t stat;
+ buf_pools_list_size_t buf_pools_list_size;
+ ulint LRU_len;
+ ulint free_len;
+ ulint flush_list_len;
+ ulint mem_adaptive_hash, mem_dictionary;
+ read_view_t* oldest_view;
+ ulint i;
buf_get_total_stat(&stat);
buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len);
+ buf_get_total_list_size_in_bytes(&buf_pools_list_size);
if (btr_search_sys && btr_search_sys->hash_index[0]->heap) {
mem_adaptive_hash = mem_heap_get_size(btr_search_sys->hash_index[0]->heap);
@@ -2467,7 +2495,12 @@ srv_export_innodb_status(void)
export_vars.innodb_buffer_pool_read_ahead_evicted
= stat.n_ra_pages_evicted;
export_vars.innodb_buffer_pool_pages_data = LRU_len;
+ export_vars.innodb_buffer_pool_bytes_data =
+ buf_pools_list_size.LRU_bytes
+ + buf_pools_list_size.unzip_LRU_bytes;
export_vars.innodb_buffer_pool_pages_dirty = flush_list_len;
+ export_vars.innodb_buffer_pool_bytes_dirty =
+ buf_pools_list_size.flush_list_bytes;
export_vars.innodb_buffer_pool_pages_free = free_len;
export_vars.innodb_deadlocks = srv_n_lock_deadlock_count;
#ifdef UNIV_DEBUG
@@ -2600,6 +2633,23 @@ srv_export_innodb_status(void)
export_vars.innodb_rows_deleted = srv_n_rows_deleted;
export_vars.innodb_truncated_status_writes = srv_truncated_status_writes;
+#ifdef UNIV_DEBUG
+ if (trx_sys->max_trx_id < purge_sys->done_trx_no) {
+ export_vars.innodb_purge_trx_id_age = 0;
+ } else {
+ export_vars.innodb_purge_trx_id_age =
+ trx_sys->max_trx_id - purge_sys->done_trx_no;
+ }
+
+ if (!purge_sys->view
+ || trx_sys->max_trx_id < purge_sys->view->up_limit_id) {
+ export_vars.innodb_purge_view_trx_id_age = 0;
+ } else {
+ export_vars.innodb_purge_view_trx_id_age =
+ trx_sys->max_trx_id - purge_sys->view->up_limit_id;
+ }
+#endif /* UNIV_DEBUG */
+
mutex_exit(&srv_innodb_monitor_mutex);
}
@@ -3223,11 +3273,19 @@ srv_redo_log_follow_thread(
os_event_reset(srv_checkpoint_completed_event);
if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) {
- log_online_follow_redo_log();
+ if (!log_online_follow_redo_log()) {
+ /* TODO: sync with I_S log tracking status? */
+ fprintf(stderr,
+ "InnoDB: Error: log tracking bitmap "
+ "write failed, stopping log tracking "
+ "thread!\n");
+ break;
+ }
}
} while (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE);
+ srv_track_changed_pages = FALSE;
log_online_read_shutdown();
os_event_set(srv_redo_log_thread_finished_event);
@@ -3472,6 +3530,26 @@ loop:
for (i = 0; i < 10; i++) {
ulint cur_time = ut_time_ms();
+#ifdef UNIV_DEBUG
+ if (btr_cur_limit_optimistic_insert_debug
+ && srv_n_purge_threads == 0) {
+ /* If btr_cur_limit_optimistic_insert_debug is enabled
+ and no purge_threads, purge opportunity is increased
+ by x100 (1purge/100msec), to speed up debug scripts
+ which should wait for purged. */
+ next_itr_time -= 900;
+
+ srv_main_thread_op_info = "master purging";
+
+ srv_master_do_purge();
+
+ if (srv_fast_shutdown && srv_shutdown_state > 0) {
+
+ goto background_loop;
+ }
+ }
+#endif /* UNIV_DEBUG */
+
n_pages_flushed = 0; /* initialize */
/* ALTER TABLE in MySQL requires on Unix that the table handler
@@ -3630,8 +3708,7 @@ loop:
buf_pool = buf_pool_from_array(j);
- /* The scanning flush_list is optimistic here */
-
+ buf_flush_list_mutex_enter(buf_pool);
level = 0;
n_blocks = 0;
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
@@ -3645,6 +3722,7 @@ loop:
bpage = UT_LIST_GET_NEXT(flush_list, bpage);
n_blocks++;
}
+ buf_flush_list_mutex_exit(buf_pool);
if (level) {
bpl += ((ib_uint64_t) n_blocks * n_blocks
@@ -3710,30 +3788,25 @@ retry_flush_batch:
/* prev_flush_info[j] should be the previous loop's */
for (j = 0; j < srv_buf_pool_instances; j++) {
- lint blocks_num, new_blocks_num, flushed_blocks_num;
- ibool found;
+ lint blocks_num, new_blocks_num = 0;
+ lint flushed_blocks_num;
buf_pool = buf_pool_from_array(j);
+ buf_flush_list_mutex_enter(buf_pool);
blocks_num = UT_LIST_GET_LEN(buf_pool->flush_list);
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
- new_blocks_num = 0;
- found = FALSE;
while (bpage != NULL) {
if (prev_flush_info[j].space == bpage->space
&& prev_flush_info[j].offset == bpage->offset
&& prev_flush_info[j].oldest_modification
== bpage->oldest_modification) {
- found = TRUE;
break;
}
bpage = UT_LIST_GET_NEXT(flush_list, bpage);
new_blocks_num++;
}
- if (!found) {
- new_blocks_num = blocks_num;
- }
flushed_blocks_num = new_blocks_num + prev_flush_info[j].count
- blocks_num;
@@ -3748,7 +3821,9 @@ retry_flush_batch:
prev_flush_info[j].space = bpage->space;
prev_flush_info[j].offset = bpage->offset;
prev_flush_info[j].oldest_modification = bpage->oldest_modification;
+ buf_flush_list_mutex_exit(buf_pool);
} else {
+ buf_flush_list_mutex_exit(buf_pool);
prev_flush_info[j].space = 0;
prev_flush_info[j].offset = 0;
prev_flush_info[j].oldest_modification = 0;
@@ -3774,6 +3849,7 @@ retry_flush_batch:
/* store previous first pages of the flush_list */
for (j = 0; j < srv_buf_pool_instances; j++) {
buf_pool = buf_pool_from_array(j);
+ buf_flush_list_mutex_enter(buf_pool);
bpage = UT_LIST_GET_FIRST(buf_pool->flush_list);
@@ -3782,7 +3858,9 @@ retry_flush_batch:
prev_flush_info[j].space = bpage->space;
prev_flush_info[j].offset = bpage->offset;
prev_flush_info[j].oldest_modification = bpage->oldest_modification;
+ buf_flush_list_mutex_exit(buf_pool);
} else {
+ buf_flush_list_mutex_exit(buf_pool);
prev_flush_info[j].space = 0;
prev_flush_info[j].offset = 0;
prev_flush_info[j].oldest_modification = 0;
diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c
index 2faa68cb87c..9e0477253cd 100644
--- a/storage/xtradb/srv/srv0start.c
+++ b/storage/xtradb/srv/srv0start.c
@@ -1155,6 +1155,11 @@ void
init_log_online(void)
/*=================*/
{
+ if (UNIV_UNLIKELY(srv_force_recovery > 0)) {
+ srv_track_changed_pages = FALSE;
+ return;
+ }
+
if (srv_track_changed_pages) {
log_online_read_init();
diff --git a/storage/xtradb/trx/trx0purge.c b/storage/xtradb/trx/trx0purge.c
index 122aab119ba..b048dc66efe 100644
--- a/storage/xtradb/trx/trx0purge.c
+++ b/storage/xtradb/trx/trx0purge.c
@@ -61,6 +61,10 @@ UNIV_INTERN mysql_pfs_key_t trx_purge_latch_key;
UNIV_INTERN mysql_pfs_key_t purge_sys_bh_mutex_key;
#endif /* UNIV_PFS_MUTEX */
+#ifdef UNIV_DEBUG
+UNIV_INTERN my_bool srv_purge_view_update_only_debug;
+#endif /* UNIV_DEBUG */
+
/*****************************************************************//**
Checks if trx_id is >= purge_view: then it is guaranteed that its update
undo log still exists in the system.
@@ -236,6 +240,7 @@ trx_purge_sys_create(
purge_sys->purge_trx_no = 0;
purge_sys->purge_undo_no = 0;
purge_sys->next_stored = FALSE;
+ ut_d(purge_sys->done_trx_no = 0);
rw_lock_create(trx_purge_latch_key,
&purge_sys->latch, SYNC_PURGE_LATCH);
@@ -656,6 +661,12 @@ trx_purge_truncate_if_arr_empty(void)
{
static ulint count;
+#ifdef UNIV_DEBUG
+ if (purge_sys->arr->n_used == 0) {
+ purge_sys->done_trx_no = purge_sys->purge_trx_no;
+ }
+#endif /* UNIV_DEBUG */
+
if (!(++count % TRX_SYS_N_RSEGS) && purge_sys->arr->n_used == 0) {
trx_purge_truncate_history();
@@ -1172,6 +1183,12 @@ trx_purge(
rw_lock_x_unlock(&(purge_sys->latch));
+#ifdef UNIV_DEBUG
+ if (srv_purge_view_update_only_debug) {
+ return(0);
+ }
+#endif
+
purge_sys->state = TRX_PURGE_ON;
purge_sys->handle_limit = purge_sys->n_pages_handled + limit;
diff --git a/storage/xtradb/trx/trx0rec.c b/storage/xtradb/trx/trx0rec.c
index db4897c368d..ef42152aeb7 100644
--- a/storage/xtradb/trx/trx0rec.c
+++ b/storage/xtradb/trx/trx0rec.c
@@ -36,6 +36,7 @@ Created 3/26/1996 Heikki Tuuri
#ifndef UNIV_HOTBACKUP
#include "dict0dict.h"
#include "ut0mem.h"
+#include "read0read.h"
#include "row0ext.h"
#include "row0upd.h"
#include "que0que.h"
@@ -1647,6 +1648,25 @@ trx_undo_prev_version_build(
if (row_upd_changes_field_size_or_external(index, offsets, update)) {
ulint n_ext;
+ /* We should confirm the existence of disowned external data,
+ if the previous version record is delete marked. If the trx_id
+ of the previous record is seen by purge view, we should treat
+ it as missing history, because the disowned external data
+ might be purged already.
+
+ The inherited external data (BLOBs) can be freed (purged)
+ after trx_id was committed, provided that no view was started
+ before trx_id. If the purge view can see the committed
+ delete-marked record by trx_id, no transactions need to access
+ the BLOB. */
+
+ if ((update->info_bits & REC_INFO_DELETED_FLAG)
+ && read_view_sees_trx_id(purge_sys->view, trx_id)) {
+ /* treat as a fresh insert, not to
+ cause assertion error at the caller. */
+ return(DB_SUCCESS);
+ }
+
/* We have to set the appropriate extern storage bits in the
old version of the record: the extern bits in rec for those
fields that update does NOT update, as well as the bits for
diff --git a/storage/xtradb/trx/trx0trx.c b/storage/xtradb/trx/trx0trx.c
index e6c72c09184..9d598db43ba 100644
--- a/storage/xtradb/trx/trx0trx.c
+++ b/storage/xtradb/trx/trx0trx.c
@@ -238,7 +238,7 @@ trx_allocate_for_mysql(void)
mutex_exit(&kernel_mutex);
- if (innobase_get_slow_log() && trx->take_stats) {
+ if (UNIV_UNLIKELY(trx->take_stats)) {
trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
}
@@ -1290,7 +1290,7 @@ trx_end_lock_wait(
thr = UT_LIST_GET_FIRST(trx->wait_thrs);
}
- if (innobase_get_slow_log() && trx->take_stats) {
+ if (UNIV_UNLIKELY(trx->take_stats)) {
ut_usectime(&sec, &ms);
now = (ib_uint64_t)sec * 1000000 + ms;
trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
@@ -1325,7 +1325,7 @@ trx_lock_wait_to_suspended(
thr = UT_LIST_GET_FIRST(trx->wait_thrs);
}
- if (innobase_get_slow_log() && trx->take_stats) {
+ if (UNIV_UNLIKELY(trx->take_stats)) {
ut_usectime(&sec, &ms);
now = (ib_uint64_t)sec * 1000000 + ms;
trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
diff --git a/strings/decimal.c b/strings/decimal.c
index f318a234d3f..3245f224b44 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1445,7 +1445,9 @@ int decimal_bin_size(int precision, int scale)
intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1,
intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1;
- DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= precision);
+ DBUG_ASSERT(scale >= 0);
+ DBUG_ASSERT(precision > 0);
+ DBUG_ASSERT(scale <= precision);
return intg0*sizeof(dec1)+dig2bytes[intg0x]+
frac0*sizeof(dec1)+dig2bytes[frac0x];
}
diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c
index 55d907acf1c..3ac4156da22 100644
--- a/strings/my_vsnprintf.c
+++ b/strings/my_vsnprintf.c
@@ -343,6 +343,7 @@ start:
print_arr[idx].length--;
DBUG_ASSERT(*fmt == '$' && print_arr[idx].length < MAX_ARGS);
args_arr[print_arr[idx].length].arg_type= 'd';
+ args_arr[print_arr[idx].length].have_longlong= 0;
print_arr[idx].flags|= LENGTH_ARG;
arg_count= max(arg_count, print_arr[idx].length + 1);
fmt++;
@@ -361,6 +362,7 @@ start:
print_arr[idx].width--;
DBUG_ASSERT(*fmt == '$' && print_arr[idx].width < MAX_ARGS);
args_arr[print_arr[idx].width].arg_type= 'd';
+ args_arr[print_arr[idx].width].have_longlong= 0;
print_arr[idx].flags|= WIDTH_ARG;
arg_count= max(arg_count, print_arr[idx].width + 1);
fmt++;
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index fa21775aa14..1fcb9be71da 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -392,7 +392,6 @@ For a description of MySQL see the base MySQL RPM or http://www.mysql.com/
Summary: MySQL - Shared libraries
Group: Applications/Databases
Provides: MySQL-shared
-Conflicts: mysql-libs mysql-libs-advanced
Obsoletes: MySQL-shared-standard MySQL-shared-pro
Obsoletes: MySQL-shared-pro-cert MySQL-shared-pro-gpl
Obsoletes: MySQL-shared-pro-gpl-cert MySQL-shared
diff --git a/support-files/rpm/server-postin.sh b/support-files/rpm/server-postin.sh
index 156865b61ad..b5ba10bd265 100644
--- a/support-files/rpm/server-postin.sh
+++ b/support-files/rpm/server-postin.sh
@@ -5,41 +5,46 @@ if [ $1 = 1 ] ; then
/sbin/chkconfig --add mysql
fi
- mysql_dirs=(`%{_sbindir}/mysqld --verbose --help 2>/dev/null|sed -ne 's/^\(basedir\|datadir\)[[:space:]]*\(.*\)$/\2/p'`)
- basedir="${mysql_dirs[0]}"
- datadir="${mysql_dirs[1]}"
- # datadir may be relative to a basedir!
- if expr $datadir : / > /dev/null; then
- mysql_datadir=$datadir
+ basedir=`%{_bindir}/my_print_defaults --mysqld|sed -ne 's/^--basedir=//p'|tail -1`
+ if [ -z "$basedir" ] ; then
+ basedir=%{mysqlbasedir}
+ fi
+
+ datadir=`%{_bindir}/my_print_defaults --mysqld|sed -ne 's/^--datadir=//p'|tail -1`
+ if [ -z "$datadir" ] ; then
+ datadir=%{mysqldatadir}
else
- mysql_datadir=$basedir/$datadir
+ # datadir may be relative to a basedir!
+ if ! expr $datadir : / > /dev/null; then
+ datadir=$basedir/$datadir
+ fi
fi
# Create a MySQL user and group. Do not report any problems if it already
# exists.
groupadd -r %{mysqld_group} 2> /dev/null || true
- useradd -M -r -d $mysql_datadir -s /bin/bash -c "MySQL server" -g %{mysqld_group} %{mysqld_user} 2> /dev/null || true
+ useradd -M -r -d $datadir -s /bin/bash -c "MySQL server" -g %{mysqld_group} %{mysqld_user} 2> /dev/null || true
# The user may already exist, make sure it has the proper group nevertheless (BUG#12823)
usermod -g %{mysqld_group} %{mysqld_user} 2> /dev/null || true
# Change permissions so that the user that will run the MySQL daemon
# owns all database files.
- chown -R %{mysqld_user}:%{mysqld_group} $mysql_datadir
+ chown -R %{mysqld_user}:%{mysqld_group} $datadir
- if [ ! -e $mysql_datadir ]; then
+ if [ ! -e $datadir ]; then
# Create data directory
- mkdir -p $mysql_datadir/{mysql,test}
+ mkdir -p $datadir/{mysql,test}
# Initiate databases
%{_bindir}/mysql_install_db --rpm --user=%{mysqld_user}
fi
# Change permissions again to fix any new files.
- chown -R %{mysqld_user}:%{mysqld_group} $mysql_datadir
+ chown -R %{mysqld_user}:%{mysqld_group} $datadir
# Fix permissions for the permission database so that only the user
# can read them.
- chmod -R og-rw $mysql_datadir/mysql
+ chmod -R og-rw $datadir/mysql
fi
# install SELinux files - but don't override existing ones