summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2011-11-12 19:56:29 +0400
committerAlexey Botchkov <holyfoot@askmonty.org>2011-11-12 19:56:29 +0400
commit7c7269d3723a4044816b1f80424af0ff2bc56f3f (patch)
tree877f14dd7dcbe276aa07dc26cbe63541bc893aff
parent45bb808c7ec0a77bb51038ff370753f8ed5c7ddf (diff)
parentdb0aed93482759844af7b39c9bf6e7fe141f28f6 (diff)
downloadmariadb-git-7c7269d3723a4044816b1f80424af0ff2bc56f3f.tar.gz
merging.
-rw-r--r--.bzrignore13
-rwxr-xr-xCMakeLists.txt57
-rw-r--r--INSTALL-WIN-SOURCE289
-rw-r--r--client/client_priv.h2
-rw-r--r--client/mysql.cc59
-rw-r--r--client/mysqlbinlog.cc14
-rw-r--r--client/mysqlcheck.c30
-rw-r--r--client/mysqldump.c15
-rw-r--r--client/mysqlslap.c18
-rw-r--r--client/mysqltest.cc3
-rw-r--r--client/readline.cc2
-rw-r--r--configure.in4
-rw-r--r--extra/comp_err.c2
-rw-r--r--include/Makefile.am1
-rw-r--r--include/config-win.h3
-rw-r--r--include/ma_dyncol.h12
-rw-r--r--include/maria.h2
-rw-r--r--include/my_compare.h5
-rw-r--r--include/my_dir.h4
-rw-r--r--include/my_global.h41
-rw-r--r--include/my_pthread.h78
-rw-r--r--include/my_sys.h28
-rw-r--r--include/myisam.h2
-rw-r--r--include/myisamchk.h7
-rw-r--r--include/mysql.h3
-rw-r--r--include/mysql.h.pp9
-rw-r--r--include/mysql/plugin.h31
-rw-r--r--include/mysql/plugin_auth.h.pp23
-rw-r--r--include/mysql/service_progress_report.h82
-rw-r--r--include/mysql/services.h1
-rw-r--r--include/mysql_com.h13
-rw-r--r--include/service_versions.h1
-rw-r--r--include/sql_common.h6
-rw-r--r--include/typelib.h2
-rwxr-xr-xlibmysql/CMakeLists.txt1
-rw-r--r--libmysqld/CMakeLists.txt27
-rw-r--r--libservices/CMakeLists.txt3
-rw-r--r--libservices/Makefile.am3
-rw-r--r--libservices/progress_report_service.c17
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_annotate.test12
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_func003.test27
-rw-r--r--mysql-test/include/default_mysqld.cnf2
-rw-r--r--mysql-test/include/icp_tests.inc519
-rw-r--r--mysql-test/include/ps_query.inc1
-rw-r--r--mysql-test/lib/mtr_cases.pm166
-rwxr-xr-xmysql-test/lib/v1/mysql-test-run.pl14
-rwxr-xr-xmysql-test/mysql-test-run.pl49
-rw-r--r--mysql-test/r/case.result7
-rw-r--r--mysql-test/r/cast.result11
-rw-r--r--mysql-test/r/comments.result14
-rw-r--r--mysql-test/r/create.result12
-rw-r--r--mysql-test/r/ctype_collate.result12
-rw-r--r--mysql-test/r/derived.result56
-rw-r--r--mysql-test/r/derived_opt.result276
-rw-r--r--mysql-test/r/derived_view.result1273
-rw-r--r--mysql-test/r/explain.result19
-rw-r--r--mysql-test/r/feedback_plugin_install.result13
-rw-r--r--mysql-test/r/feedback_plugin_load.result11
-rw-r--r--mysql-test/r/feedback_plugin_send.result15
-rw-r--r--mysql-test/r/fulltext.result8
-rw-r--r--mysql-test/r/func_group.result12
-rw-r--r--mysql-test/r/func_in.result73
-rw-r--r--mysql-test/r/func_str.result10
-rw-r--r--mysql-test/r/func_time.result4
-rw-r--r--mysql-test/r/group_by.result19
-rw-r--r--mysql-test/r/group_min_max.result14
-rw-r--r--mysql-test/r/having.result24
-rw-r--r--mysql-test/r/index_intersect.result44
-rw-r--r--mysql-test/r/index_merge_innodb.result6
-rw-r--r--mysql-test/r/index_merge_myisam.result49
-rw-r--r--mysql-test/r/information_schema.result3
-rw-r--r--mysql-test/r/innodb.result8
-rw-r--r--mysql-test/r/innodb_bug878769.result57
-rw-r--r--mysql-test/r/innodb_icp.result502
-rw-r--r--mysql-test/r/innodb_mrr.result8
-rw-r--r--mysql-test/r/innodb_mrr_cpk.result3
-rw-r--r--mysql-test/r/innodb_no_mrricp.result3316
-rw-r--r--mysql-test/r/innodb_release_row_locks_early.result104
-rw-r--r--mysql-test/r/join.result29
-rw-r--r--mysql-test/r/join_cache.result264
-rw-r--r--mysql-test/r/join_nested.result99
-rw-r--r--mysql-test/r/join_nested_jcl6.result118
-rw-r--r--mysql-test/r/join_outer.result115
-rw-r--r--mysql-test/r/join_outer_jcl6.result117
-rw-r--r--mysql-test/r/key_cache.result2
-rw-r--r--mysql-test/r/kill.result24
-rw-r--r--mysql-test/r/maria_icp.result508
-rw-r--r--mysql-test/r/maria_mrr.result20
-rw-r--r--mysql-test/r/merge.result2
-rw-r--r--mysql-test/r/mix2_myisam.result8
-rw-r--r--mysql-test/r/mrr_icp_extra.result892
-rw-r--r--mysql-test/r/myisam.result32
-rw-r--r--mysql-test/r/myisam_icp.result574
-rw-r--r--mysql-test/r/myisam_mrr.result66
-rw-r--r--mysql-test/r/mysql.result10
-rw-r--r--mysql-test/r/mysqldump.result84
-rw-r--r--mysql-test/r/negation_elimination.result121
-rw-r--r--mysql-test/r/null.result4
-rw-r--r--mysql-test/r/null_key.result2
-rw-r--r--mysql-test/r/old-mode.result3
-rw-r--r--mysql-test/r/optimizer_switch.result36
-rw-r--r--mysql-test/r/order_by.result23
-rw-r--r--mysql-test/r/partition_error.result5
-rw-r--r--mysql-test/r/partition_pruning.result5
-rw-r--r--mysql-test/r/plugin_innodb.result11
-rw-r--r--mysql-test/r/ps.result3
-rw-r--r--mysql-test/r/ps_1general.result4
-rw-r--r--mysql-test/r/ps_2myisam.result2
-rw-r--r--mysql-test/r/ps_ddl.result12
-rw-r--r--mysql-test/r/range.result132
-rw-r--r--mysql-test/r/range_mrr_icp.result1826
-rw-r--r--mysql-test/r/range_vs_index_merge.result141
-rw-r--r--mysql-test/r/range_vs_index_merge_innodb.result123
-rw-r--r--mysql-test/r/select.result113
-rw-r--r--mysql-test/r/select_jcl6.result45
-rw-r--r--mysql-test/r/select_pkeycache.result113
-rw-r--r--mysql-test/r/select_safe.result6
-rw-r--r--mysql-test/r/sp-threads.result10
-rw-r--r--mysql-test/r/sp.result6
-rw-r--r--mysql-test/r/status.result62
-rw-r--r--mysql-test/r/status_user.result36
-rw-r--r--mysql-test/r/subselect.result606
-rw-r--r--mysql-test/r/subselect2.result17
-rw-r--r--mysql-test/r/subselect3.result35
-rw-r--r--mysql-test/r/subselect3_jcl6.result37
-rw-r--r--mysql-test/r/subselect4.result475
-rw-r--r--mysql-test/r/subselect_cache.result74
-rw-r--r--mysql-test/r/subselect_extra.result475
-rw-r--r--mysql-test/r/subselect_extra_no_semijoin.result480
-rw-r--r--mysql-test/r/subselect_innodb.result61
-rw-r--r--mysql-test/r/subselect_mat.result573
-rw-r--r--mysql-test/r/subselect_mat_cost.result4334
-rw-r--r--mysql-test/r/subselect_mat_cost_bugs.result107
-rw-r--r--mysql-test/r/subselect_no_mat.result607
-rw-r--r--mysql-test/r/subselect_no_opts.result646
-rw-r--r--mysql-test/r/subselect_no_scache.result5673
-rw-r--r--mysql-test/r/subselect_no_semijoin.result604
-rw-r--r--mysql-test/r/subselect_nulls.result3
-rw-r--r--mysql-test/r/subselect_partial_match.result333
-rw-r--r--mysql-test/r/subselect_sj.result716
-rw-r--r--mysql-test/r/subselect_sj2.result147
-rw-r--r--mysql-test/r/subselect_sj2_jcl6.result151
-rw-r--r--mysql-test/r/subselect_sj2_mat.result159
-rw-r--r--mysql-test/r/subselect_sj_jcl6.result721
-rw-r--r--mysql-test/r/subselect_sj_mat.result461
-rw-r--r--mysql-test/r/subselect_sj_nonmerged.result5
-rw-r--r--mysql-test/r/system_mysql_db.result2
-rw-r--r--mysql-test/r/table_elim.result13
-rw-r--r--mysql-test/r/trigger.result19
-rw-r--r--mysql-test/r/user_limits-2.result2
-rw-r--r--mysql-test/r/user_limits.result37
-rw-r--r--mysql-test/r/variables-big.result20
-rw-r--r--mysql-test/r/variables.result5
-rw-r--r--mysql-test/r/view.result202
-rw-r--r--mysql-test/suite/binlog/r/binlog_row_annotate.result4
-rw-r--r--mysql-test/suite/binlog/t/binlog_row_annotate.test22
-rw-r--r--mysql-test/suite/funcs_1/datadict/datadict_priv.inc2
-rw-r--r--mysql-test/suite/funcs_1/datadict/processlist_priv.inc2
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_is.result7
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_is_embedded.result333
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_mysql.result4
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result29
-rw-r--r--mysql-test/suite/funcs_1/r/is_tables_is_embedded.result460
-rw-r--r--mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result246
-rw-r--r--mysql-test/suite/funcs_1/r/processlist_priv_ps.result304
-rw-r--r--mysql-test/suite/funcs_1/r/processlist_val_no_prot.result93
-rw-r--r--mysql-test/suite/funcs_1/r/processlist_val_ps.result293
-rw-r--r--mysql-test/suite/innodb/r/innodb.result6
-rw-r--r--mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result4
-rw-r--r--mysql-test/suite/innodb/r/innodb_mysql.result40
-rw-r--r--mysql-test/suite/innodb/t/innodb_mysql.test44
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result4
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb_mysql.result37
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb_bug52663.test2
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb_mysql.test44
-rw-r--r--mysql-test/suite/maria/r/locking.result31
-rw-r--r--mysql-test/suite/maria/r/maria-recovery3.result2
-rw-r--r--mysql-test/suite/maria/r/maria.result48
-rw-r--r--mysql-test/suite/maria/r/maria3.result1
-rw-r--r--mysql-test/suite/maria/r/max_length.result56
-rw-r--r--mysql-test/suite/maria/r/small_blocksize.result33
-rw-r--r--mysql-test/suite/maria/t/locking.test43
-rw-r--r--mysql-test/suite/maria/t/maria.test13
-rw-r--r--mysql-test/suite/maria/t/max_length.test52
-rw-r--r--mysql-test/suite/maria/t/small_blocksize-master.opt1
-rw-r--r--mysql-test/suite/maria/t/small_blocksize.test34
-rw-r--r--mysql-test/suite/parts/r/partition_repair_myisam.result1
-rw-r--r--mysql-test/suite/pbxt/r/derived.result39
-rw-r--r--mysql-test/suite/pbxt/r/func_group.result2
-rw-r--r--mysql-test/suite/pbxt/r/func_in.result6
-rw-r--r--mysql-test/suite/pbxt/r/group_min_max.result8
-rw-r--r--mysql-test/suite/pbxt/r/join_nested.result5
-rw-r--r--mysql-test/suite/pbxt/r/key_diff.result16
-rw-r--r--mysql-test/suite/pbxt/r/limit.result2
-rw-r--r--mysql-test/suite/pbxt/r/negation_elimination.result10
-rw-r--r--mysql-test/suite/pbxt/r/null_key.result2
-rw-r--r--mysql-test/suite/pbxt/r/order_by.result2
-rw-r--r--mysql-test/suite/pbxt/r/partition_pruning.result2
-rw-r--r--mysql-test/suite/pbxt/r/pbxt_locking.result12
-rw-r--r--mysql-test/suite/pbxt/r/ps_1general.result4
-rw-r--r--mysql-test/suite/pbxt/r/range.result4
-rw-r--r--mysql-test/suite/pbxt/r/skip_name_resolve.result6
-rw-r--r--mysql-test/suite/pbxt/r/status.result10
-rw-r--r--mysql-test/suite/pbxt/r/subselect.result75
-rw-r--r--mysql-test/suite/pbxt/t/join_nested.test5
-rw-r--r--mysql-test/suite/pbxt/t/key_diff.test14
-rw-r--r--mysql-test/suite/pbxt/t/limit.test2
-rw-r--r--mysql-test/suite/pbxt/t/subselect.test5
-rw-r--r--mysql-test/suite/rpl/r/rpl_idempotency.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_annotate_do.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_row_annotate_dont.result2
-rw-r--r--mysql-test/suite/rpl/r/rpl_stm_000001.result2
-rw-r--r--mysql-test/suite/rpl/t/rpl_idempotency.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_annotate_do-slave.opt2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_annotate_do.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_annotate_dont.test2
-rw-r--r--mysql-test/suite/rpl/t/rpl_stm_000001.test7
-rw-r--r--mysql-test/suite/vcol/r/vcol_misc.result7
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_innodb.result17
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_myisam.result21
-rw-r--r--mysql-test/suite/vcol/t/vcol_misc.test3
-rw-r--r--mysql-test/t/case.test9
-rw-r--r--mysql-test/t/cast.test7
-rw-r--r--mysql-test/t/comments.test11
-rw-r--r--mysql-test/t/derived.test16
-rw-r--r--mysql-test/t/derived_opt.test206
-rw-r--r--mysql-test/t/derived_view.test1028
-rw-r--r--mysql-test/t/disabled.def1
-rw-r--r--mysql-test/t/explain.test2
-rw-r--r--mysql-test/t/feedback_plugin_install.opt1
-rw-r--r--mysql-test/t/feedback_plugin_install.test15
-rw-r--r--mysql-test/t/feedback_plugin_load.opt2
-rw-r--r--mysql-test/t/feedback_plugin_load.test10
-rw-r--r--mysql-test/t/feedback_plugin_send.test24
-rw-r--r--mysql-test/t/flush_read_lock_kill.test2
-rw-r--r--mysql-test/t/fulltext.test2
-rw-r--r--mysql-test/t/fulltext_plugin.test3
-rw-r--r--mysql-test/t/func_group.test7
-rw-r--r--mysql-test/t/func_in.test20
-rw-r--r--mysql-test/t/func_time.test2
-rw-r--r--mysql-test/t/group_by.test18
-rw-r--r--mysql-test/t/having.test25
-rw-r--r--mysql-test/t/index_merge_myisam.test24
-rw-r--r--mysql-test/t/innodb.test8
-rw-r--r--mysql-test/t/innodb_bug878769.test56
-rw-r--r--mysql-test/t/innodb_icp.test4
-rw-r--r--mysql-test/t/innodb_mrr.test5
-rw-r--r--mysql-test/t/innodb_mrr_cpk.test4
-rw-r--r--mysql-test/t/innodb_no_mrricp.test10
-rw-r--r--mysql-test/t/innodb_release_row_locks_early-master.opt1
-rw-r--r--mysql-test/t/innodb_release_row_locks_early.test136
-rw-r--r--mysql-test/t/join.test28
-rw-r--r--mysql-test/t/join_cache.test157
-rw-r--r--mysql-test/t/join_nested.test55
-rw-r--r--mysql-test/t/join_nested_jcl6.test11
-rw-r--r--mysql-test/t/join_outer.test103
-rw-r--r--mysql-test/t/join_outer_jcl6.test2
-rw-r--r--mysql-test/t/kill.test32
-rw-r--r--mysql-test/t/maria_icp.test4
-rw-r--r--mysql-test/t/maria_mrr.test16
-rw-r--r--mysql-test/t/mrr_icp_extra.test239
-rw-r--r--mysql-test/t/myisam.test8
-rw-r--r--mysql-test/t/myisam_icp.test66
-rw-r--r--mysql-test/t/myisam_mrr.test52
-rw-r--r--mysql-test/t/mysql.test9
-rw-r--r--mysql-test/t/mysqldump.test4
-rw-r--r--mysql-test/t/negation_elimination.test29
-rw-r--r--mysql-test/t/old-mode.test10
-rw-r--r--mysql-test/t/order_by.test1
-rw-r--r--mysql-test/t/partition_error.test6
-rw-r--r--mysql-test/t/partition_pruning.test1
-rw-r--r--mysql-test/t/plugin_innodb.test27
-rw-r--r--mysql-test/t/range.test60
-rw-r--r--mysql-test/t/range_mrr_icp.test7
-rwxr-xr-xmysql-test/t/range_vs_index_merge.test29
-rw-r--r--mysql-test/t/select.test19
-rw-r--r--mysql-test/t/select_jcl6.test2
-rw-r--r--mysql-test/t/select_safe.test2
-rw-r--r--mysql-test/t/status.test17
-rw-r--r--mysql-test/t/status_user.test20
-rw-r--r--mysql-test/t/subselect.test373
-rw-r--r--mysql-test/t/subselect2.test6
-rw-r--r--mysql-test/t/subselect3.test12
-rw-r--r--mysql-test/t/subselect3_jcl6.test2
-rw-r--r--mysql-test/t/subselect4.test409
-rw-r--r--mysql-test/t/subselect_cache.test86
-rw-r--r--mysql-test/t/subselect_extra.test393
-rw-r--r--mysql-test/t/subselect_extra_no_semijoin.test7
-rw-r--r--mysql-test/t/subselect_innodb.test63
-rw-r--r--mysql-test/t/subselect_mat.test57
-rw-r--r--mysql-test/t/subselect_mat_cost-master.opt1
-rw-r--r--mysql-test/t/subselect_mat_cost.test619
-rw-r--r--mysql-test/t/subselect_mat_cost_bugs.test88
-rw-r--r--mysql-test/t/subselect_no_mat.test1
-rw-r--r--mysql-test/t/subselect_no_opts.test5
-rw-r--r--mysql-test/t/subselect_no_scache.test11
-rw-r--r--mysql-test/t/subselect_no_semijoin.test4
-rw-r--r--mysql-test/t/subselect_nulls.test5
-rw-r--r--mysql-test/t/subselect_partial_match.test323
-rw-r--r--mysql-test/t/subselect_sj.test644
-rw-r--r--mysql-test/t/subselect_sj2.test129
-rw-r--r--mysql-test/t/subselect_sj2_jcl6.test2
-rw-r--r--mysql-test/t/subselect_sj2_mat.test1
-rw-r--r--mysql-test/t/subselect_sj_jcl6.test5
-rw-r--r--mysql-test/t/subselect_sj_mat.test481
-rw-r--r--mysql-test/t/subselect_sj_nonmerged.test3
-rw-r--r--mysql-test/t/table_elim.test3
-rw-r--r--mysql-test/t/table_elim_debug.test3
-rw-r--r--mysql-test/t/trigger.test25
-rw-r--r--mysql-test/t/user_limits-2.test11
-rw-r--r--mysql-test/t/user_limits-master.opt1
-rw-r--r--mysql-test/t/user_limits.test41
-rw-r--r--mysql-test/t/variables-master.opt1
-rw-r--r--mysql-test/t/variables.test5
-rw-r--r--mysql-test/t/view.test174
-rw-r--r--mysql-test/valgrind.supp9
-rw-r--r--mysys/CMakeLists.txt3
-rw-r--r--mysys/Makefile.am2
-rw-r--r--mysys/default_modify.c8
-rw-r--r--mysys/ma_dyncol.c129
-rw-r--r--mysys/mf_iocache.c13
-rw-r--r--mysys/my_chsize.c19
-rw-r--r--mysys/my_create.c15
-rw-r--r--mysys/my_dup.c6
-rw-r--r--mysys/my_file.c1
-rw-r--r--mysys/my_fopen.c48
-rw-r--r--mysys/my_fstream.c17
-rw-r--r--mysys/my_gethwaddr.c110
-rw-r--r--mysys/my_getopt.c6
-rw-r--r--mysys/my_init.c5
-rw-r--r--mysys/my_lib.c26
-rw-r--r--mysys/my_lock.c137
-rw-r--r--mysys/my_malloc.c6
-rw-r--r--mysys/my_mmap.c6
-rw-r--r--mysys/my_open.c238
-rw-r--r--mysys/my_pread.c93
-rw-r--r--mysys/my_quick.c22
-rw-r--r--mysys/my_read.c15
-rw-r--r--mysys/my_seek.c17
-rw-r--r--mysys/my_static.c4
-rw-r--r--mysys/my_sync.c2
-rw-r--r--mysys/my_wincond.c183
-rw-r--r--mysys/my_winerr.c123
-rw-r--r--mysys/my_winfile.c681
-rw-r--r--mysys/my_winthread.c15
-rw-r--r--mysys/my_write.c47
-rw-r--r--mysys/mysys_priv.h24
-rw-r--r--mysys/thr_mutex.c1
-rw-r--r--mysys/thr_rwlock.c160
-rw-r--r--plugin/feedback/CMakeLists.txt11
-rw-r--r--plugin/feedback/Makefile.am18
-rw-r--r--plugin/feedback/feedback.cc373
-rw-r--r--plugin/feedback/feedback.h67
-rw-r--r--plugin/feedback/plug.in28
-rw-r--r--plugin/feedback/sender_thread.cc301
-rw-r--r--plugin/feedback/url_base.cc51
-rw-r--r--plugin/feedback/url_http.cc303
-rw-r--r--plugin/feedback/utils.cc392
-rw-r--r--plugin/fulltext/CMakeLists.txt3
-rw-r--r--plugin/handler_socket/handlersocket/Makefile.am2
-rw-r--r--plugin/handler_socket/handlersocket/database.cpp8
-rw-r--r--plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp2
-rw-r--r--plugin/handler_socket/libhsclient/auto_addrinfo.hpp3
-rw-r--r--plugin/handler_socket/libhsclient/socket.cpp2
-rw-r--r--plugin/handler_socket/libhsclient/socket.hpp4
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.xs5
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.in (renamed from plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL)4
-rw-r--r--plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.installed2
-rw-r--r--plugin/handler_socket/plug.in1
-rwxr-xr-xscripts/CMakeLists.txt7
-rw-r--r--scripts/Makefile.am8
-rw-r--r--scripts/make_binary_distribution.sh2
-rwxr-xr-xscripts/make_win_bin_dist1
-rw-r--r--scripts/mysql_system_tables.sql2
-rw-r--r--scripts/mysql_system_tables_fix.sql5
-rwxr-xr-xscripts/mytop.sh2342
-rw-r--r--sql-bench/crash-me.sh45
-rw-r--r--sql-bench/limits/mysql.cfg27
-rw-r--r--sql-common/client.c136
-rw-r--r--sql/CMakeLists.txt4
-rw-r--r--sql/debug_sync.cc4
-rw-r--r--sql/discover.cc2
-rw-r--r--sql/event_scheduler.cc2
-rw-r--r--sql/field_conv.cc14
-rw-r--r--sql/filesort.cc31
-rw-r--r--sql/ha_ndbcluster_binlog.cc2
-rw-r--r--sql/ha_partition.cc10
-rw-r--r--sql/handler.cc35
-rw-r--r--sql/handler.h44
-rw-r--r--sql/item.cc162
-rw-r--r--sql/item.h76
-rw-r--r--sql/item_cmpfunc.cc220
-rw-r--r--sql/item_cmpfunc.h89
-rw-r--r--sql/item_func.cc12
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/item_geofunc.h1
-rw-r--r--sql/item_row.cc18
-rw-r--r--sql/item_row.h1
-rw-r--r--sql/item_strfunc.cc150
-rw-r--r--sql/item_subselect.cc377
-rw-r--r--sql/item_subselect.h185
-rw-r--r--sql/item_sum.cc15
-rw-r--r--sql/item_sum.h2
-rw-r--r--sql/item_timefunc.cc20
-rw-r--r--sql/lex.h2
-rw-r--r--sql/log.cc39
-rw-r--r--sql/log_event.cc3
-rw-r--r--sql/log_event.h2
-rw-r--r--sql/multi_range_read.cc25
-rw-r--r--sql/mysql_priv.h81
-rw-r--r--sql/mysqld.cc236
-rw-r--r--sql/opt_index_cond_pushdown.cc90
-rw-r--r--sql/opt_range.cc669
-rw-r--r--sql/opt_range.h11
-rw-r--r--sql/opt_subselect.cc621
-rw-r--r--sql/opt_subselect.h4
-rw-r--r--sql/opt_sum.cc26
-rw-r--r--sql/opt_table_elimination.cc2
-rw-r--r--sql/parse_file.cc4
-rw-r--r--sql/protocol.cc50
-rw-r--r--sql/protocol.h1
-rw-r--r--sql/records.cc27
-rw-r--r--sql/rpl_rli.h8
-rw-r--r--sql/scheduler.cc10
-rw-r--r--sql/set_var.cc67
-rw-r--r--sql/share/errmsg.txt8
-rw-r--r--sql/slave.cc10
-rw-r--r--sql/slave.h2
-rw-r--r--sql/sp.cc45
-rw-r--r--sql/sp.h16
-rw-r--r--sql/sp_head.cc10
-rw-r--r--sql/sp_head.h22
-rw-r--r--sql/sql_acl.cc63
-rw-r--r--sql/sql_base.cc75
-rw-r--r--sql/sql_cache.cc9
-rw-r--r--sql/sql_class.cc241
-rw-r--r--sql/sql_class.h147
-rw-r--r--sql/sql_connect.cc34
-rw-r--r--sql/sql_db.cc1
-rw-r--r--sql/sql_delete.cc41
-rw-r--r--sql/sql_derived.cc140
-rw-r--r--sql/sql_error.cc2
-rw-r--r--sql/sql_expression_cache.cc150
-rw-r--r--sql/sql_expression_cache.h23
-rw-r--r--sql/sql_insert.cc37
-rw-r--r--sql/sql_join_cache.cc103
-rw-r--r--sql/sql_join_cache.h1
-rw-r--r--sql/sql_lex.cc279
-rw-r--r--sql/sql_lex.h26
-rw-r--r--sql/sql_list.h34
-rw-r--r--sql/sql_load.cc56
-rw-r--r--sql/sql_parse.cc225
-rw-r--r--sql/sql_plugin.cc57
-rw-r--r--sql/sql_plugin_services.h11
-rw-r--r--sql/sql_prepare.cc14
-rw-r--r--sql/sql_repl.cc14
-rw-r--r--sql/sql_select.cc757
-rw-r--r--sql/sql_select.h40
-rw-r--r--sql/sql_show.cc70
-rw-r--r--sql/sql_table.cc43
-rw-r--r--sql/sql_union.cc6
-rw-r--r--sql/sql_update.cc39
-rw-r--r--sql/sql_view.cc18
-rw-r--r--sql/sql_yacc.yy60
-rw-r--r--sql/structs.h11
-rw-r--r--sql/table.cc38
-rw-r--r--sql/table.h7
-rw-r--r--storage/archive/archive_reader.c20
-rw-r--r--storage/archive/ha_archive.cc28
-rw-r--r--storage/blackhole/plug.in1
-rw-r--r--storage/csv/plug.in1
-rw-r--r--storage/heap/ha_heap.cc14
-rw-r--r--storage/heap/plug.in1
-rw-r--r--storage/innobase/handler/ha_innodb.cc22
-rw-r--r--storage/innobase/plug.in.disabled1
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc25
-rw-r--r--storage/innodb_plugin/plug.in1
-rw-r--r--storage/maria/CMakeLists.txt22
-rw-r--r--storage/maria/ha_maria.cc130
-rw-r--r--storage/maria/ha_maria.h1
-rw-r--r--storage/maria/ma_bitmap.c233
-rw-r--r--storage/maria/ma_blockrec.c83
-rw-r--r--storage/maria/ma_blockrec.h4
-rw-r--r--storage/maria/ma_check.c185
-rw-r--r--storage/maria/ma_check_standalone.h7
-rw-r--r--storage/maria/ma_checkpoint.c108
-rw-r--r--storage/maria/ma_close.c3
-rw-r--r--storage/maria/ma_create.c20
-rw-r--r--storage/maria/ma_delete.c27
-rw-r--r--storage/maria/ma_dynrec.c14
-rw-r--r--storage/maria/ma_extra.c11
-rw-r--r--storage/maria/ma_ft_update.c6
-rw-r--r--storage/maria/ma_info.c6
-rw-r--r--storage/maria/ma_key_recover.c3
-rw-r--r--storage/maria/ma_locking.c6
-rw-r--r--storage/maria/ma_loghandler.c11
-rw-r--r--storage/maria/ma_open.c73
-rw-r--r--storage/maria/ma_page.c1
-rw-r--r--storage/maria/ma_pagecache.c299
-rw-r--r--storage/maria/ma_recovery.c30
-rw-r--r--storage/maria/ma_recovery.h1
-rw-r--r--storage/maria/ma_rt_split.c2
-rw-r--r--storage/maria/ma_sort.c25
-rw-r--r--storage/maria/ma_write.c1
-rw-r--r--storage/maria/maria_chk.c26
-rw-r--r--storage/maria/maria_def.h13
-rw-r--r--storage/maria/maria_pack.c2
-rw-r--r--storage/maria/maria_read_log.c18
-rw-r--r--storage/maria/plug.in1
-rw-r--r--storage/maria/trnman.c1
-rw-r--r--storage/maria/unittest/CMakeLists.txt3
-rw-r--r--storage/myisam/CMakeLists.txt18
-rw-r--r--storage/myisam/ha_myisam.cc44
-rw-r--r--storage/myisam/ha_myisam.h2
-rw-r--r--storage/myisam/mi_check.c125
-rw-r--r--storage/myisam/mi_dbug.c3
-rw-r--r--storage/myisam/mi_locking.c8
-rw-r--r--storage/myisam/mi_test2.c1
-rw-r--r--storage/myisam/myisamchk.c1
-rw-r--r--storage/myisam/plug.in1
-rw-r--r--storage/myisam/sort.c4
-rw-r--r--storage/myisammrg/plug.in1
-rw-r--r--storage/mysql_storage_engine.cmake48
-rw-r--r--storage/ndb/plug.in1
-rw-r--r--storage/pbxt/plug.in1
-rw-r--r--storage/pbxt/src/database_xt.cc2
-rw-r--r--storage/pbxt/src/ha_pbxt.cc4
-rw-r--r--storage/pbxt/src/memory_xt.cc2
-rw-r--r--storage/pbxt/src/myxt_xt.cc15
-rwxr-xr-xstorage/pbxt/src/pthread_xt.cc39
-rw-r--r--storage/pbxt/src/restart_xt.cc29
-rw-r--r--storage/pbxt/src/tabcache_xt.cc5
-rw-r--r--storage/pbxt/src/table_xt.cc4
-rw-r--r--storage/pbxt/src/thread_xt.cc5
-rw-r--r--storage/pbxt/src/xactlog_xt.cc4
-rw-r--r--storage/sphinx/ha_sphinx.cc2
-rw-r--r--storage/xtradb/CMakeLists.txt17
-rw-r--r--storage/xtradb/btr/btr0cur.c5
-rw-r--r--storage/xtradb/buf/buf0buf.c4
-rw-r--r--storage/xtradb/dict/dict0dict.c13
-rw-r--r--storage/xtradb/handler/ha_innodb.cc715
-rw-r--r--storage/xtradb/handler/ha_innodb.h88
-rw-r--r--storage/xtradb/include/dict0dict.h14
-rw-r--r--storage/xtradb/include/dict0dict.ic14
-rw-r--r--storage/xtradb/include/ha_prototypes.h9
-rw-r--r--storage/xtradb/include/os0file.h8
-rw-r--r--storage/xtradb/include/os0sync.h71
-rw-r--r--storage/xtradb/include/os0sync.ic9
-rw-r--r--storage/xtradb/include/row0mysql.h29
-rw-r--r--storage/xtradb/include/srv0srv.h7
-rw-r--r--storage/xtradb/include/sync0sync.h2
-rw-r--r--storage/xtradb/include/trx0sys.ic9
-rw-r--r--storage/xtradb/os/os0file.c502
-rw-r--r--storage/xtradb/os/os0sync.c559
-rw-r--r--storage/xtradb/plug.in1
-rw-r--r--storage/xtradb/row/row0sel.c580
-rw-r--r--storage/xtradb/srv/srv0srv.c17
-rw-r--r--storage/xtradb/srv/srv0start.c31
-rw-r--r--support-files/mysql.spec.sh1
-rw-r--r--tests/mysql_client_test.c68
-rw-r--r--unittest/mysys/lf-t.c3
-rw-r--r--unittest/mysys/ma_dyncol-t.c240
-rw-r--r--win/README12
-rw-r--r--win/cmake/install_macros.cmake3
-rw-r--r--win/configure-mariadb.bat3
-rw-r--r--win/configure-mariadb.sh1
-rw-r--r--win/configure.js8
-rw-r--r--win/packaging/extra.wxs.in62
568 files changed, 47077 insertions, 11234 deletions
diff --git a/.bzrignore b/.bzrignore
index 685bcfff6b4..68f47a7f1f2 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -702,7 +702,6 @@ ma_test_recovery.output
man/*.1
maria-win.patch
maria_log.00000*
-maria_log_control
merge/*.ds?
merge/*.vcproj
missing
@@ -1969,3 +1968,15 @@ plugin/handler_socket/client/hsclient
client/strings_def.h
libmysql/strings_def.h
libmysql_r/strings_def.h
+storage/maria/aria_log_control
+scripts/mytop
+CPackConfig.cmake
+CPackSourceConfig.cmake
+win/nmake_cache.txt
+*.manifest
+*.resource.txt
+plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.c
+plugin/handler_socket/perl-Net-HandlerSocket/blib
+plugin/handler_socket/perl-Net-HandlerSocket/pm_to_blib
+plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.bs
+plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3c6a65505fe..438d859d3ae 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -39,6 +39,8 @@ SET(WITH_PARTITION_STORAGE_ENGINE 1 CACHE BOOL "Include partition storage engine
SET(WITH_ARIA_STORAGE_ENGINE 1 CACHE BOOL "Include aria storage engine")
SET(WITH_PBXT_STORAGE_ENGINE 1 CACHE BOOL "Include pbxt storage engine")
SET(WITH_XTRADB_STORAGE_ENGINE 1 CACHE BOOL "Include xtradb storage engine")
+SET(WITH_FEEDBACK_STORAGE_ENGINE 1 CACHE FORCE BOOL "Include feedback plugin")
+
IF(WIN32)
LINK_LIBRARIES(ws2_32)
# This reads user configuration, generated by configure.js.
@@ -59,7 +61,7 @@ IF (MSVC_VERSION GREATER 1400)
ENDIF()
-SET(CMAKE_INSTALL_PREFIX "C:/MariaDB${MYSQL_BASE_VERSION}")
+SET(CMAKE_INSTALL_PREFIX "C:/MariaDB${MYSQL_BASE_VERSION}" CACHE PATH "Default installation directory")
SET(INSTALL_ROOT "${CMAKE_INSTALL_PREFIX}")
# Set standard options
ADD_DEFINITIONS(-DHAVE_YASSL)
@@ -247,16 +249,15 @@ IF(WITHOUT_DYNAMIC_PLUGINS)
MESSAGE("Dynamic plugins are disabled.")
ENDIF(WITHOUT_DYNAMIC_PLUGINS)
-FILE(GLOB STORAGE_SUBDIRS storage/*)
+FILE(GLOB STORAGE_SUBDIRS storage/* plugin/*)
FOREACH(SUBDIR ${STORAGE_SUBDIRS})
- FILE(RELATIVE_PATH DIRNAME ${PROJECT_SOURCE_DIR}/storage ${SUBDIR})
IF (EXISTS ${SUBDIR}/CMakeLists.txt)
# Check MYSQL_STORAGE_ENGINE macro is present
- FILE(STRINGS ${SUBDIR}/CMakeLists.txt HAVE_STORAGE_ENGINE REGEX MYSQL_STORAGE_ENGINE)
+ FILE(STRINGS ${SUBDIR}/CMakeLists.txt HAVE_STORAGE_ENGINE REGEX "MYSQL_(STORAGE_ENGINE|PLUGIN)")
IF(HAVE_STORAGE_ENGINE)
# Extract name of engine from HAVE_STORAGE_ENGINE
- STRING(REGEX REPLACE ".*MYSQL_STORAGE_ENGINE\\((.*\)\\).*"
- "\\1" ENGINE_NAME ${HAVE_STORAGE_ENGINE})
+ STRING(REGEX REPLACE ".*MYSQL_(STORAGE_ENGINE|PLUGIN)\\((.*\)\\).*"
+ "\\2" ENGINE_NAME ${HAVE_STORAGE_ENGINE})
STRING(TOUPPER ${ENGINE_NAME} ENGINE)
STRING(TOLOWER ${ENGINE_NAME} ENGINE_LOWER)
@@ -265,21 +266,23 @@ FOREACH(SUBDIR ${STORAGE_SUBDIRS})
# build as shared library (dynamic).
IF(EXISTS ${SUBDIR}/plug.in)
FILE(READ ${SUBDIR}/plug.in PLUGIN_FILE_CONTENT)
- STRING (REGEX MATCH "MYSQL_PLUGIN_DYNAMIC" MYSQL_PLUGIN_DYNAMIC ${PLUGIN_FILE_CONTENT})
+ IF (PLUGIN_FILE_CONTENT MATCHES "MYSQL_PLUGIN_DYNAMIC\\(${ENGINE_LOWER}")
+ STRING (REGEX REPLACE
+ ".*MYSQL_PLUGIN_DYNAMIC\\(${ENGINE_LOWER},[ \\t]*\\[?([a-zA-Z0-9_]+/)*([a-zA-Z0-9_]+).*"
+ "\\2" MYSQL_PLUGIN_DYNAMIC ${PLUGIN_FILE_CONTENT})
+ ELSE (PLUGIN_FILE_CONTENT MATCHES "MYSQL_PLUGIN_DYNAMIC\\(${ENGINE_LOWER}")
+ SET (MYSQL_PLUGIN_DYNAMIC "")
+ ENDIF(PLUGIN_FILE_CONTENT MATCHES "MYSQL_PLUGIN_DYNAMIC\\(${ENGINE_LOWER}")
+ IF (PLUGIN_FILE_CONTENT MATCHES "MYSQL_PLUGIN_STATIC\\(${ENGINE_LOWER}")
+ STRING (REGEX REPLACE
+ ".*MYSQL_PLUGIN_STATIC\\(${ENGINE_LOWER},[ \\t]*\\[?([a-zA-Z0-9_]+/)*([a-zA-Z0-9_]+).*"
+ "\\2"
+ MYSQL_PLUGIN_STATIC ${PLUGIN_FILE_CONTENT})
+ ELSE (PLUGIN_FILE_CONTENT MATCHES "MYSQL_PLUGIN_STATIC\\(${ENGINE_LOWER}")
+ SET (MYSQL_PLUGIN_STATIC "")
+ ENDIF(PLUGIN_FILE_CONTENT MATCHES "MYSQL_PLUGIN_STATIC\\(${ENGINE_LOWER}")
STRING (REGEX MATCH "MYSQL_PLUGIN_MANDATORY" MYSQL_PLUGIN_MANDATORY ${PLUGIN_FILE_CONTENT})
- STRING (REGEX MATCH "MYSQL_PLUGIN_STATIC" MYSQL_PLUGIN_STATIC ${PLUGIN_FILE_CONTENT})
-
- #
- # XTRADB is located in storage/xtradb, but it says everywhere it is 'innobase' (e.g.
- # it declares 'builtin_innobase_plugin', not builtin_xtradb_plugin).
- # Extract the intended plugin name from MYSQL_STORAGE_ENGINE definition and use it
- # where appropriate.
- STRING (REGEX MATCH "MYSQL_STORAGE_ENGINE.[a-z]*" PLUGIN_NAME ${PLUGIN_FILE_CONTENT})
- STRING (REGEX REPLACE "MYSQL_STORAGE_ENGINE.(.*)" "\\1" PLUGIN_NAME ${PLUGIN_NAME})
- # Also remember this "xtradb"/"innobase" name discrepancy for libmysqld/CMakeLists.txt:
- SET (plugin_dir_${PLUGIN_NAME} ${DIRNAME})
-
IF(MYSQL_PLUGIN_MANDATORY)
SET(WITH_${ENGINE}_STORAGE_ENGINE TRUE)
ENDIF(MYSQL_PLUGIN_MANDATORY)
@@ -293,15 +296,17 @@ FOREACH(SUBDIR ${STORAGE_SUBDIRS})
ENDIF(WITH_${ENGINE}_STORAGE_ENGINE AND MYSQL_PLUGIN_STATIC)
IF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
- SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_${PLUGIN_NAME}_plugin")
- SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${PLUGIN_NAME})
+ SET (maria_plugin_defs "${maria_plugin_defs},builtin_maria_${ENGINE_LOWER}_plugin")
+ SET (MYSQLD_STATIC_ENGINE_LIBS ${MYSQLD_STATIC_ENGINE_LIBS} ${MYSQL_PLUGIN_STATIC})
+ SET (MYSQLD_STATIC_ENGINES ${MYSQLD_STATIC_ENGINES} ${ENGINE})
SET (STORAGE_ENGINE_DEFS "${STORAGE_ENGINE_DEFS} -DWITH_${ENGINE}_STORAGE_ENGINE")
SET (WITH_${ENGINE}_STORAGE_ENGINE TRUE)
- SET (${ENGINE}_DIR ${DIRNAME})
+ SET (${ENGINE}_DIR ${SUBDIR})
ENDIF (ENGINE_BUILD_TYPE STREQUAL "STATIC")
ENDIF(EXISTS ${SUBDIR}/plug.in)
IF(NOT ENGINE_BUILD_TYPE STREQUAL "NONE")
+ SET (${ENGINE}_LIB ${MYSQL_PLUGIN_${ENGINE_BUILD_TYPE}})
LIST(APPEND ${ENGINE_BUILD_TYPE}_ENGINE_DIRECTORIES ${SUBDIR})
ENDIF(NOT ENGINE_BUILD_TYPE STREQUAL "NONE")
@@ -318,10 +323,12 @@ ENDIF(NOT WITHOUT_PARTITION_STORAGE_ENGINE)
# Special handling for tmp tables with the Aria engine
IF(WITH_ARIA_STORAGE_ENGINE)
ADD_DEFINITIONS(-DWITH_ARIA_STORAGE_ENGINE)
- IF(WITH_MARIA_TMP_TABLES)
+ SET(WITH_ARIA_TMP_TABLES 1 CACHE BOOL "Use Aria for temporary tables")
+ IF(WITH_ARIA_TMP_TABLES)
+ MESSAGE(STATUS "Using Aria for temporary tables")
ADD_DEFINITIONS(-DUSE_MARIA_FOR_TMP_TABLES)
- ENDIF(WITH_MARIA_TMP_TABLES)
-ENDIF(WITH_ARIA_STORAGE_ENGINE)
+ ENDIF()
+ENDIF()
ADD_DEFINITIONS(${STORAGE_ENGINE_DEFS})
diff --git a/INSTALL-WIN-SOURCE b/INSTALL-WIN-SOURCE
index 8faf511936b..2e77959d69c 100644
--- a/INSTALL-WIN-SOURCE
+++ b/INSTALL-WIN-SOURCE
@@ -1,289 +1,2 @@
+Up-to-date instructions on MariaDB building on Windows can be found in http://kb.askmonty.org/en/building-mariadb-on-windows.
-2.5.10. Installing MySQL from Source on Windows
-
- These instructions describe how to build binaries from source for
- MySQL 5.1 on Windows. Instructions are provided for building
- binaries from a standard source distribution or from the Bazaar
- tree that contains the latest development source.
-
-Note
-
- The instructions here are strictly for users who want to test
- MySQL on Microsoft Windows from the latest source distribution or
- from the Bazaar tree. For production use, we do not advise using a
- MySQL server built by yourself from source. Normally, it is best
- to use precompiled binary distributions of MySQL that are built
- specifically for optimal performance on Windows by Oracle
- Corporation. Instructions for installing binary distributions are
- available in Section 2.5, "Installing MySQL on Windows."
-
- To build MySQL on Windows from source, you must satisfy the
- following system, compiler, and resource requirements:
-
- * Windows 2000, Windows XP, or newer version.
- Windows Vista is supported when using Visual Studio 2005
- provided you have installed the following updates:
-
- + Microsoft Visual Studio 2005 Professional Edition - ENU
- Service Pack 1 (KB926601)
- (http://support.microsoft.com/?kbid=926601)
-
- + Security Update for Microsoft Visual Studio 2005
- Professional Edition - ENU (KB937061)
- (http://support.microsoft.com/?kbid=937061)
-
- + Update for Microsoft Visual Studio 2005 Professional
- Edition - ENU (KB932232)
- (http://support.microsoft.com/?kbid=932232)
-
- * CMake, which can be downloaded from http://www.cmake.org.
- After installing, modify your path to include the cmake
- binary.
-
- * Microsoft Visual C++ 2005 Express Edition, Visual Studio .Net
- 2003 (7.1), or Visual Studio 2005 (8.0) compiler system.
-
- * If you are using Visual C++ 2005 Express Edition, you must
- also install an appropriate Platform SDK. More information and
- links to downloads for various Windows platforms is available
- from
- http://www.microsoft.com/downloads/details.aspx?familyid=0baf2
- b35-c656-4969-ace8-e4c0c0716adb.
-
- * If you are compiling from a Bazaar tree or making changes to
- the parser, you need bison for Windows, which can be
- downloaded from
- http://gnuwin32.sourceforge.net/packages/bison.htm. Download
- the package labeled "Complete package, excluding sources".
- After installing the package, modify your path to include the
- bison binary and ensure that this binary is accessible from
- Visual Studio.
-
- * Cygwin might be necessary if you want to run the test script
- or package the compiled binaries and support files into a Zip
- archive. (Cygwin is needed only to test or package the
- distribution, not to build it.) Cygwin is available from
- http://cygwin.com.
-
- * 3GB to 5GB of disk space.
-
- The exact system requirements for Visual Studio can be found here:
- http://msdn.microsoft.com/vstudio/Previous/2003/sysreqs/default.as
- px and
- http://msdn.microsoft.com/vstudio/products/sysreqs/default.aspx
-
- You also need a MySQL source distribution for Windows, which can
- be obtained two ways:
-
- * Obtain a source distribution packaged by Oracle Corporation.
- These are available from http://dev.mysql.com/downloads/.
-
- * Package a source distribution yourself from the latest Bazaar
- developer source tree. For instructions on pulling the latest
- source files, see Section 2.3.3, "Installing from the
- Development Source Tree."
-
- If you find something not working as expected, or you have
- suggestions about ways to improve the current build process on
- Windows, please send a message to the win32 mailing list. See
- Section 1.6.1, "MySQL Mailing Lists."
-
-2.5.10.1. Building MySQL from Source Using CMake and Visual Studio
-
- You can build MySQL on Windows by using a combination of cmake and
- Microsoft Visual Studio .NET 2003 (7.1), Microsoft Visual Studio
- 2005 (8.0), Microsoft Visual Studio 2008 (9.0) or Microsoft Visual
- C++ 2005 Express Edition. You must have the appropriate Microsoft
- Platform SDK installed.
-
-Note
-
- To compile from the source code on Windows you must use the
- standard source distribution (for example, mysql-5.1.46.tar.gz).
- You build from the same distribution as used to build MySQL on
- Unix, Linux and other platforms. Do not use the Windows Source
- distributions as they do not contain the necessary configuration
- script and other files.
-
- Follow this procedure to build MySQL:
-
- 1. If you are installing from a packaged source distribution,
- create a work directory (for example, C:\workdir), and unpack
- the source distribution there using WinZip or another Windows
- tool that can read .zip files. This directory is the work
- directory in the following instructions.
-
-Note
- You must run the commands in the win directory from the
- top-level source directory. Do not change into the win
- directory, as the commands will not be executed correctly.
-
- 2. Start a command shell. If you have not configured the PATH and
- other environment variables for all command shells, you may be
- able to start a command shell from the Start Menu within the
- Windows Visual Studio menu that contains the necessary
- environment changes.
-
- 3. Within the command shell, navigate to the work directory and
- run the following command:
-C:\workdir>win\configure.js options
- If you have associated the .js file extension with an
- application such as a text editor, then you may need to use
- the following command to force configure.js to be executed as
- a script:
-C:\workdir>cscript win\configure.js options
- These options are available for configure.js:
-
- + WITH_INNOBASE_STORAGE_ENGINE: Enable the InnoDB storage
- engine.
-
- + WITH_PARTITION_STORAGE_ENGINE: Enable user-defined
- partitioning.
-
- + WITH_ARCHIVE_STORAGE_ENGINE: Enable the ARCHIVE storage
- engine.
-
- + WITH_BLACKHOLE_STORAGE_ENGINE: Enable the BLACKHOLE
- storage engine.
-
- + WITH_EXAMPLE_STORAGE_ENGINE: Enable the EXAMPLE storage
- engine.
-
- + WITH_FEDERATED_STORAGE_ENGINE: Enable the FEDERATED
- storage engine.
-
- + WITH_NDBCLUSTER_STORAGE_ENGINE (experimental): Enable the
- NDBCLUSTER storage engine in the MySQL server; cause
- binaries for the MySQL Cluster management and data node,
- management client, and other programs to be built.
- This option is supported only in MySQL Cluster NDB 7.0
- (NDBCLUSTER storage engine versions 6.4.0 and later)
- using the MySQL Cluster sources. It cannot be used to
- enable clustering support in other MySQL source trees or
- distributions.
-
- + MYSQL_SERVER_SUFFIX=suffix: Server suffix, default none.
-
- + COMPILATION_COMMENT=comment: Server comment, default
- "Source distribution".
-
- + MYSQL_TCP_PORT=port: Server port, default 3306.
-
- + DISABLE_GRANT_OPTIONS: Disables the --bootstrap,
- --skip-grant-tables, and --init-file options for mysqld.
- This option is available as of MySQL 5.1.15.
- For example (type the command on one line):
-C:\workdir>win\configure.js WITH_INNOBASE_STORAGE_ENGINE
- WITH_PARTITION_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-pro
-
- 4. From the work directory, execute the win\build-vs9.bat
- (Windows Visual Studio 2008), win\build-vs8.bat (Windows
- Visual Studio 2005), or win\build-vs71.bat (Windows Visual
- Stidion 2003) script, depending on the version of Visual
- Studio you have installed. The script invokes CMake, which
- generates the mysql.sln solution file.
- You can also use the corresponding 64-bit file (for example
- win\build-vs8_x64.bat or win\build-vs9_x64.bat) to build the
- 64-bit version of MySQL. However, you cannot build the 64-bit
- version with Visual Studio Express Edition. You must use
- Visual Studio 2005 (8.0) or higher.
-
- 5. From the work directory, open the generated mysql.sln file
- with Visual Studio and select the proper configuration using
- the Configuration menu. The menu provides Debug, Release,
- RelwithDebInfo, MinRelInfo options. Then select Solution >
- Build to build the solution.
- Remember the configuration that you use in this step. It is
- important later when you run the test script because that
- script needs to know which configuration you used.
-
- 6. Test the server. The server built using the preceding
- instructions expects that the MySQL base directory and data
- directory are C:\mysql and C:\mysql\data by default. If you
- want to test your server using the source tree root directory
- and its data directory as the base directory and data
- directory, you need to tell the server their path names. You
- can either do this on the command line with the --basedir and
- --datadir options, or by placing appropriate options in an
- option file. (See Section 4.2.3.3, "Using Option Files.") If
- you have an existing data directory elsewhere that you want to
- use, you can specify its path name instead.
- When the server is running in standalone fashion or as a
- service based on your configuration, try to connect to it from
- the mysql interactive command-line utility.
- You can also run the standard test script, mysql-test-run.pl.
- This script is written in Perl, so you'll need either Cygwin
- or ActiveState Perl to run it. You may also need to install
- the modules required by the script. To run the test script,
- change location into the mysql-test directory under the work
- directory, set the MTR_VS_CONFIG environment variable to the
- configuration you selected earlier (or use the --vs-config
- option), and invoke mysql-test-run.pl. For example (using
- Cygwin and the bash shell):
-shell> cd mysql-test
-shell> export MTR_VS_CONFIG=debug
-shell> ./mysql-test-run.pl --force --timer
-shell> ./mysql-test-run.pl --force --timer --ps-protocol
-
- When you are satisfied that the programs you have built are
- working correctly, stop the server. Now you can install the
- distribution. One way to do this is to use the make_win_bin_dist
- script in the scripts directory of the MySQL source distribution
- (see Section 4.4.2, "make_win_bin_dist --- Package MySQL
- Distribution as ZIP Archive"). This is a shell script, so you must
- have Cygwin installed if you want to use it. It creates a Zip
- archive of the built executables and support files that you can
- unpack in the location at which you want to install MySQL.
-
- It is also possible to install MySQL by copying directories and
- files directly:
-
- 1. Create the directories where you want to install MySQL. For
- example, to install into C:\mysql, use these commands:
-C:\> mkdir C:\mysql
-C:\> mkdir C:\mysql\bin
-C:\> mkdir C:\mysql\data
-C:\> mkdir C:\mysql\share
-C:\> mkdir C:\mysql\scripts
- If you want to compile other clients and link them to MySQL,
- you should also create several additional directories:
-C:\> mkdir C:\mysql\include
-C:\> mkdir C:\mysql\lib
-C:\> mkdir C:\mysql\lib\debug
-C:\> mkdir C:\mysql\lib\opt
- If you want to benchmark MySQL, create this directory:
-C:\> mkdir C:\mysql\sql-bench
- Benchmarking requires Perl support. See Section 2.15, "Perl
- Installation Notes."
-
- 2. From the work directory, copy into the C:\mysql directory the
- following files and directories:
-C:\> cd \workdir
-C:\workdir> mkdir C:\mysql
-C:\workdir> mkdir C:\mysql\bin
-C:\workdir> copy client\Release\*.exe C:\mysql\bin
-C:\workdir> copy sql\Release\mysqld.exe C:\mysql\bin\mysqld.exe
-C:\workdir> xcopy scripts\*.* C:\mysql\scripts /E
-C:\workdir> xcopy share\*.* C:\mysql\share /E
- If you want to compile other clients and link them to MySQL,
- you should also copy several libraries and header files:
-C:\workdir> copy lib\Release\mysqlclient.lib C:\mysql\lib\debug
-C:\workdir> copy lib\Release\libmysql.* C:\mysql\lib\debug
-C:\workdir> copy lib\Release\zlib.* C:\mysql\lib\debug
-C:\workdir> copy lib\Release\mysqlclient.lib C:\mysql\lib\opt
-C:\workdir> copy lib\Release\libmysql.* C:\mysql\lib\opt
-C:\workdir> copy lib\Release\zlib.* C:\mysql\lib\opt
-C:\workdir> copy include\*.h C:\mysql\include
-C:\workdir> copy libmysql\libmysql.def C:\mysql\include
-
-Note
- If you have compiled a Debug, rather than Release solution,
- you can replace Release with Debug in the source file names
- shown above.
- If you want to benchmark MySQL, you should also do this:
-C:\workdir> xcopy sql-bench\*.* C:\mysql\bench /E
-
- After installation, set up and start the server in the same way as
- for binary Windows distributions. This includes creating the
- system tables by running mysql_install_db. For more information,
- see Section 2.5, "Installing MySQL on Windows."
diff --git a/client/client_priv.h b/client/client_priv.h
index ec67ed3ae2d..128a7beca6f 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -60,6 +60,7 @@ enum options_client
OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_SERVER_ARG,
OPT_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME,
OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY, OPT_COUNT,
+ OPT_FLUSH_TABLES,
#ifdef HAVE_NDBCLUSTER_DB
OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING,
#endif
@@ -96,6 +97,7 @@ enum options_client
OPT_REWRITE_DB,
OPT_PLUGIN_DIR,
OPT_DEFAULT_PLUGIN,
+ OPT_REPORT_PROGRESS,
OPT_SKIP_ANNOTATE_ROWS_EVENTS,
OPT_MAX_CLIENT_OPTION /* should be always the last */
};
diff --git a/client/mysql.cc b/client/mysql.cc
index 03c1e669f60..824a416ec36 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -49,7 +49,7 @@ and you are welcome to modify and redistribute it under the GPL v2 license\n"
#include <locale.h>
#endif
-const char *VER= "14.16";
+const char *VER= "15.1";
/* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024
@@ -152,7 +152,7 @@ static my_bool ignore_errors=0,wait_flag=0,quick=0,
default_charset_used= 0, opt_secure_auth= 0,
default_pager_set= 0, opt_sigint_ignore= 0,
show_warnings= 0, executing_query= 0,
- ignore_spaces= 0;
+ ignore_spaces= 0, opt_progress_reports;
static my_bool debug_info_flag, debug_check_flag, batch_abort_on_error;
static my_bool column_types_flag;
static my_bool preserve_comments= 0;
@@ -248,6 +248,13 @@ static const char* construct_prompt();
static char *get_arg(char *line, my_bool get_next_arg);
static void init_username();
static void add_int_to_prompt(int toadd);
+#ifndef EMBEDDED_LIBRARY
+static uint last_progress_report_length= 0;
+static void report_progress(const MYSQL *mysql, uint stage, uint max_stage,
+ double progress, const char *proc_info,
+ uint proc_info_length);
+#endif
+static void report_progress_end();
/* A structure which contains information on the commands this program
can understand. */
@@ -1498,6 +1505,10 @@ static struct my_option my_long_options[] =
"built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
&opt_mysql_port,
&opt_mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"progress-reports", OPT_REPORT_PROGRESS,
+ "Get progress reports for long running commands (like ALTER TABLE)",
+ &opt_progress_reports, &opt_progress_reports, 0, GET_BOOL, NO_ARG, 1, 0,
+ 0, 0, 0, 0},
{"prompt", OPT_PROMPT, "Set the mysql prompt to this value.",
&current_prompt, &current_prompt, 0, GET_STR_ALLOC,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -1854,6 +1865,7 @@ static int get_options(int argc, char **argv)
opt_outfile= 0;
opt_reconnect= 0;
connect_flag= 0; /* Not in interactive mode */
+ opt_progress_reports= 0;
}
if (strcmp(default_charset, charset_info->csname) &&
@@ -1881,6 +1893,9 @@ static int get_options(int argc, char **argv)
if (ignore_spaces)
connect_flag|= CLIENT_IGNORE_SPACE;
+ if (opt_progress_reports)
+ connect_flag|= CLIENT_PROGRESS;
+
return(0);
}
@@ -2287,7 +2302,7 @@ static bool add_line(String &buffer,char *line,char *in_string,
break;
}
else if (!*in_string && inchar == '/' && *(pos+1) == '*' &&
- *(pos+2) != '!')
+ !(*(pos+2) == '!' || (*(pos+2) == 'M' && *(pos+3) == '!')))
{
if (preserve_comments)
{
@@ -3058,6 +3073,7 @@ com_go(String *buffer,char *line __attribute__((unused)))
timer=start_timer();
executing_query= 1;
error= mysql_real_query_for_lazy(buffer->ptr(),buffer->length());
+ report_progress_end();
#ifdef HAVE_READLINE
if (status.add_to_history)
@@ -4413,9 +4429,17 @@ sql_real_connect(char *host,char *database,char *user,char *password,
}
return -1; // Retryable
}
+
connected=1;
#ifndef EMBEDDED_LIBRARY
mysql.reconnect= debug_info_flag; // We want to know if this happens
+
+ /*
+ CLIENT_PROGRESS is set only if we requsted it in mysql_real_connect()
+ and the server also supports it
+ */
+ if (mysql.client_flag & CLIENT_PROGRESS)
+ mysql_options(&mysql, MYSQL_PROGRESS_CALLBACK, (void*) report_progress);
#else
mysql.reconnect= 1;
#endif
@@ -5063,4 +5087,31 @@ void sql_element_free(void *ptr)
{
my_free(ptr,MYF(0));
}
-#endif /* EMBEDDED_LIBRARY */
+
+static void report_progress(const MYSQL *mysql, uint stage, uint max_stage,
+ double progress, const char *proc_info,
+ uint proc_info_length)
+{
+ uint length= printf("Stage: %d of %d '%.*s' %6.3g%% of stage done",
+ stage, max_stage, proc_info_length, proc_info,
+ progress);
+ if (length < last_progress_report_length)
+ printf("%*s", last_progress_report_length - length, "");
+ putc('\r', stdout);
+ fflush(stdout);
+ last_progress_report_length= length;
+}
+
+static void report_progress_end()
+{
+ if (last_progress_report_length)
+ {
+ printf("%*s\r", last_progress_report_length, "");
+ last_progress_report_length= 0;
+ }
+}
+#else
+static void report_progress_end()
+{
+}
+#endif
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index b7ebdbc9f58..6540361aa02 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -109,7 +109,7 @@ static ulonglong rec_count= 0;
static short binlog_flags = 0;
static MYSQL* mysql = NULL;
static const char* dirname_for_local_load= 0;
-static bool opt_skip_annotate_rows_events= 0;
+static bool opt_skip_annotate_row_events= 0;
/**
Pointer to the Format_description_log_event of the currently active binlog.
@@ -1020,7 +1020,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
break;
}
case ANNOTATE_ROWS_EVENT:
- if (!opt_skip_annotate_rows_events)
+ if (!opt_skip_annotate_row_events)
{
/*
We don't print Annotate event just now because all subsequent
@@ -1328,10 +1328,10 @@ that may lead to an endless loop.",
"Updates to a database with a different name than the original. \
Example: rewrite-db='from->to'.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"skip-annotate-rows-events", OPT_SKIP_ANNOTATE_ROWS_EVENTS,
+ {"skip-annotate-row-events", OPT_SKIP_ANNOTATE_ROWS_EVENTS,
"Don't print Annotate_rows events stored in the binary log.",
- (uchar**) &opt_skip_annotate_rows_events,
- (uchar**) &opt_skip_annotate_rows_events,
+ (uchar**) &opt_skip_annotate_row_events,
+ (uchar**) &opt_skip_annotate_row_events,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -1815,7 +1815,7 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
cast to uint32.
*/
int4store(buf, (uint32)start_position);
- if (!opt_skip_annotate_rows_events)
+ if (!opt_skip_annotate_row_events)
binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
int2store(buf + BIN_LOG_HEADER_SIZE, binlog_flags);
@@ -2198,7 +2198,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info,
return ERROR_STOP;
}
#endif
- if (init_io_cache(file, fileno(stdin), 0, READ_CACHE, (my_off_t) 0,
+ if (init_io_cache(file, my_fileno(stdin), 0, READ_CACHE, (my_off_t) 0,
0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE)))
{
error("Failed to init IO cache.");
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 14e02bbb328..22f4b70ed81 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -16,7 +16,7 @@
/* By Jani Tolonen, 2001-04-20, MySQL Development Team */
-#define CHECK_VERSION "2.6.0"
+#define CHECK_VERSION "2.7.0"
#include "client_priv.h"
#include <m_ctype.h>
@@ -35,8 +35,8 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0,
opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0,
tty_password= 0, opt_frm= 0, debug_info_flag= 0, debug_check_flag= 0,
- opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0,
- opt_write_binlog= 1;
+ opt_fix_table_names= 0, opt_fix_db_names= 0, opt_upgrade= 0;
+static my_bool opt_write_binlog= 1, opt_flush_tables= 0;
static uint verbose = 0, opt_mysql_port=0;
static int my_end_arg;
static char * opt_mysql_unix_port = 0;
@@ -121,6 +121,9 @@ static struct my_option my_long_options[] =
"If you are using this option with CHECK TABLE, it will ensure that the table is 100 percent consistent, but will take a long time. If you are using this option with REPAIR TABLE, it will force using old slow repair with keycache method, instead of much faster repair by sorting.",
&opt_extended, &opt_extended, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
+ {"flush", OPT_FLUSH_TABLES, "Flush each table after check. This is useful if you don't want to have the checked tables take up space in the caches after the check",
+ &opt_flush_tables, &opt_flush_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
+ 0, 0 },
{"help", '?', "Display this help message and exit.", 0, 0, 0, GET_NO_ARG,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"host",'h', "Connect to host.", &current_host,
@@ -685,6 +688,7 @@ static int disable_binlog()
static int handle_request_for_tables(char *tables, uint length)
{
char *query, *end, options[100], message[100];
+ char table_name_buff[NAME_CHAR_LEN*2*2+1], *table_name;
uint query_length= 0;
const char *op = 0;
@@ -723,13 +727,17 @@ static int handle_request_for_tables(char *tables, uint length)
/* No backticks here as we added them before */
query_length= my_sprintf(query,
(query, "%s TABLE %s %s", op, tables, options));
+ table_name= tables;
}
else
{
- char *ptr;
+ char *ptr, *org;
- ptr= strmov(strmov(query, op), " TABLE ");
+ org= ptr= strmov(strmov(query, op), " TABLE ");
ptr= fix_table_name(ptr, tables);
+ strmake(table_name_buff, org, min((int) sizeof(table_name_buff)-1,
+ (int) (ptr - org)));
+ table_name= table_name_buff;
ptr= strxmov(ptr, " ", options, NullS);
query_length= (uint) (ptr - query);
}
@@ -737,9 +745,21 @@ static int handle_request_for_tables(char *tables, uint length)
{
sprintf(message, "when executing '%s TABLE ... %s'", op, options);
DBerror(sock, message);
+ my_free(query, MYF(0));
return 1;
}
print_result();
+ if (opt_flush_tables)
+ {
+ query_length= my_sprintf(query,
+ (query, "FLUSH TABLES %s", table_name));
+ if (mysql_real_query(sock, query, query_length))
+ {
+ DBerror(sock, query);
+ my_free(query, MYF(0));
+ return 1;
+ }
+ }
my_free(query, MYF(0));
return 0;
}
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 0eab2ae8e0b..d7d99e0cc17 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -36,7 +36,7 @@
** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov
*/
-#define DUMP_VERSION "10.13"
+#define DUMP_VERSION "10.14"
#include <my_global.h>
#include <my_sys.h>
@@ -635,8 +635,13 @@ static void write_header(FILE *sql_file, char *db_name)
if (!path)
{
+ if (!opt_no_create_info)
+ {
+ /* We don't need unique checks as the table is created just before */
+ fprintf(md_result_file,"\
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n");
+ }
fprintf(md_result_file,"\
-/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;\n\
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;\n\
");
}
@@ -666,8 +671,12 @@ static void write_footer(FILE *sql_file)
if (!path)
{
fprintf(md_result_file,"\
-/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n\
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;\n");
+ if (!opt_no_create_info)
+ {
+ fprintf(md_result_file,"\
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;\n");
+ }
}
if (opt_set_charset)
fprintf(sql_file,
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index c38380c7306..a876390db27 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -1223,7 +1223,7 @@ get_options(int *argc,char ***argv)
if (opt_csv_str[0] == '-')
{
- csv_file= fileno(stdout);
+ csv_file= my_fileno(stdout);
}
else
{
@@ -1382,9 +1382,9 @@ get_options(int *argc,char ***argv)
fprintf(stderr,"%s: Could not open create file\n", my_progname);
exit(1);
}
- tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ tmp_string= (char *)my_malloc((size_t)sbuf.st_size + 1,
MYF(MY_ZEROFILL|MY_FAE|MY_WME));
- my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0));
+ my_read(data_file, (uchar*) tmp_string, (size_t)sbuf.st_size, MYF(0));
tmp_string[sbuf.st_size]= '\0';
my_close(data_file,MYF(0));
parse_delimiter(tmp_string, &create_statements, delimiter[0]);
@@ -1409,9 +1409,9 @@ get_options(int *argc,char ***argv)
fprintf(stderr,"%s: Could not open query supplied file\n", my_progname);
exit(1);
}
- tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ tmp_string= (char *)my_malloc((size_t)sbuf.st_size + 1,
MYF(MY_ZEROFILL|MY_FAE|MY_WME));
- my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0));
+ my_read(data_file, (uchar*) tmp_string, (size_t)sbuf.st_size, MYF(0));
tmp_string[sbuf.st_size]= '\0';
my_close(data_file,MYF(0));
if (user_supplied_query)
@@ -1440,9 +1440,9 @@ get_options(int *argc,char ***argv)
fprintf(stderr,"%s: Could not open query supplied file\n", my_progname);
exit(1);
}
- tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ tmp_string= (char *)my_malloc((size_t)sbuf.st_size + 1,
MYF(MY_ZEROFILL|MY_FAE|MY_WME));
- my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0));
+ my_read(data_file, (uchar*) tmp_string, (size_t)sbuf.st_size, MYF(0));
tmp_string[sbuf.st_size]= '\0';
my_close(data_file,MYF(0));
if (user_supplied_pre_statements)
@@ -1471,9 +1471,9 @@ get_options(int *argc,char ***argv)
fprintf(stderr,"%s: Could not open query supplied file\n", my_progname);
exit(1);
}
- tmp_string= (char *)my_malloc(sbuf.st_size + 1,
+ tmp_string= (char *)my_malloc((size_t)sbuf.st_size + 1,
MYF(MY_ZEROFILL|MY_FAE|MY_WME));
- my_read(data_file, (uchar*) tmp_string, sbuf.st_size, MYF(0));
+ my_read(data_file, (uchar*) tmp_string, (size_t)sbuf.st_size, MYF(0));
tmp_string[sbuf.st_size]= '\0';
my_close(data_file,MYF(0));
if (user_supplied_post_statements)
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index a3689a7b757..d94023ccd0c 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -5238,7 +5238,8 @@ void do_connect(struct st_command *command)
int con_port= opt_port;
char *con_options;
my_bool con_ssl= 0, con_compress= 0;
- my_bool con_pipe= 0, con_shm= 0;
+ my_bool con_pipe= 0;
+ my_bool con_shm __attribute__ ((unused))= 0;
struct st_connection* con_slot;
static DYNAMIC_STRING ds_connection_name;
diff --git a/client/readline.cc b/client/readline.cc
index 4edccebef39..5293f7546e4 100644
--- a/client/readline.cc
+++ b/client/readline.cc
@@ -43,7 +43,7 @@ LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file)
if (!(line_buff=(LINE_BUFFER*)
my_malloc(sizeof(*line_buff),MYF(MY_WME | MY_ZEROFILL))))
return 0;
- if (init_line_buffer(line_buff,fileno(file),IO_SIZE,max_size))
+ if (init_line_buffer(line_buff,my_fileno(file),IO_SIZE,max_size))
{
my_free(line_buff,MYF(0));
return 0;
diff --git a/configure.in b/configure.in
index 06ab18fd5d2..96cb19fc6a9 100644
--- a/configure.in
+++ b/configure.in
@@ -18,7 +18,7 @@ dnl When merging new MySQL releases, update the version number to match the
dnl MySQL version number.
dnl
dnl Note: the following line must be parseable by win/configure.js:GetVersion()
-AC_INIT([MariaDB Server], [5.3.0-MariaDB-alpha], [], [mysql])
+AC_INIT([MariaDB Server], [5.3.2-MariaDB-beta], [], [mysql])
AC_CONFIG_SRCDIR([sql/mysqld.cc])
AC_CANONICAL_SYSTEM
@@ -870,7 +870,7 @@ AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(fcntl.h fenv.h float.h floatingpoint.h fpu_control.h \
ieeefp.h limits.h memory.h pwd.h select.h fnmatch.h \
- stdlib.h stddef.h sys/stat.h \
+ stdlib.h stddef.h sys/stat.h sys/sockio.h \
strings.h string.h synch.h sys/mman.h sys/socket.h netinet/in.h arpa/inet.h \
sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
diff --git a/extra/comp_err.c b/extra/comp_err.c
index 24ec8974d03..5ae5d29994b 100644
--- a/extra/comp_err.c
+++ b/extra/comp_err.c
@@ -402,7 +402,7 @@ static void clean_up(struct languages *lang_head, struct errors *error_head)
my_free((uchar*) tmp_error->sql_code1, MYF(0));
if (tmp_error->sql_code2[0])
my_free((uchar*) tmp_error->sql_code2, MYF(0));
- my_free((uchar*) tmp_error->er_name, MYF(0));
+ my_free((uchar*) tmp_error->er_name, MYF(MY_ALLOW_ZERO_PTR));
my_free((uchar*) tmp_error, MYF(0));
}
}
diff --git a/include/Makefile.am b/include/Makefile.am
index 99a21d686a3..afc2afff115 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -22,6 +22,7 @@ HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
my_list.h my_alloc.h typelib.h mysql/plugin.h
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
my_xml.h mysql_embed.h mysql/services.h \
+ mysql/service_progress_report.h \
mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
my_pthread.h my_no_pthread.h \
mysql/plugin_auth.h mysql/client_plugin.h \
diff --git a/include/config-win.h b/include/config-win.h
index 97b0891bcfb..979e7ae32dd 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -66,7 +66,6 @@
#endif
/* File and lock constants */
-#define O_SHARE 0x1000 /* Open file in sharing mode */
#ifdef __BORLANDC__
#define F_RDLCK LK_NBLCK /* read lock */
#define F_WRLCK LK_NBRLCK /* write lock */
@@ -373,7 +372,7 @@ inline ulonglong double2ulonglong(double d)
#define FN_DEVCHAR ':'
#define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */
#define FN_NO_CASE_SENCE /* Files are not case-sensitive */
-#define OS_FILE_LIMIT 2048
+#define OS_FILE_LIMIT UINT_MAX
#define DO_NOT_REMOVE_THREAD_WRAPPERS
#define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))
diff --git a/include/ma_dyncol.h b/include/ma_dyncol.h
index 687823a4e73..6174328d62a 100644
--- a/include/ma_dyncol.h
+++ b/include/ma_dyncol.h
@@ -79,15 +79,15 @@ struct st_dynamic_column_value
unsigned long long ulong_value;
double double_value;
struct {
- LEX_STRING string_value;
+ LEX_STRING value;
CHARSET_INFO *charset;
- };
+ } string;
struct {
- decimal_digit_t decimal_buffer[DECIMAL_BUFF_LENGTH];
- decimal_t decimal_value;
- };
+ decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
+ decimal_t value;
+ } decimal;
MYSQL_TIME time_value;
- };
+ } x;
};
typedef struct st_dynamic_column_value DYNAMIC_COLUMN_VALUE;
diff --git a/include/maria.h b/include/maria.h
index 470f76669f3..ff83bb238e0 100644
--- a/include/maria.h
+++ b/include/maria.h
@@ -466,6 +466,8 @@ void maria_change_pagecache(PAGECACHE *old_key_cache,
int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves);
void maria_versioning(MARIA_HA *info, my_bool versioning);
void maria_ignore_trids(MARIA_HA *info);
+uint maria_max_key_length(void);
+#define maria_max_key_segments() HA_MAX_KEY_SEG
/* fulltext functions */
FT_INFO *maria_ft_init_search(uint,void *, uint, uchar *, size_t,
diff --git a/include/my_compare.h b/include/my_compare.h
index 7e886d1e0dc..058d6b6d94a 100644
--- a/include/my_compare.h
+++ b/include/my_compare.h
@@ -103,6 +103,8 @@ extern HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, const uchar *a);
if we're scanning "t.key BETWEEN 10 AND 20" and got a
"t.key=21" tuple (the engine should stop scanning and
return HA_ERR_END_OF_FILE right away).
+ 3=ICP_ABORTED_BY_USER - engine must stop scanning and should return
+ HA_ERR_ABORTED_BY_USER right away
-1= ICP_ERROR - Reserved for internal errors in engines. Should not be
returned by index_cond_func_xxx
*/
@@ -111,7 +113,8 @@ typedef enum icp_result {
ICP_ERROR=-1,
ICP_NO_MATCH=0,
ICP_MATCH=1,
- ICP_OUT_OF_RANGE=2
+ ICP_OUT_OF_RANGE=2,
+ ICP_ABORTED_BY_USER=3,
} ICP_RESULT;
diff --git a/include/my_dir.h b/include/my_dir.h
index 06509a3af19..90d708ac811 100644
--- a/include/my_dir.h
+++ b/include/my_dir.h
@@ -69,7 +69,11 @@ typedef struct my_stat
#else
+#if(_MSC_VER)
+#define MY_STAT struct _stati64 /* 64 bit file size */
+#else
#define MY_STAT struct stat /* Orginal struct have what we need */
+#endif
#endif /* USE_MY_STAT_STRUCT */
diff --git a/include/my_global.h b/include/my_global.h
index 1fa3f750b44..eff16d0dfff 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -784,7 +784,41 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define FN_DIRSEP "/" /* Valid directory separators */
#define FN_ROOTDIR "/"
#endif
-#define MY_NFILE 64 /* This is only used to save filenames */
+
+/*
+ MY_FILE_MIN is Windows speciality and is used to quickly detect
+ the mismatch of CRT and mysys file IO usage on Windows at runtime.
+ CRT file descriptors can be in the range 0-2047, whereas descriptors returned
+ by my_open() will start with 2048. If a file descriptor with value less then
+ MY_FILE_MIN is passed to mysys IO function, chances are it stemms from
+ open()/fileno() and not my_open()/my_fileno.
+
+ For Posix, mysys functions are light wrappers around libc, and MY_FILE_MIN
+ is logically 0.
+*/
+
+#ifdef _WIN32
+#define MY_FILE_MIN 2048
+#else
+#define MY_FILE_MIN 0
+#endif
+
+/*
+ MY_NFILE is the default size of my_file_info array.
+
+ It is larger on Windows, because it all file handles are stored in my_file_info
+ Default size is 16384 and this should be enough for most cases.If it is not
+ enough, --max-open-files with larger value can be used.
+
+ For Posix , my_file_info array is only used to store filenames for
+ error reporting and its size is not a limitation for number of open files.
+*/
+#ifdef _WIN32
+#define MY_NFILE (16384 + MY_FILE_MIN)
+#else
+#define MY_NFILE 64
+#endif
+
#ifndef OS_FILE_LIMIT
#define OS_FILE_LIMIT UINT_MAX
#endif
@@ -821,9 +855,8 @@ typedef SOCKET_SIZE_TYPE size_socket;
/* Some things that this system doesn't have */
#define NO_HASH /* Not needed anymore */
-#ifdef __WIN__
-#define NO_DIR_LIBRARY /* Not standar dir-library */
-#define USE_MY_STAT_STRUCT /* For my_lib */
+#ifdef _WIN32
+#define NO_DIR_LIBRARY /* Not standard dir-library */
#endif
/* Some defines of functions for portability */
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 139e5d08437..7057f90a89a 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -48,19 +48,30 @@ typedef struct st_pthread_link {
struct st_pthread_link *next;
} pthread_link;
-typedef struct {
- uint32 waiting;
- CRITICAL_SECTION lock_waiting;
-
- enum {
- SIGNAL= 0,
- BROADCAST= 1,
- MAX_EVENTS= 2
- } EVENTS;
-
- HANDLE events[MAX_EVENTS];
- HANDLE broadcast_block_event;
-
+/**
+ Implementation of Windows condition variables.
+ We use native conditions on Vista and later, and fallback to own
+ implementation on earlier OS version.
+*/
+typedef union
+{
+ /* Native condition (used on Vista and later) */
+ CONDITION_VARIABLE native_cond;
+
+ /* Own implementation (used on XP) */
+ struct
+ {
+ uint32 waiting;
+ CRITICAL_SECTION lock_waiting;
+ enum
+ {
+ SIGNAL= 0,
+ BROADCAST= 1,
+ MAX_EVENTS= 2
+ } EVENTS;
+ HANDLE events[MAX_EVENTS];
+ HANDLE broadcast_block_event;
+ };
} pthread_cond_t;
@@ -605,6 +616,45 @@ int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp);
#endif
#define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0)
#else
+#ifdef _WIN32
+/**
+ Implementation of Windows rwlock.
+
+ We use native (slim) rwlocks on Win7 and later, and fallback to portable
+ implementation on earlier Windows.
+
+ slim rwlock are also available on Vista/WS2008, but we do not use it
+ ("trylock" APIs are missing on Vista)
+*/
+typedef union
+{
+ /* Native rwlock (is_srwlock == TRUE) */
+ struct
+ {
+ SRWLOCK srwlock; /* native reader writer lock */
+ BOOL have_exclusive_srwlock; /* used for unlock */
+ };
+
+ /*
+ Portable implementation (is_srwlock == FALSE)
+ Fields are identical with Unix my_rw_lock_t fields.
+ */
+ struct
+ {
+ pthread_mutex_t lock; /* lock for structure */
+ pthread_cond_t readers; /* waiting readers */
+ pthread_cond_t writers; /* waiting writers */
+ int state; /* -1:writer,0:free,>0:readers */
+ int waiters; /* number of waiting writers */
+#ifdef SAFE_MUTEX
+ pthread_t write_thread;
+#endif
+ };
+} my_rw_lock_t;
+
+
+#else /* _WIN32 */
+
/* Use our own version of read/write locks */
typedef struct _my_rw_lock_t {
pthread_mutex_t lock; /* lock for structure */
@@ -614,6 +664,8 @@ typedef struct _my_rw_lock_t {
int waiters; /* number of waiting writers */
} my_rw_lock_t;
+#endif /* _WIN32 */
+
#define rw_lock_t my_rw_lock_t
#define rw_rdlock(A) my_rw_rdlock((A))
#define rw_wrlock(A) my_rw_wrlock((A))
diff --git a/include/my_sys.h b/include/my_sys.h
index 41e04265946..2bbeec48c88 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -49,7 +49,6 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_WME 16 /* Write message on error */
#define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */
#define MY_IGNORE_BADFD 32 /* my_sync: ignore 'bad descriptor' errors */
-#define MY_SYNC_DIR 1024 /* my_create/delete/rename: sync directory */
#define MY_RAID 64 /* Support for RAID */
#define MY_FULL_IO 512 /* For my_read - loop intil I/O is complete */
#define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */
@@ -70,6 +69,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_DONT_OVERWRITE_FILE 2048 /* my_copy: Don't overwrite file */
#define MY_THREADSAFE 2048 /* my_seek(): lock fd mutex */
#define MY_SYNC 4096 /* my_copy(): sync dst file */
+#define MY_SYNC_DIR 32768 /* my_create/delete/rename: sync directory */
#define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */
#define MY_GIVE_INFO 2 /* Give time info about process*/
@@ -255,7 +255,8 @@ extern ulong my_file_total_opened;
extern ulong my_sync_count;
extern uint mysys_usage_id;
extern my_bool my_init_done;
-
+extern my_bool my_assert_on_error;
+extern myf my_global_flags; /* Set to MY_WME for more error messages */
/* Point to current my_message() */
extern void (*my_sigtstp_cleanup)(void),
/* Executed before jump to shell */
@@ -342,11 +343,12 @@ enum file_type
struct st_my_file_info
{
- char * name;
- enum file_type type;
-#if defined(THREAD) && !defined(HAVE_PREAD)
- pthread_mutex_t mutex;
+ char *name;
+#ifdef _WIN32
+ HANDLE fhandle; /* win32 file handle */
+ int oflag; /* open flags, e.g O_APPEND */
#endif
+ enum file_type type;
};
extern struct st_my_file_info *my_file_info;
@@ -652,12 +654,12 @@ extern void *my_memmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);
-#ifdef __WIN__
-extern int my_access(const char *path, int amode);
-extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
+#ifdef _WIN32
+extern int my_access(const char *path, int amode);
#else
#define my_access access
#endif
+
extern int check_if_legal_filename(const char *path);
extern int check_if_legal_tablename(const char *path);
@@ -668,6 +670,13 @@ extern int nt_share_delete(const char *name,myf MyFlags);
#define my_delete_allow_opened(fname,flags) my_delete((fname),(flags))
#endif
+#ifdef _WIN32
+/* Windows-only functions (CRT equivalents)*/
+extern File my_sopen(const char *path, int oflag, int shflag, int pmode);
+extern HANDLE my_get_osfhandle(File fd);
+extern void my_osmaperr(unsigned long last_error);
+#endif
+
#ifndef TERMINATE
extern void TERMINATE(FILE *file, uint flag);
#endif
@@ -677,6 +686,7 @@ extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
extern FILE *my_freopen(const char *path, const char *mode, FILE *stream);
extern int my_fclose(FILE *fd,myf MyFlags);
+extern File my_fileno(FILE *fd);
extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
extern int my_chmod(const char *name, mode_t mode, myf my_flags);
extern int my_sync(File fd, myf my_flags);
diff --git a/include/myisam.h b/include/myisam.h
index 9fc17fdf2d6..736a49fd9ad 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -298,6 +298,8 @@ extern ulong _mi_calc_blob_length(uint length , const uchar *pos);
extern uint mi_get_pointer_length(ulonglong file_length, uint def);
extern int mi_make_backup_of_index(struct st_myisam_info *info,
time_t backup_time, myf flags);
+#define myisam_max_key_length() HA_MAX_KEY_LENGTH
+#define myisam_max_key_segments() HA_MAX_KEY_SEG
#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for mmap file */
/* this is used to pass to mysql_myisamchk_table */
diff --git a/include/myisamchk.h b/include/myisamchk.h
index 7d7100bdd71..f85824e76bb 100644
--- a/include/myisamchk.h
+++ b/include/myisamchk.h
@@ -144,7 +144,7 @@ typedef struct st_handler_check_param
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];
- uint out_flag, warning_printed, error_printed, verbose;
+ uint out_flag, warning_printed, error_printed, note_printed, verbose;
uint opt_sort_key, total_files, max_level;
uint key_cache_block_size, pagecache_block_size;
int tmpfile_createflag, err_count;
@@ -155,6 +155,11 @@ typedef struct st_handler_check_param
char temp_filename[FN_REFLEN];
IO_CACHE read_cache;
enum_handler_stats_method stats_method;
+ /* For reporting progress */
+ uint stage, max_stage;
+ uint progress_counter; /* How often to call _report_progress() */
+ ulonglong progress, max_progress;
+
#ifdef THREAD
pthread_mutex_t print_msg_mutex;
my_bool need_print_msg_lock;
diff --git a/include/mysql.h b/include/mysql.h
index 19aab89283b..2e412468bbe 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -169,7 +169,8 @@ enum mysql_option
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH,
+ MYSQL_PROGRESS_CALLBACK
};
/**
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index 7b29c1f2ce9..780dbc9db3d 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -67,8 +67,8 @@ enum mysql_enum_shutdown_level {
SHUTDOWN_WAIT_UPDATES= (unsigned char)(1 << 3),
SHUTDOWN_WAIT_ALL_BUFFERS= ((unsigned char)(1 << 3) << 1),
SHUTDOWN_WAIT_CRITICAL_BUFFERS= ((unsigned char)(1 << 3) << 1) + 1,
- KILL_QUERY= 254,
- KILL_CONNECTION= 255
+ SHUTDOWN_KILL_QUERY= 254,
+ SHUTDOWN_KILL_CONNECTION= 255
};
enum enum_cursor_type
{
@@ -225,7 +225,7 @@ typedef struct st_typelib {
extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position);
extern int find_type_with_warning(const char *x, TYPELIB *typelib,
const char *option);
-extern uint find_type_or_exit(const char *x, TYPELIB *typelib,
+extern unsigned int find_type_or_exit(const char *x, TYPELIB *typelib,
const char *option);
extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name);
extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
@@ -258,7 +258,8 @@ enum mysql_option
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
- MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH,
+ MYSQL_PROGRESS_CALLBACK
};
struct st_mysql_options_extention;
struct st_mysql_options {
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index 77d141d5282..83e2aceaf1e 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -1,4 +1,5 @@
/* Copyright (C) 2005 MySQL AB, 2009 Sun Microsystems, Inc.
+ Copyright (C) 2009-2011 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
@@ -16,13 +17,27 @@
#ifndef _my_plugin_h
#define _my_plugin_h
-
/*
On Windows, exports from DLL need to be declared
-*/
-#if (defined(_WIN32) && defined(MYSQL_DYNAMIC_PLUGIN))
-#define MYSQL_PLUGIN_EXPORT extern "C" __declspec(dllexport)
-#else
+ Also, plugin needs to be declared as extern "C" because MSVC
+ unlike other compilers, uses C++ mangling for variables not only
+ for functions.
+*/
+#if defined(_MSC_VER)
+#if defined(MYSQL_DYNAMIC_PLUGIN)
+ #ifdef __cplusplus
+ #define MYSQL_PLUGIN_EXPORT extern "C" __declspec(dllexport)
+ #else
+ #define MYSQL_PLUGIN_EXPORT __declspec(dllexport)
+ #endif
+#else /* MYSQL_DYNAMIC_PLUGIN */
+ #ifdef __cplusplus
+ #define MYSQL_PLUGIN_EXPORT extern "C"
+ #else
+ #define MYSQL_PLUGIN_EXPORT
+ #endif
+#endif /*MYSQL_DYNAMIC_PLUGIN */
+#else /*_MSC_VER */
#define MYSQL_PLUGIN_EXPORT
#endif
@@ -60,7 +75,7 @@ typedef struct st_mysql_xid MYSQL_XID;
/* MySQL plugin interface version */
#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0101
/* MariaDB plugin interface version */
-#define MARIA_PLUGIN_INTERFACE_VERSION 0x0100
+#define MARIA_PLUGIN_INTERFACE_VERSION 0x0101
/*
The allowable types of plugins
@@ -747,10 +762,6 @@ char *thd_security_context(MYSQL_THD thd, char *buffer, unsigned int length,
/* Increments the row counter, see THD::row_count */
void thd_inc_row_count(MYSQL_THD thd);
-#define thd_proc_info(thd, msg) set_thd_proc_info(thd, msg, __func__, __FILE__, __LINE__)
-const char *set_thd_proc_info(MYSQL_THD, const char * info, const char *func,
- const char *file, const unsigned int line);
-
/**
Create a temporary file.
diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp
index b0d5daf4c64..e4878d28f94 100644
--- a/include/mysql/plugin_auth.h.pp
+++ b/include/mysql/plugin_auth.h.pp
@@ -31,6 +31,27 @@ void *thd_memdup(void* thd, const void* str, unsigned int size);
MYSQL_LEX_STRING *thd_make_lex_string(void* thd, MYSQL_LEX_STRING *lex_str,
const char *str, unsigned int size,
int allocate_lex_string);
+#include <mysql/service_progress_report.h>
+extern struct progress_report_service_st {
+ void (*thd_progress_init_func)(void* thd, unsigned int max_stage);
+ void (*thd_progress_report_func)(void* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+ void (*thd_progress_next_stage_func)(void* thd);
+ void (*thd_progress_end_func)(void* thd);
+ const char *(*set_thd_proc_info_func)(void*, const char *info,
+ const char *func,
+ const char *file,
+ unsigned int line);
+} *progress_report_service;
+void thd_progress_init(void* thd, unsigned int max_stage);
+void thd_progress_report(void* thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+void thd_progress_next_stage(void* thd);
+void thd_progress_end(void* thd);
+const char *set_thd_proc_info(void*, const char * info, const char *func,
+ const char *file, unsigned int line);
struct st_mysql_xid {
long formatID;
long gtrid_length;
@@ -166,8 +187,6 @@ int thd_tx_isolation(const void* thd);
char *thd_security_context(void* thd, char *buffer, unsigned int length,
unsigned int max_query_len);
void thd_inc_row_count(void* thd);
-const char *set_thd_proc_info(void*, const char * info, const char *func,
- const char *file, const unsigned int line);
int mysql_tmpfile(const char *prefix);
int thd_killed(const void* thd);
unsigned long thd_get_thread_id(const void* thd);
diff --git a/include/mysql/service_progress_report.h b/include/mysql/service_progress_report.h
new file mode 100644
index 00000000000..670b1c37630
--- /dev/null
+++ b/include/mysql/service_progress_report.h
@@ -0,0 +1,82 @@
+#ifndef MYSQL_SERVICE_PROGRESS_REPORT_INCLUDED
+/* Copyright (C) 2011 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
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file
+ This service allows plugins to report progress of long running operations
+ to the server. The progress report is visible in SHOW PROCESSLIST,
+ INFORMATION_SCHEMA.PROCESSLIST, and is sent to the client
+ if requested.
+
+ The functions are documented at
+ http://kb.askmonty.org/en/progress-reporting#how-to-add-support-for-progress-reporting-to-a-storage-engine
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define thd_proc_info(thd, msg) set_thd_proc_info(thd, msg, \
+ __func__, __FILE__, __LINE__)
+
+extern struct progress_report_service_st {
+ void (*thd_progress_init_func)(MYSQL_THD thd, unsigned int max_stage);
+ void (*thd_progress_report_func)(MYSQL_THD thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+ void (*thd_progress_next_stage_func)(MYSQL_THD thd);
+ void (*thd_progress_end_func)(MYSQL_THD thd);
+ const char *(*set_thd_proc_info_func)(MYSQL_THD, const char *info,
+ const char *func,
+ const char *file,
+ unsigned int line);
+} *progress_report_service;
+
+#ifdef MYSQL_DYNAMIC_PLUGIN
+
+#define thd_progress_init(thd,max_stage) (progress_report_service->thd_progress_init_func((thd),(max_stage)))
+#define thd_progress_report(thd, progress, max_progress) (progress_report_service->thd_progress_report_func((thd), (progress), (max_progress)))
+#define thd_progress_next_stage(thd) (progress_report_service->thd_progress_next_stage_func(thd))
+#define thd_progress_end(thd) (progress_report_service->thd_progress_end_func(thd))
+#define set_thd_proc_info(thd,info,func,file,line) (progress_report_service->set_thd_proc_info_func((thd),(info),(func),(file),(line)))
+
+#else
+
+/**
+ Report progress for long running operations
+
+ @param thd User thread connection handle
+ @param progress Where we are now
+ @param max_progress Progress will continue up to this
+*/
+void thd_progress_init(MYSQL_THD thd, unsigned int max_stage);
+void thd_progress_report(MYSQL_THD thd,
+ unsigned long long progress,
+ unsigned long long max_progress);
+void thd_progress_next_stage(MYSQL_THD thd);
+void thd_progress_end(MYSQL_THD thd);
+const char *set_thd_proc_info(MYSQL_THD, const char * info, const char *func,
+ const char *file, unsigned int line);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MYSQL_SERVICE_PROGRESS_REPORT_INCLUDED
+#endif
+
diff --git a/include/mysql/services.h b/include/mysql/services.h
index 19003e66b96..b8cdfc3510d 100644
--- a/include/mysql/services.h
+++ b/include/mysql/services.h
@@ -20,6 +20,7 @@ extern "C" {
#include <mysql/service_my_snprintf.h>
#include <mysql/service_thd_alloc.h>
+#include <mysql/service_progress_report.h>
#ifdef __cplusplus
}
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 96d9afce5e6..81e0f4abaf6 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -158,6 +158,7 @@ enum enum_server_command
#define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */
#define CLIENT_PLUGIN_AUTH (1UL << 19) /* Client supports plugin authentication */
+#define CLIENT_PROGRESS (1UL << 29) /* Client support progress indicator */
#define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30)
#define CLIENT_REMEMBER_OPTIONS (1UL << 31)
@@ -189,6 +190,7 @@ enum enum_server_command
CLIENT_MULTI_RESULTS | \
CLIENT_SSL_VERIFY_SERVER_CERT | \
CLIENT_REMEMBER_OPTIONS | \
+ CLIENT_PROGRESS | \
CLIENT_PLUGIN_AUTH)
/*
@@ -383,12 +385,15 @@ enum mysql_enum_shutdown_level {
/* don't flush InnoDB buffers, flush other storage engines' buffers*/
SHUTDOWN_WAIT_CRITICAL_BUFFERS= (MYSQL_SHUTDOWN_KILLABLE_UPDATE << 1) + 1,
/* Now the 2 levels of the KILL command */
-#if MYSQL_VERSION_ID >= 50000
- KILL_QUERY= 254,
-#endif
- KILL_CONNECTION= 255
+ SHUTDOWN_KILL_QUERY= 254,
+ SHUTDOWN_KILL_CONNECTION= 255
};
+/* Compatibility */
+#if !defined(MYSQL_SERVER) && defined(USE_OLD_FUNCTIONS)
+#define KILL_QUERY SHUTDOWN_KILL_QUERY
+#define KILL_CONNECTION SHUTDOWN_KILL_CONNECTION
+#endif
enum enum_cursor_type
{
diff --git a/include/service_versions.h b/include/service_versions.h
index 114957cdd86..6f06b609e61 100644
--- a/include/service_versions.h
+++ b/include/service_versions.h
@@ -21,4 +21,5 @@
#define VERSION_my_snprintf 0x0100
#define VERSION_thd_alloc 0x0100
+#define VERSION_progress_report 0x0100
diff --git a/include/sql_common.h b/include/sql_common.h
index 6b66ae2fd81..20e06275653 100644
--- a/include/sql_common.h
+++ b/include/sql_common.h
@@ -29,6 +29,12 @@ extern const char *not_error_sqlstate;
struct st_mysql_options_extention {
char *plugin_dir;
char *default_auth;
+ void (*report_progress)(const MYSQL *mysql,
+ unsigned int stage,
+ unsigned int max_stage,
+ double progress,
+ const char *proc_info,
+ uint proc_info_length);
};
typedef struct st_mysql_methods
diff --git a/include/typelib.h b/include/typelib.h
index a5ac5cc7bbf..16c719e3419 100644
--- a/include/typelib.h
+++ b/include/typelib.h
@@ -29,7 +29,7 @@ typedef struct st_typelib { /* Different types saved here */
extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position);
extern int find_type_with_warning(const char *x, TYPELIB *typelib,
const char *option);
-extern uint find_type_or_exit(const char *x, TYPELIB *typelib,
+extern unsigned int find_type_or_exit(const char *x, TYPELIB *typelib,
const char *option);
extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name);
extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
index 4589d1c86af..a58b3735243 100755
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -89,6 +89,7 @@ SET(CLIENT_SOURCES ../mysys/array.c ../strings/bchange.c ../strings/bmove.c
../mysys/ma_dyncol.c
../mysys/my_symlink2.c ../mysys/my_thr_init.c ../sql-common/my_time.c
../strings/my_vsnprintf.c ../mysys/my_wincond.c ../mysys/my_winthread.c
+ ../mysys/my_wincond.c ../mysys/my_winthread.c ../mysys/my_winfile.c ../mysys/my_winerr.c
../mysys/my_write.c ../sql/net_serv.cc ../sql-common/pack.c ../sql/password.c
../mysys/safemalloc.c ../mysys/sha1.c ../strings/str2int.c
../strings/str_alloc.c ../strings/strcend.c ../strings/strcont.c ../strings/strend.c
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index 545f48627c2..6924a26c81c 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -86,15 +86,13 @@ FOREACH(rpath ${VIO_SOURCES})
SET(LIB_SOURCES ${LIB_SOURCES} ../vio/${rpath})
ENDFOREACH(rpath)
-FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS})
- INCLUDE(${CMAKE_SOURCE_DIR}/storage/${plugin_dir_${ENGINE_LIB}}/CMakeLists.txt)
- STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER)
- SET(ENGINE_DIR ${${ENGINE_LIB_UPPER}_DIR})
- INCLUDE(${CMAKE_SOURCE_DIR}/storage/${ENGINE_DIR}/CMakeLists.txt)
- FOREACH(rpath ${${ENGINE_LIB_UPPER}_SOURCES})
- SET(LIB_SOURCES ${LIB_SOURCES} ${CMAKE_SOURCE_DIR}/storage/${ENGINE_DIR}/${rpath})
+SET (ENGINE_BUILD_TYPE "STATIC")
+FOREACH (ENGINE ${MYSQLD_STATIC_ENGINES})
+ INCLUDE(${${ENGINE}_DIR}/CMakeLists.txt)
+ FOREACH(rpath ${${ENGINE}_SOURCES})
+ SET(LIB_SOURCES ${LIB_SOURCES} ${${ENGINE}_DIR}/${rpath})
ENDFOREACH(rpath)
-ENDFOREACH(ENGINE_LIB)
+ENDFOREACH(ENGINE)
SET(SOURCE_SUBLIBS FALSE)
@@ -169,15 +167,14 @@ IF(MSVC AND CMAKE_SIZEOF_VOID_P MATCHES 8)
ENDIF()
# Add any additional libraries requested by engine(s)
-FOREACH (ENGINE_LIB ${MYSQLD_STATIC_ENGINE_LIBS})
- STRING(TOUPPER ${ENGINE_LIB} ENGINE_LIB_UPPER)
- IF(${ENGINE_LIB_UPPER}_LIBS)
- TARGET_LINK_LIBRARIES(mysqlserver ${${ENGINE_LIB_UPPER}_LIBS})
- ENDIF(${ENGINE_LIB_UPPER}_LIBS)
-ENDFOREACH(ENGINE_LIB)
+FOREACH (ENGINE ${MYSQLD_STATIC_ENGINES})
+ IF(${ENGINE}_LIBS)
+ TARGET_LINK_LIBRARIES(mysqlserver ${${ENGINE}_LIBS})
+ ENDIF(${ENGINE}_LIBS)
+ENDFOREACH(ENGINE)
ADD_LIBRARY(libmysqld SHARED cmake_dummy.c libmysqld.def)
ADD_DEPENDENCIES(libmysqld mysqlserver)
-TARGET_LINK_LIBRARIES(libmysqld mysqlserver wsock32)
+TARGET_LINK_LIBRARIES(libmysqld mysqlserver wsock32 iphlpapi)
MYSQL_INSTALL_TARGETS(mysqlserver libmysqld DESTINATION lib COMPONENT Embedded)
diff --git a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt
index ddfa2495ade..d22873661fb 100644
--- a/libservices/CMakeLists.txt
+++ b/libservices/CMakeLists.txt
@@ -15,6 +15,7 @@
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
-SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c)
+SET(MYSQLSERVICES_SOURCES my_snprintf_service.c thd_alloc_service.c
+ progress_report_service.c)
ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
diff --git a/libservices/Makefile.am b/libservices/Makefile.am
index 642081859c1..5002b85e328 100644
--- a/libservices/Makefile.am
+++ b/libservices/Makefile.am
@@ -15,5 +15,6 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
pkglib_LIBRARIES = libmysqlservices.a
-libmysqlservices_a_SOURCES = my_snprintf_service.c thd_alloc_service.c
+libmysqlservices_a_SOURCES = my_snprintf_service.c thd_alloc_service.c \
+ progress_report_service.c
EXTRA_DIST = CMakeLists.txt
diff --git a/libservices/progress_report_service.c b/libservices/progress_report_service.c
new file mode 100644
index 00000000000..cd8db3eeacb
--- /dev/null
+++ b/libservices/progress_report_service.c
@@ -0,0 +1,17 @@
+/* Copyright (C) 2009 Sun Microsystems, Inc.
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include <service_versions.h>
+SERVICE_VERSION *progress_report_service= (void*)VERSION_progress_report;
diff --git a/mysql-test/extra/rpl_tests/rpl_row_annotate.test b/mysql-test/extra/rpl_tests/rpl_row_annotate.test
index 77c5f626e28..f3d8006ce01 100644
--- a/mysql-test/extra/rpl_tests/rpl_row_annotate.test
+++ b/mysql-test/extra/rpl_tests/rpl_row_annotate.test
@@ -1,8 +1,8 @@
########################################################################
# WL47: Store in binlog text of statements that caused RBR events
# new event : ANNOTATE_ROWS_EVENT
-# new master option : --binlog-annotate-rows-events
-# new slave option : --replicate-annotate-rows-events
+# new master option : --binlog-annotate-row-events
+# new slave option : --replicate-annotate-row-events
########################################################################
--source include/master-slave.inc
connect (master2,127.0.0.1,root,,test,$MASTER_MYPORT,);
@@ -29,11 +29,11 @@ CREATE TABLE t5 (
b VARCHAR(10) CHARACTER SET utf8 COLLATE utf8_bin
);
-SET SESSION binlog_annotate_rows_events = OFF;
+SET SESSION binlog_annotate_row_events = OFF;
INSERT INTO t1 VALUES (0,0), (1,1);
-SET SESSION binlog_annotate_rows_events = ON;
+SET SESSION binlog_annotate_row_events = ON;
UPDATE t1 SET b = b + 1;
REPLACE t1 VALUES (1,1), (2,2), (3,3);
@@ -84,7 +84,7 @@ SELECT * FROM t5 ORDER BY a;
--echo ########################################################################
--echo # EVENTS ON SLAVE
-let $annotate= `select @@global.replicate_annotate_rows_events`;
+let $annotate= `select @@global.replicate_annotate_row_events`;
if ($annotate)
{
--echo # The following Annotate_rows events should appear below:
@@ -116,7 +116,7 @@ let $start_pos= `select @binlog_start_pos`;
--echo # INSERTs DELAYED ON MASTERs
--echo ########################################################################
connection master;
-SET SESSION binlog_annotate_rows_events = ON;
+SET SESSION binlog_annotate_row_events = ON;
INSERT DELAYED INTO test1.t4 VALUES (1,1);
FLUSH TABLES;
SELECT * FROM test1.t4 ORDER BY a;
diff --git a/mysql-test/extra/rpl_tests/rpl_row_func003.test b/mysql-test/extra/rpl_tests/rpl_row_func003.test
index b77465de39e..6369d36e7e3 100644
--- a/mysql-test/extra/rpl_tests/rpl_row_func003.test
+++ b/mysql-test/extra/rpl_tests/rpl_row_func003.test
@@ -47,17 +47,9 @@ delimiter ;|
--disable_warnings
INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1());
-sleep 6;
INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1());
-sleep 6;
--enable_warnings
-#Select in this test are used for debugging
-#select * from test.t1;
-#connection slave;
-#select * from test.t1;
-
-connection master;
SET AUTOCOMMIT=0;
START TRANSACTION;
--disable_warnings
@@ -65,18 +57,14 @@ INSERT INTO test.t1 VALUES (null,test.f1());
--enable_warnings
ROLLBACK;
SET AUTOCOMMIT=1;
-#select * from test.t1;
-#sleep 6;
-
-#connection slave;
-#select * from test.t1;
-
-#connection master;
-#used for debugging
-#show binlog events;
+# Sync master and slave for all engines except NDB
+if (`SELECT UPPER(LEFT('$engine_type', 3)) != 'NDB'`) {
+ sync_slave_with_master;
+ connection master;
+}
-# time to dump the databases and so we can see if they match
+# Time to dump the databases and so we can see if they match
--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/func003_master.sql
--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/func003_slave.sql
@@ -93,5 +81,8 @@ DROP TABLE test.t1;
diff_files $MYSQLTEST_VARDIR/tmp/func003_master.sql $MYSQLTEST_VARDIR/tmp/func003_slave.sql;
+# Clean up
+remove_file $MYSQLTEST_VARDIR/tmp/func003_master.sql;
+remove_file $MYSQLTEST_VARDIR/tmp/func003_slave.sql;
# End of 5.0 test case
diff --git a/mysql-test/include/default_mysqld.cnf b/mysql-test/include/default_mysqld.cnf
index e46c3bc3c17..a1b477c51dd 100644
--- a/mysql-test/include/default_mysqld.cnf
+++ b/mysql-test/include/default_mysqld.cnf
@@ -15,6 +15,8 @@ max_heap_table_size= 1M
loose-skip-innodb
loose-skip-pbxt
+loose-skip-feedback
+loose-feedback-user-info= mysql-test
loose-innodb_data_file_path= ibdata1:10M:autoextend
diff --git a/mysql-test/include/icp_tests.inc b/mysql-test/include/icp_tests.inc
index 52f30188455..ea4fc6439d2 100644
--- a/mysql-test/include/icp_tests.inc
+++ b/mysql-test/include/icp_tests.inc
@@ -87,6 +87,152 @@ SELECT * FROM t1 WHERE c2 <=> NULL ORDER BY c1,c2 LIMIT 2;
DROP TABLE t1;
--echo #
+--echo # Bug#43617 - Innodb returns wrong results with timestamp's range value
+--echo # in IN clause
+--echo # (Note: Fixed by patch for BUG#42580)
+--echo #
+
+CREATE TABLE t1(
+ c1 TIMESTAMP NOT NULL,
+ c2 TIMESTAMP NULL,
+ c3 DATE,
+ c4 DATETIME,
+ PRIMARY KEY(c1),
+ UNIQUE INDEX(c2)
+);
+
+INSERT INTO t1 VALUES
+ ('0000-00-00 00:00:00','0000-00-00 00:00:00','2008-01-04','2008-01-05 00:00:00'),
+ ('1971-01-01 00:00:01','1980-01-01 00:00:01','2009-01-01','2009-01-02 00:00:00'),
+ ('1999-01-01 00:00:00','1999-01-01 00:00:00', NULL, NULL),
+ ('2007-05-23 09:15:28','2007-05-23 09:15:28','2007-05-24','2007-05-24 09:15:28'),
+ ('2007-05-27 00:00:00','2007-05-25 00:00:00','2007-05-26','2007-05-26 00:00:00'),
+ ('2008-01-01 00:00:00', NULL, '2008-01-02','2008-01-03 00:00:00'),
+ ('2009-01-29 11:11:27','2009-01-29 11:11:27','2009-01-29','2009-01-29 11:11:27'),
+ ('2038-01-09 03:14:07','2038-01-09 03:14:07','2009-01-05','2009-01-06 00:00:00');
+
+--echo
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2;
+
+--echo
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 LIMIT 2;
+
+--echo
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC;
+
+--echo
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC LIMIT 2;
+
+--echo
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#43618: MyISAM&Maria returns wrong results with 'between'
+--echo # on timestamp
+--echo #
+
+CREATE TABLE t1(
+ ts TIMESTAMP NOT NULL,
+ c char NULL,
+ PRIMARY KEY(ts)
+);
+
+INSERT INTO t1 VALUES
+ ('1971-01-01','a'),
+ ('2007-05-25','b'),
+ ('2008-01-01','c'),
+ ('2038-01-09','d');
+
+--disable_warnings
+
+--echo
+--echo # Execute select with invalid timestamp, desc ordering
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+
+--echo
+--echo # Should use index condition
+EXPLAIN
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+--echo
+
+--enable_warnings
+
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#49906: Assertion failed - Field_varstring::val_str in field.cc
+--echo # (Note: Fixed by patch for LP BUG#625841)
+--echo #
+
+CREATE TABLE t1 (
+ f1 VARCHAR(1024),
+ f2 VARCHAR(10),
+ INDEX test_idx USING BTREE (f2,f1(5))
+);
+
+INSERT INTO t1 VALUES ('a','c'), ('b','d');
+
+SELECT f1
+FROM t1
+WHERE f2 LIKE 'd'
+ORDER BY f1;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#52660 - "Perf. regr. using ICP for MyISAM on range queries on
+--echo # an index containing TEXT"
+--echo #
+
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 SELECT A.a + 10*(B.a) FROM t1 A, t1 B;
+
+CREATE TABLE t3 (
+ c1 TINYTEXT NOT NULL,
+ i1 INT NOT NULL,
+ KEY (c1(6),i1)
+);
+
+INSERT INTO t3 SELECT CONCAT('c-',1000+t2.a,'=w'), 1 FROM t2;
+
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+
+DROP TABLE t1, t2, t3;
+
+--echo #
--echo # Bug#40992 - InnoDB: Crash when engine_condition_pushdown is on
--echo #
@@ -102,6 +248,7 @@ SELECT * FROM t WHERE a > 2 FOR UPDATE;
DROP TABLE t;
+
--echo #
--echo # Bug#35080 - Innodb crash at mem_block_get_len line 72
--echo #
@@ -225,3 +372,375 @@ SELECT COUNT(*) FROM t3;
DROP PROCEDURE insert_data;
DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # Bug#57372 "Multi-table updates and deletes fail when running with ICP
+--echo # against InnoDB"
+--echo #
+
+CREATE TABLE t1 (
+ a INT KEY,
+ b INT
+);
+
+CREATE TABLE t2 (
+ a INT KEY,
+ b INT
+);
+
+INSERT INTO t1 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105);
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+
+UPDATE t1, t2
+SET t1.a = t1.a + 100, t2.b = t1.a + 10
+WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b - 100;
+
+--sorted_result
+SELECT * FROM t1;
+--sorted_result
+SELECT * FROM t2;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug#52605 - "Adding LIMIT 1 clause to query with complex range
+--echo # predicate causes wrong results"
+--echo #
+
+CREATE TABLE t1 (
+ pk INT NOT NULL,
+ c1 INT,
+ PRIMARY KEY (pk),
+ KEY k1 (c1)
+);
+
+INSERT INTO t1 VALUES (1,NULL);
+INSERT INTO t1 VALUES (2,6);
+INSERT INTO t1 VALUES (3,NULL);
+INSERT INTO t1 VALUES (4,6);
+INSERT INTO t1 VALUES (5,NULL);
+INSERT INTO t1 VALUES (6,NULL);
+INSERT INTO t1 VALUES (7,9);
+INSERT INTO t1 VALUES (8,0);
+
+SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+
+EXPLAIN SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#59259 "Incorrect rows returned for a correlated subquery
+--echo # when ICP is on"
+--echo #
+
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=off';
+
+EXPLAIN
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+
+set optimizer_switch=@save_optimizer_switch;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug #58816 "Extra temporary duplicate rows in result set when
+--echo # switching ICP off"
+--echo #
+
+set @save_optimizer_switch= @@optimizer_switch;
+
+CREATE TABLE t1 (
+ pk INT NOT NULL,
+ c1 INT NOT NULL,
+ PRIMARY KEY (pk)
+);
+
+INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1);
+
+EXPLAIN SELECT pk, c1 FROM t1 WHERE pk <> 3;
+
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+
+SELECT pk, c1 FROM t1 WHERE pk <> 3;
+
+DROP TABLE t1;
+
+set optimizer_switch= @save_optimizer_switch;
+
+--echo #
+--echo # Bug#58837: ICP crash or valgrind error due to uninitialized
+--echo # value in innobase_index_cond
+--echo #
+
+CREATE TABLE t1 (
+ t1_int INT,
+ t1_time TIME
+);
+
+CREATE TABLE t2 (
+ t2_int int PRIMARY KEY,
+ t2_int2 INT
+);
+
+--disable_warnings
+INSERT INTO t2 VALUES ();
+INSERT INTO t1 VALUES ();
+--enable_warnings
+
+SELECT * FROM t1 AS t1a
+ WHERE NOT EXISTS (SELECT * FROM t1 AS t1b
+ WHERE t1b.t1_int NOT IN
+ (SELECT t2.t2_int FROM t2
+ WHERE t1b.t1_time LIKE t1b.t1_int
+ OR t1b.t1_time <> t2.t2_int2
+ AND 6=7));
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug#59186: Wrong results of join when ICP is enabled
+--echo # (fixed by the patch for LP bug #694092)
+--echo #
+
+CREATE TABLE t1 (
+ pk INTEGER NOT NULL,
+ c1 VARCHAR(3) NOT NULL,
+ PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'y'),(0,'or');
+
+CREATE TABLE t2 (
+ pk INTEGER NOT NULL,
+ c1 VARCHAR(3) NOT NULL,
+ c2 VARCHAR(6) NOT NULL,
+ PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (6,'y','RPOYT'),(10,'m','JINQE');
+
+EXPLAIN
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+ (t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+ (t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug#58838: "Wrong results with HAVING + LIMIT without GROUP BY when
+--echo # ICP is enabled".
+--echo # (Fixed by the patches for LP bugs #668644, #702322)
+--echo #
+
+CREATE TABLE t1 (
+ pk INT NOT NULL,
+ c1 INT,
+ PRIMARY KEY (pk),
+ KEY col_int_key (c1)
+);
+
+INSERT INTO t1 VALUES (1,37),(2,8),(3,-25),(4,NULL),(5,55);
+
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 0;
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 1;
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 2;
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 5;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#59483 "Crash on INSERT/REPLACE in
+--echo # rec_convert_dtuple_to_rec_comp with ICP on"
+--echo #
+
+CREATE TABLE t1 (
+ pk INTEGER AUTO_INCREMENT PRIMARY KEY,
+ i1 INTEGER,
+ c1 CHAR(6),
+ i2 INTEGER NOT NULL,
+ KEY (i2)
+);
+
+INSERT INTO t1 VALUES
+ (NULL, 4, 'that', 8),
+ (NULL, 1, 'she', 6),
+ (NULL, 6, 'tell', 2);
+
+SELECT * FROM t1 WHERE i2 IN (3, 6) LIMIT 2 FOR UPDATE;
+INSERT INTO t1 (i2) VALUES (1);
+
+DROP TABLE t1;
+
+--echo #
+--echo # Bug #11766678 - 59843:
+--echo # USING UNINITIALISED VALUE IN USES_INDEX_FIELDS_ONLY
+--echo #
+
+CREATE TABLE t1 (
+ col999 FLOAT NOT NULL,
+ COL1000 VARBINARY(179) NOT NULL,
+ col1003 DATE DEFAULT NULL,
+ KEY idx4267 (col1000, col1003)
+);
+
+INSERT INTO t1 VALUES (),();
+SELECT col999 FROM t1 WHERE col1000 = "3" AND col1003 <=> sysdate();
+
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#12822678 - ICP WITH STRAIGHT_JOIN
+--echo #
+
+CREATE TABLE t1 (
+ i1 INTEGER NOT NULL,
+ d1 DOUBLE,
+ KEY k1 (d1)
+);
+INSERT INTO t1 VALUES (10,1), (17,NULL), (22,NULL);
+
+CREATE TABLE t2 (
+ pk INTEGER NOT NULL,
+ i1 INTEGER NOT NULL,
+ PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (4,1);
+
+EXPLAIN
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+ WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+ WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#778434 Wrong result with in_to_exists=on in maria-5.3-mwl89
+--echo #
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0);
+
+CREATE TABLE t2 ( f10 int) ;
+INSERT IGNORE INTO t2 VALUES (0);
+
+CREATE TABLE t3 ( f1 int NOT NULL , f10 int, PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES (6,0),(10,0);
+
+CREATE TABLE t4 ( f11 int) ;
+INSERT IGNORE INTO t4 VALUES
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(NULL),
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+
+set @tmp_778434=@@optimizer_switch;
+SET optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off,semijoin=off';
+
+SELECT * FROM t1 INNER JOIN t2 ON t2.f10 = t1.f11
+WHERE (6, 234) IN (
+ SELECT t3.f1, t3.f1
+ FROM t3 JOIN t4 ON t4.f11 = t3.f10
+);
+
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch= @tmp_778434;
+
+--echo #
+--echo # Bug#885168: ICP for one index + potential ORDER BY for another
+--echo #
+
+CREATE TABLE t1 (a varchar(64), b varchar(10), INDEX(a), INDEX(b)) ;
+INSERT INTO t1 VALUES
+ ('Ohio','Iowa'), ('k','d'), ('bdkpj','mbdkpjdanp'), ('d','xdmbdkpjda'),
+ ('fkxdmbdkpjdanpje','o'), ('f','Pennsylvan'), ('Virginia','ei');
+
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT * FROM t1
+ WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+SELECT * FROM t1
+ WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT * FROM t1
+ WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+SELECT * FROM t1
+ WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#886145: join with ICP + ORDER BY
+--echo #
+
+CREATE TABLE t1 (b int NOT NULL, c int, a varchar(1024), PRIMARY KEY (b));
+INSERT INTO t1 VALUES (1,4,'Ill');
+
+CREATE TABLE t2 (a varchar(1024), KEY (a(512)));
+INSERT INTO t2 VALUES
+ ('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w');
+
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+ HAVING t1.c != 5 ORDER BY t1.c;
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+ HAVING t1.c != 5 ORDER BY t1.c;
+
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+ HAVING t1.c != 5 ORDER BY t1.c;
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+ HAVING t1.c != 5 ORDER BY t1.c;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug#879871: InnoDB: possible ICP + GROUP BY primary index
+--echo #
+
+CREATE TABLE t1 (
+ a int NOT NULL, b int, c varchar(1), d varchar(1),
+ PRIMARY KEY (a), KEY c (c,b)
+);
+INSERT INTO t1 VALUES (10,8,'g','g');
+
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+
+DROP TABLE t1;
+
+
diff --git a/mysql-test/include/ps_query.inc b/mysql-test/include/ps_query.inc
index ae6027a0e07..8148935cbe1 100644
--- a/mysql-test/include/ps_query.inc
+++ b/mysql-test/include/ps_query.inc
@@ -597,7 +597,6 @@ execute stmt1 using @arg00, @arg01, @arg02, @arg03, @arg04, @arg05, @arg06,
--enable_result_log
drop table t2 ;
-
##### test case derived from client_test.c: test_bug4079()
--error 1242
select 1 < (select a from t1) ;
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index 5f557ef5d99..584fa6738de 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -891,7 +891,8 @@ sub collect_one_test_case {
if ( -f "$testdir/$tname.slave-mi");
- my @source_files = tags_from_test_file($tinfo,"$testdir/${tname}.test");
+ my ($master_opts, $slave_opts)=
+ tags_from_test_file($tinfo, "$testdir/${tname}.test", $suitedir);
# Get default storage engine from suite.opt file
@@ -1059,16 +1060,8 @@ sub collect_one_test_case {
# ----------------------------------------------------------------------
# Append mysqld extra options to master and slave, as appropriate
# ----------------------------------------------------------------------
- for (@source_files) {
- s/\.\w+$//;
- push @{$tinfo->{master_opt}}, opts_from_file("$_.opt");
- push @{$tinfo->{slave_opt}}, opts_from_file("$_.opt");
- push @{$tinfo->{master_opt}}, opts_from_file("$_-master.opt");
- push @{$tinfo->{slave_opt}}, opts_from_file("$_-slave.opt");
- }
-
- push(@{$tinfo->{'master_opt'}}, @::opt_extra_mysqld_opt);
- push(@{$tinfo->{'slave_opt'}}, @::opt_extra_mysqld_opt);
+ push @{$tinfo->{'master_opt'}}, @$master_opts, @::opt_extra_mysqld_opt;
+ push @{$tinfo->{'slave_opt'}}, @$slave_opts, @::opt_extra_mysqld_opt;
process_opts($tinfo, 'master_opt');
process_opts($tinfo, 'slave_opt');
@@ -1077,74 +1070,113 @@ sub collect_one_test_case {
}
-# List of tags in the .test files that if found should set
-# the specified value in "tinfo"
-my @tags=
-(
- ["include/big_test.inc", "big_test", 1],
- ["include/have_debug.inc", "need_debug", 1],
- ["include/have_ndb.inc", "ndb_test", 1],
- ["include/have_multi_ndb.inc", "ndb_test", 1],
- ["include/master-slave.inc", "rpl_test", 1],
- ["include/ndb_master-slave.inc", "rpl_test", 1],
- ["include/ndb_master-slave.inc", "ndb_test", 1],
- ["include/not_embedded.inc", "not_embedded", 1],
- ["include/not_valgrind.inc", "not_valgrind", 1],
- ["include/have_example_plugin.inc", "example_plugin_test", 1],
- ["include/have_oqgraph_engine.inc", "oqgraph_test", 1],
- ["include/have_ssl.inc", "need_ssl", 1],
- ["include/long_test.inc", "long_test", 1],
-);
-
-
-sub tags_from_test_file {
- my $tinfo= shift;
- my $file= shift;
- #mtr_verbose("$file");
- my $F= IO::File->new($file) or mtr_error("can't open file \"$file\": $!");
- my @all_files=($file);
-
- while ( my $line= <$F> )
+my $tags_map= {'big_test' => ['big_test', 1],
+ 'have_debug' => ['need_debug', 1],
+ 'have_ndb' => ['ndb_test', 1],
+ 'have_multi_ndb' => ['ndb_test', 1],
+ 'master-slave' => ['rpl_test', 1],
+ 'ndb_master-slave' => ['rpl_test', 1, 'ndb_test', 1],
+ 'not_embedded' => ['not_embedded', 1],
+ 'not_valgrind' => ['not_valgrind', 1],
+ 'have_example_plugin' => ['example_plugin_test', 1],
+ 'have_oqgraph_engine' => ['oqgraph_test', 1],
+ 'have_ssl' => ['need_ssl', 1],
+ 'long_test' => ['long_test', 1],
+};
+my $tags_regex_string= join('|', keys %$tags_map);
+my $tags_regex= qr:include/($tags_regex_string)\.inc:o;
+
+my $file_to_tags= { };
+my $file_to_master_opts= { };
+my $file_to_slave_opts= { };
+
+# Get various tags from a file, recursively scanning also included files.
+# And get options from .opt file, also recursively for included files.
+# Return a list of [TAG_TO_SET, VALUE_TO_SET_TO] of found tags.
+# Also returns lists of options for master and slave found in .opt files.
+# Each include file is scanned only once, and subsequent calls just look up the
+# cached result.
+# We need to be a bit careful about speed here; previous version of this code
+# took forever to scan the full test suite.
+sub get_tags_from_file {
+ my ($file, $suitedir)= @_;
+
+ return ($file_to_tags->{$file}, $file_to_master_opts->{$file},
+ $file_to_slave_opts->{$file})
+ if exists($file_to_tags->{$file});
+
+ my $F= IO::File->new($file)
+ or mtr_error("can't open file \"$file\": $!");
+
+ my $tags= [];
+ my $master_opts= [];
+ my $slave_opts= [];
+
+ while (my $line= <$F>)
{
+ # Ignore comments.
+ next if $line =~ /^\#/;
- # Skip line if it start's with #
- next if ( $line =~ /^#/ );
-
- # Match this line against tag in "tags" array
- foreach my $tag (@tags)
+ # Add any tag we find.
+ if ($line =~ /$tags_regex/o)
{
- if ( index($line, $tag->[0]) >= 0 )
+ my $to_set= $tags_map->{$1};
+ for (my $i= 0; $i < @$to_set; $i+= 2)
{
- # Tag matched, assign value to "tinfo"
- $tinfo->{"$tag->[1]"}= $tag->[2];
+ push @$tags, [$to_set->[$i], $to_set->[$i+1]];
}
}
- # If test sources another file, open it as well
- if ( $line =~ /^\-\-([[:space:]]*)source(.*)$/ or
- $line =~ /^([[:space:]]*)source(.*);$/ )
+ # Check for a sourced include file.
+ if ($line =~ /^(--)?[[:space:]]*source[[:space:]]+([^;[:space:]]+)/)
{
- my $value= $2;
- $value =~ s/^\s+//; # Remove leading space
- $value =~ s/[[:space:]]+$//; # Remove ending space
-
- # Sourced file may exist relative to test or
- # in global location
- foreach my $sourced_file (dirname($file). "/$value",
- "$::glob_mysql_test_dir/$value")
+ my $include= $2;
+ # Sourced file may exist relative to test file, or in global location.
+ # Note that for the purpose of tag collection we ignore
+ # non-existing files, and let mysqltest handle the error
+ # (e.g. mysqltest.test needs this)
+ for my $sourced_file (dirname($file) . '/' . $include,
+ $suitedir . '/' . $include,
+ $::glob_mysql_test_dir . '/' . $include)
{
- if ( -f $sourced_file )
- {
- # Only source the file if it exists, we may get
- # false positives in the regexes above if someone
- # writes "source nnnn;" in a test case(such as mysqltest.test)
- unshift @all_files, tags_from_test_file($tinfo, $sourced_file);
- last;
- }
+ if (-e $sourced_file)
+ {
+ my ($sub_tags, $sub_master_opts, $sub_slave_opts)=
+ get_tags_from_file($sourced_file, $suitedir);
+ push @$tags, @$sub_tags;
+ push @$master_opts, @$sub_master_opts;
+ push @$slave_opts, @$sub_slave_opts;
+ last;
+ }
}
}
}
- @all_files;
+
+ # Add options from main file _after_ those of any includes; this allows a
+ # test file to override options set by includes (eg. rpl.rpl_ddl uses this
+ # to enable innodb, then disable innodb in the slave.
+ my $file_no_ext= $file;
+ $file_no_ext =~ s/\.\w+$//;
+ my @common_opts= opts_from_file("$file_no_ext.opt");
+ push @$master_opts, @common_opts, opts_from_file("$file_no_ext-master.opt");
+ push @$slave_opts, @common_opts, opts_from_file("$file_no_ext-slave.opt");
+
+ # Save results so we can reuse without parsing if seen again.
+ $file_to_tags->{$file}= $tags;
+ $file_to_master_opts->{$file}= $master_opts;
+ $file_to_slave_opts->{$file}= $slave_opts;
+ return ($tags, $master_opts, $slave_opts);
+}
+
+sub tags_from_test_file {
+ my ($tinfo, $file, $suitedir)= @_;
+
+ my ($tags, $master_opts, $slave_opts)= get_tags_from_file($file, $suitedir);
+ for (@$tags)
+ {
+ $tinfo->{$_->[0]}= $_->[1];
+ }
+ return ($master_opts, $slave_opts);
}
sub unspace {
diff --git a/mysql-test/lib/v1/mysql-test-run.pl b/mysql-test/lib/v1/mysql-test-run.pl
index e9a264ac60b..b903f50568a 100755
--- a/mysql-test/lib/v1/mysql-test-run.pl
+++ b/mysql-test/lib/v1/mysql-test-run.pl
@@ -2372,8 +2372,11 @@ sub remove_stale_vardir () {
mtr_report("WARNING: Using the 'mysql-test/var' symlink");
# Make sure the directory where it points exist
- mtr_error("The destination for symlink $opt_vardir does not exist")
- if ! -d readlink($opt_vardir);
+ if (! -d readlink($opt_vardir))
+ {
+ mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory");
+ unlink($opt_vardir);
+ }
foreach my $bin ( glob("$opt_vardir/*") )
{
@@ -2432,8 +2435,11 @@ sub setup_vardir() {
# it's a symlink
# Make sure the directory where it points exist
- mtr_error("The destination for symlink $opt_vardir does not exist")
- if ! -d readlink($opt_vardir);
+ if (! -d readlink($opt_vardir))
+ {
+ mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory");
+ unlink($opt_vardir);
+ }
}
elsif ( $opt_mem )
{
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index e2b2a3c2262..7aa19611a59 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -2355,9 +2355,11 @@ sub remove_stale_vardir () {
mtr_report(" - WARNING: Using the 'mysql-test/var' symlink");
# Make sure the directory where it points exist
- mtr_error("The destination for symlink $opt_vardir does not exist")
- if ! -d readlink($opt_vardir);
-
+ if (! -d readlink($opt_vardir))
+ {
+ mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory");
+ unlink($opt_vardir);
+ }
foreach my $bin ( glob("$opt_vardir/*") )
{
mtr_verbose("Removing bin $bin");
@@ -2424,8 +2426,11 @@ sub setup_vardir() {
# it's a symlink
# Make sure the directory where it points exist
- mtr_error("The destination for symlink $opt_vardir does not exist")
- if ! -d readlink($opt_vardir);
+ if (! -d readlink($opt_vardir))
+ {
+ mtr_report("The destination for symlink $opt_vardir does not exist; Removing it and creating a new var directory");
+ unlink($opt_vardir);
+ }
}
elsif ( $opt_mem )
{
@@ -2876,7 +2881,6 @@ sub mysql_server_start($) {
}
if (-d $datadir ) {
- preserve_error_log($mysqld);
mtr_verbose(" - removing '$datadir'");
rmtree($datadir);
}
@@ -2905,7 +2909,6 @@ sub mysql_server_start($) {
unless -d $datadir;
}
- restore_error_log($mysqld);
# Create the servers tmpdir
my $tmpdir= $mysqld->value('tmpdir');
@@ -4223,30 +4226,6 @@ sub run_testcase ($$) {
}
-# We want to preserve the error log between server restarts, as it may contain
-# valuable debugging information even if there is no test failure recorded.
-sub _preserve_error_log_names {
- my ($mysqld)= @_;
- my $error_log_file= $mysqld->if_exist('#log-error');
- return (undef, undef) unless $error_log_file;
- my $error_log_dir= dirname($error_log_file);
- my $save_name= $error_log_dir ."/../". $mysqld->name() .".error.log";
- return ($error_log_file, $save_name);
-}
-
-sub preserve_error_log {
- my ($mysqld)= @_;
- my ($error_log_file, $save_name)= _preserve_error_log_names($mysqld);
- rename($error_log_file, $save_name) if $save_name;
- # Ignore any errors, as it's just a best-effort to keep the log if possible.
-}
-
-sub restore_error_log {
- my ($mysqld)= @_;
- my ($error_log_file, $save_name)= _preserve_error_log_names($mysqld);
- rename($save_name, $error_log_file) if $save_name;
-}
-
# Keep track of last position in mysqld error log where we scanned for
# warnings, so we can attribute any warnings found to the correct test
# suite or server restart.
@@ -4452,7 +4431,11 @@ sub extract_warning_lines ($$) {
qr|Checking table: '\./mtr/test_suppressions'|,
qr|Table \./test/bug53592 has a primary key in InnoDB data dictionary, but not in MySQL|,
qr|mysqld: Table '\./mtr/test_suppressions' is marked as crashed and should be repaired|,
+ qr|Can't open shared library.*ha_archive|,
qr|InnoDB: Error: table 'test/bug39438'|,
+ qr|Access denied for user|,
+ qr|Aborted connection|,
+ qr|table.*is full|,
);
my $matched_lines= [];
@@ -4764,7 +4747,6 @@ sub clean_datadir {
for (all_servers())
{
- preserve_error_log($_); # or at least, try to
my $dir= "$opt_vardir/".$_->{name};
mtr_verbose(" - removing '$dir'");
rmtree($dir);
@@ -4957,14 +4939,13 @@ sub mysqld_arguments ($$$) {
if ( $opt_valgrind_mysqld )
{
- mtr_add_arg($args, "--skip-safemalloc");
-
if ( $mysql_version_id < 50100 )
{
mtr_add_arg($args, "--skip-bdb");
}
}
+ mtr_add_arg($args, "--loose-skip-safemalloc");
mtr_add_arg($args, "%s--disable-sync-frm");
# Retry bind as this may fail on busy server
mtr_add_arg($args, "%s--port-open-timeout=10");
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index 0c0e2d623c8..103883deb15 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -218,3 +218,10 @@ a d
3 11120436154190595086
drop table t1, t2;
End of 5.0 tests
+create table t1 (f1 time);
+insert t1 values ('00:00:00'),('00:01:00');
+select case t1.f1 when '00:00:00' then 1 end from t1;
+case t1.f1 when '00:00:00' then 1 end
+1
+NULL
+drop table t1;
diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result
index 877a6badc16..82d93a606ba 100644
--- a/mysql-test/r/cast.result
+++ b/mysql-test/r/cast.result
@@ -105,9 +105,9 @@ cast("2011-02-03 10:11:12.123456" as datetime(6))
select cast("2011-02-03 10:11:12" as datetime(6));
cast("2011-02-03 10:11:12" as datetime(6))
2011-02-03 10:11:12.000000
-select cast(cast(20010203101112.1 as double) as datetime(1));
-cast(cast(20010203101112.1 as double) as datetime(1))
-2001-02-03 10:11:12.1
+select cast(cast(20010203101112.5 as double) as datetime(1));
+cast(cast(20010203101112.5 as double) as datetime(1))
+2001-02-03 10:11:12.5
select cast(cast(010203101112.12 as double) as datetime(2));
cast(cast(010203101112.12 as double) as datetime(2))
0001-02-03 10:11:12.12
@@ -733,3 +733,8 @@ select cast(f1 as unsigned), cast(f2 as unsigned), cast(f3 as unsigned) from t1;
cast(f1 as unsigned) cast(f2 as unsigned) cast(f3 as unsigned)
112233 20111213 20111213112233
drop table t1;
+SELECT CAST(TIME('10:20:30') AS DATE) + INTERVAL 1 DAY;
+CAST(TIME('10:20:30') AS DATE) + INTERVAL 1 DAY
+NULL
+Warnings:
+Warning 1292 Truncated incorrect date value: '0000-00-00'
diff --git a/mysql-test/r/comments.result b/mysql-test/r/comments.result
index 99fab38d7a7..77c520b0c64 100644
--- a/mysql-test/r/comments.result
+++ b/mysql-test/r/comments.result
@@ -26,6 +26,20 @@ select 1 # The rest of the row will be ignored
1
1
/* line with only comment */;
+select 1 /*M! +1 */;
+1 +1
+2
+select 1 /*M!50000 +1 */;
+1 +1
+2
+select 1 /*M!50300 +1 */;
+1 +1
+2
+select 2 /*M!99999 +1 */;
+2
+2
+select 2 /*M!0000 +1 */;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '0000 +1 */' at line 1
select 1/*!2*/;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2*/' at line 1
select 1/*!000002*/;
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index 5d4ffa6b9d3..cb3adfb459d 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -104,7 +104,7 @@ insert into t1 (b) values ("hello"),("my"),("world");
create table t2 (key (b)) select * from t1;
explain select * from t2 where b="world";
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref B B 21 const 1 Using index condition
+1 SIMPLE t2 ref B B 21 const 1 Using where
select * from t2 where b="world";
a B
3 world
@@ -1760,7 +1760,10 @@ t1 CREATE TABLE `t1` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
drop table t1;
create temporary table t1 like information_schema.processlist;
@@ -1775,7 +1778,10 @@ t1 CREATE TEMPORARY TABLE `t1` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
drop table t1;
create table t1 like information_schema.character_sets;
diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result
index 8b1a7957229..b42094550bd 100644
--- a/mysql-test/r/ctype_collate.result
+++ b/mysql-test/r/ctype_collate.result
@@ -566,31 +566,31 @@ INSERT INTO t1 VALUES ('i','i');
INSERT INTO t1 VALUES ('j','j');
EXPLAIN SELECT * FROM t1 WHERE s1='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref s1 s1 11 const 1 Using index condition
+1 SIMPLE t1 ref s1 s1 11 const 1 Using where
EXPLAIN SELECT * FROM t1 WHERE s2='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref s2 s2 11 const 1 Using index condition
+1 SIMPLE t1 ref s2 s2 11 const 1 Using where
EXPLAIN SELECT * FROM t1 WHERE s1='a' COLLATE latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref s1 s1 11 const 1 Using index condition
+1 SIMPLE t1 ref s1 s1 11 const 1 Using where
EXPLAIN SELECT * FROM t1 WHERE s2='a' COLLATE latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
EXPLAIN SELECT * FROM t1 WHERE s1 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range s1 s1 11 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range s1 s1 11 NULL 2 Using where
EXPLAIN SELECT * FROM t1 WHERE s2 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
EXPLAIN SELECT * FROM t1 WHERE s1 IN ('a','b' COLLATE latin1_german1_ci);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range s1 s1 11 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range s1 s1 11 NULL 2 Using where
EXPLAIN SELECT * FROM t1 WHERE s2 IN ('a','b' COLLATE latin1_german1_ci);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
EXPLAIN SELECT * FROM t1 WHERE s1 LIKE 'a' COLLATE latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range s1 s1 11 NULL 1 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range s1 s1 11 NULL 1 Using where
EXPLAIN SELECT * FROM t1 WHERE s2 LIKE 'a' COLLATE latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result
index fe803ed37a5..b1225c31575 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/derived.result
@@ -57,8 +57,9 @@ a b a b
3 c 3 c
explain select * from t1 as x1, (select * from t1) as x2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE x1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
+1 PRIMARY x1 ALL NULL NULL NULL NULL 4
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 4
drop table if exists t2,t3;
select * from (select 1) as a;
1
@@ -112,8 +113,9 @@ a b
3 c
explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 system NULL NULL NULL NULL 1
-1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+2 DERIVED t2 system NULL NULL NULL NULL 1
+2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using where
drop table t1, t2;
create table t1(a int not null, t char(8), index(a));
SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20;
@@ -140,7 +142,9 @@ a t
20 20
explain select count(*) from t1 as tt1, (select * from t1) as tt2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+1 PRIMARY tt1 index NULL a 4 NULL 10000 Using index
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000 Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 10000
drop table t1;
SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b;
(SELECT * FROM (SELECT 1 as a) as a )
@@ -169,30 +173,30 @@ insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd'
insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
pla_id mat_id
-102 1
-101 1
100 1
-104 2
+101 1
+102 1
103 2
+104 2
105 3
SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
pla_id test
-102 1
-101 1
100 1
-104 2
+101 1
+102 1
103 2
+104 2
105 3
explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
-1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
+1 PRIMARY <derived2> ALL NULL $hj 7 test.m2.matintnum 9 Using where
2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
-1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
+1 PRIMARY <derived2> ALL NULL $hj 7 test.m2.matintnum 9 Using where
2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
drop table t1,t2;
@@ -227,8 +231,9 @@ count(*)
2
explain select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE A ALL NULL NULL NULL NULL 2 Using where
-1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.A.E2 1 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 THEMAX.E2 1 Using where
+2 DERIVED A ALL NULL NULL NULL NULL 2 Using where
3 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 2 Using where
drop table t1;
create table t1 (a int);
@@ -318,7 +323,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
explain select a from (select a from t2 where a>1) tt;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
drop table t2;
CREATE TABLE `t1` ( `itemid` int(11) NOT NULL default '0', `grpid` varchar(15) NOT NULL default '', `vendor` int(11) NOT NULL default '0', `date_` date NOT NULL default '0000-00-00', `price` decimal(12,2) NOT NULL default '0.00', PRIMARY KEY (`itemid`,`grpid`,`vendor`,`date_`), KEY `itemid` (`itemid`,`vendor`), KEY `itemid_2` (`itemid`,`date_`));
insert into t1 values (128, 'rozn', 2, curdate(), 10),
@@ -407,21 +413,3 @@ MIN(i)
1
DROP TABLE t1;
# End of 5.0 tests
-#
-# LP bug #793436: query with a derived table for which optimizer proves
-# that it contains not more than 1 row
-#
-CREATE TABLE t1 (a int, KEY (a)) ;
-INSERT INTO t1 VALUES (3), (1);
-CREATE TABLE t2 (a int);
-INSERT INTO t2 VALUES (3);
-EXPLAIN
-SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> system NULL NULL NULL NULL 1
-1 PRIMARY t1 ref a a 5 const 1 Using index
-2 DERIVED t2 system NULL NULL NULL NULL 1
-SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a;
-a a
-3 3
-DROP TABLE t1,t2;
diff --git a/mysql-test/r/derived_opt.result b/mysql-test/r/derived_opt.result
new file mode 100644
index 00000000000..721d4277775
--- /dev/null
+++ b/mysql-test/r/derived_opt.result
@@ -0,0 +1,276 @@
+drop table if exists t1,t2,t3;
+set @exit_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+set @save_optimizer_switch=@@optimizer_switch;
+CREATE TABLE t1 (a int not null, b char (10) not null);
+insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
+CREATE TABLE t2 (a int not null, b char (10) not null);
+insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e');
+CREATE TABLE t3 (a int not null, b char (10) not null);
+insert into t3 values (3,'f'),(4,'y'),(5,'z'),(6,'c');
+select * from t1 as x1, (select * from t1) as x2;
+a b a b
+1 a 1 a
+2 b 1 a
+3 c 1 a
+3 c 1 a
+1 a 2 b
+2 b 2 b
+3 c 2 b
+3 c 2 b
+1 a 3 c
+2 b 3 c
+3 c 3 c
+3 c 3 c
+1 a 3 c
+2 b 3 c
+3 c 3 c
+3 c 3 c
+explain select * from t1 as x1, (select * from t1) as x2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE x1 ALL NULL NULL NULL NULL 4
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
+drop table if exists t2,t3;
+CREATE TABLE t2 (a int not null);
+insert into t2 values(1);
+select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
+a b t2a
+1 a 1
+explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 system NULL NULL NULL NULL 1
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
+drop table t1, t2;
+create table t1(a int not null, t char(8), index(a));
+SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20;
+a t
+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 count(*) from t1 as tt1, (select * from t1) as tt2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+drop table t1;
+create table t1 (mat_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, matintnum CHAR(6) NOT NULL, test MEDIUMINT UNSIGNED NULL);
+create table t2 (mat_id MEDIUMINT UNSIGNED NOT NULL, pla_id MEDIUMINT UNSIGNED NOT NULL);
+insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd', 4), (NULL, 'e', 5), (NULL, 'f', 6), (NULL, 'g', 7), (NULL, 'h', 8), (NULL, 'i', 9);
+insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
+SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+pla_id mat_id
+102 1
+101 1
+100 1
+104 2
+103 2
+105 3
+SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+pla_id test
+102 1
+101 1
+100 1
+104 2
+103 2
+105 3
+explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY m2 ALL NULL NULL NULL NULL 9
+1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
+2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
+explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY m2 ALL NULL NULL NULL NULL 9
+1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
+2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
+2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
+drop table t1,t2;
+create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1)
+);
+insert into t1 VALUES(1,1,1), (2,2,1);
+select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2;
+count(*)
+2
+explain select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE A ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.A.E2 1 Using where
+3 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 2 Using where
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2);
+select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
+a a
+1 1
+2 1
+1 2
+2 2
+explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+1 PRIMARY <derived4> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
+4 DERIVED t1 ALL NULL NULL NULL NULL 2
+5 UNION t1 ALL NULL NULL NULL NULL 2
+NULL UNION RESULT <union4,5> ALL NULL NULL NULL NULL NULL
+2 DERIVED t1 ALL NULL NULL NULL NULL 2
+3 UNION t1 ALL NULL NULL NULL NULL 2
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
+drop table t1;
+create table t2 (a int, b int, primary key (a));
+insert into t2 values (1,7),(2,7);
+explain select a from t2 where a>1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+explain select a from (select a from t2 where a>1) tt;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+drop table t2;
+create table t1
+(
+c1 tinyint, c2 smallint, c3 mediumint, c4 int,
+c5 integer, c6 bigint, c7 float, c8 double,
+c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
+c13 date, c14 datetime, c15 timestamp, c16 time,
+c17 year, c18 bit, c19 bool, c20 char,
+c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
+c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
+c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
+c32 set('monday', 'tuesday', 'wednesday')
+) engine = MYISAM ;
+create table t2 like t1;
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ;
+prepare stmt1 from @stmt ;
+execute stmt1 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+execute stmt1 ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+deallocate prepare stmt1;
+drop tables t1,t2;
+set @@optimizer_switch=@save_optimizer_switch;
+#
+# LP bug #793436: query with a derived table for which optimizer proves
+# that it contains not more than 1 row
+#
+CREATE TABLE t1 (a int, KEY (a)) ;
+INSERT INTO t1 VALUES (3), (1);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (3);
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1
+1 PRIMARY t1 ref a a 5 const 1 Using index
+2 DERIVED t2 system NULL NULL NULL NULL 1
+SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a;
+a a
+3 3
+DROP TABLE t1,t2;
+#
+# LP bug #800518: crash with a query over a derived table
+# when a min/max optimization is applied
+#
+CREATE TABLE t1 (a int, b int, c varchar(10), INDEX idx(a,b)) ;
+INSERT INTO t1 VALUES
+(100, 3, 'xxx'), (200, 7, 'yyyyyyy'), (100, 1, 't'),
+(200, 4, 'aaaa'), (100, 3, 'eee'), (100, 5, 'zzzzz');
+EXPLAIN
+SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100;
+MAX(b)
+5
+DROP TABLE t1;
+#
+# LP bug #799499: query over a materialized view
+# accessed by a key
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (8);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES
+(262, NULL), (253, 190), (260, NULL), (250, 163), (188, 8),
+(257,200), (256, NULL), (255, 8), (249, NULL), (259, 7);
+CREATE VIEW v1 AS SELECT a, MIN(b) AS b FROM t2 GROUP BY a;
+EXPLAIN
+SELECT * FROM v1, t1 WHERE v1.b=t1.a ORDER BY v1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 Using filesort
+1 PRIMARY <derived2> ref key0 key0 5 const 1 Using where
+2 DERIVED t2 ALL NULL NULL NULL NULL 10 Using temporary; Using filesort
+SELECT * FROM v1, t1 WHERE v1.b=t1.a ORDER BY v1.a;
+a b a
+188 8 8
+255 8 8
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #800085: crash with a query using a simple derived table
+# (fixed by the patch for bug 798621)
+#
+CREATE TABLE t1 (f1 int, f2 varchar(32)) ;
+INSERT INTO t1 VALUES (NULL,'j'), (8,'c');
+CREATE TABLE t2 (f1 int);
+INSERT INTO t2 VALUES (1), (5);
+SELECT DISTINCT t.f1 FROM (SELECT * FROM t1) AS t, t2
+WHERE t.f2='s' AND t.f2 LIKE '%a%' OR t.f1<>0 ORDER BY t.f2;
+f1
+8
+DROP TABLE t1, t2;
+#
+# BUG##806524: Assertion `join->best_read < 1.7976931348623157e+308 with table_elimination=on and derived_merge=on
+#
+CREATE TABLE t1 ( f4 int) ;
+CREATE TABLE t2 ( f4 int) ;
+CREATE TABLE t3 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+CREATE TABLE t4 ( f2 int, f4 int) ;
+SELECT *
+FROM ( SELECT * FROM t1 ) AS alias1
+RIGHT JOIN (
+t2 AS alias2
+LEFT JOIN (
+SELECT t4.*
+FROM ( SELECT * FROM t3 ) AS SQ1_alias1
+RIGHT JOIN t4
+ON t4.f2 = SQ1_alias1.f1
+) AS alias3
+ON alias3.f4 != 0
+) ON alias3.f4 != 0;
+f4 f4 f2 f4
+drop table t1,t2,t3,t4;
+set optimizer_switch=@exit_optimizer_switch;
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index 5e3fc1e8cf1..9d572a0b223 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -1,5 +1,8 @@
drop table if exists t1,t2;
drop view if exists v1,v2,v3,v4;
+set @exit_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+set @save_optimizer_switch=@@optimizer_switch;
create table t1(f1 int, f11 int);
create table t2(f2 int, f22 int);
insert into t1 values(1,1),(2,2),(3,3),(5,5),(9,9),(7,7);
@@ -589,3 +592,1273 @@ f1 f1
224 224
DROP VIEW v1;
DROP TABLE t1,t2;
+#
+# LP bug #794890: abort failure on multi-update with view
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (20), (7);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (7), (9), (7);
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT a FROM t1;
+CREATE VIEW v2 AS SELECT t2.a FROM t2, v1 WHERE t2.a=t2.a;
+UPDATE v2 SET a = 2;
+SELECT * FROM t2;
+a
+2
+2
+2
+UPDATE t1,v2 SET t1.a = 3;
+SELECT * FROM t1;
+a
+3
+3
+DELETE t1 FROM t1,v2;
+SELECT * FROM t1;
+a
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+#
+# LP bug #802023: MIN/MAX optimization
+# for mergeable derived tables and views
+#
+CREATE TABLE t1 (a int, b int, c varchar(32), INDEX idx(a,b));
+INSERT INTO t1 VALUES
+(7, 74, 'yyyyyyy'), (9, 97, 'aaaaaaaaa'), (2, 23, 'tt'),
+(5, 55, 'ddddd'), (2, 27, 'ss'), (7, 76, 'xxxxxxx'),
+(7, 79, 'zzzzzzz'), (9, 92, 'bbbbbbbbb'), (2, 25, 'pp'),
+(5, 53, 'eeeee'), (2, 23, 'qq'), (7, 76,'wwwwwww'),
+(7, 74, 'uuuuuuu'), (9, 92, 'ccccccccc'), (2, 25, 'oo');
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT MIN(a) FROM t1 WHERE a >= 5;
+MIN(a)
+5
+EXPLAIN
+SELECT MIN(a) FROM t1 WHERE a >= 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MIN(a) FROM (SELECT * FROM t1) t WHERE a >= 5;
+MIN(a)
+5
+EXPLAIN
+SELECT MIN(a) FROM(SELECT * FROM t1) t WHERE a >= 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MIN(a) FROM v1 WHERE a >= 5;
+MIN(a)
+5
+EXPLAIN
+SELECT MIN(a) FROM v1 WHERE a >= 5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MAX(b) FROM t1 WHERE a=7 AND b<75;
+MAX(b)
+74
+EXPLAIN
+SELECT MAX(b) FROM t1 WHERE a=7 AND b<75;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MAX(b) FROM (SELECT * FROM t1) t WHERE a=7 AND b<75;
+MAX(b)
+74
+EXPLAIN
+SELECT MAX(b) FROM (SELECT * FROM t1) t WHERE a=7 AND b<75;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MAX(b) FROM v1 WHERE a=7 AND b<75;
+MAX(b)
+74
+EXPLAIN
+SELECT MAX(b) FROM v1 WHERE a=7 AND b<75;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# LP bug #800535: GROUP BY query with nested left join
+# and a derived table in the nest
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (1), (2);
+CREATE TABLE t2 (a int NOT NULL);
+INSERT INTO t2 VALUES (1), (2);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (3,3), (4,4);
+EXPLAIN EXTENDED
+SELECT t.a FROM t1 LEFT JOIN
+(t2 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+GROUP BY t.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 SIMPLE t ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t`.`a` AS `a` from `test`.`t1` left join (`test`.`t2` `t` join `test`.`t3`) on(((`test`.`t`.`a` >= 1) and (`test`.`t3`.`b` > 5))) where 1 group by `test`.`t`.`a`
+SELECT t.a FROM t1 LEFT JOIN
+(t2 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+GROUP BY t.a;
+a
+NULL
+EXPLAIN EXTENDED
+SELECT t.a FROM t1 LEFT JOIN
+(( SELECT * FROM t2 ) t JOIN t3 ON t3.b > 5) ON t.a >= 1
+GROUP BY t.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`a` >= 1) and (`test`.`t3`.`b` > 5))) where 1 group by `test`.`t2`.`a`
+SELECT t.a FROM t1 LEFT JOIN
+(( SELECT * FROM t2 ) t JOIN t3 ON t3.b > 5) ON t.a >= 1
+GROUP BY t.a;
+a
+NULL
+CREATE VIEW v1 AS SELECT * FROM t2;
+EXPLAIN EXTENDED
+SELECT t.a FROM t1 LEFT JOIN
+(v1 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+GROUP BY t.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`a` >= 1) and (`test`.`t3`.`b` > 5))) where 1 group by `test`.`t2`.`a`
+SELECT t.a FROM t1 LEFT JOIN
+(v1 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+GROUP BY t.a;
+a
+NULL
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #803410: materialized view/dt accessed by two-component key
+#
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('c');
+CREATE TABLE t2 (a varchar(1) , KEY (a)) ;
+INSERT INTO t2 VALUES ('c'), (NULL), ('r');
+CREATE TABLE t3 (a varchar(1), b varchar(1));
+INSERT INTO t3 VALUES
+('e', 'c'), ('c', 'c'), ('c', 'r'), ('g', 'a'), ('b', 'x'), ('b', 'y'),
+('h', 'w'), ('d', 'z'), ('k', 'v'), ('j', 's'), ('m', 'p'), ('l', 'q');
+CREATE VIEW v1 AS SELECT a, MIN(b) AS b FROM t3 GROUP BY a;
+EXPLAIN
+SELECT * FROM t1, t2, v1 WHERE t2.a=t1.a AND t2.a=v1.a AND t2.a=v1.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ref a a 4 const 1 Using index
+1 PRIMARY <derived2> ref key0 key0 10 const,const 1
+2 DERIVED t3 ALL NULL NULL NULL NULL 12 Using temporary; Using filesort
+SELECT * FROM t1, t2, v1 WHERE t2.a=t1.a AND t2.a=v1.a AND t2.a=v1.b;
+a a a b
+c c c c
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #802845: select from derived table with limit 0
+#
+SELECT * FROM (SELECT 1 LIMIT 0) t;
+1
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (7), (1), (3);
+SELECT * FROM (SELECT * FROM t1 LIMIT 0) t;
+a
+DROP TABLE t1;
+#
+# LP bug #803851: materialized view + IN->EXISTS
+#
+SET SESSION optimizer_switch='semijoin=off,derived_with_keys=on';
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,2), (3,3), (1,1);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1), (2), (1);
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (3), (1), (2), (1);
+CREATE VIEW v1 AS SELECT a, MAX(b) AS b FROM t1 GROUP BY a;
+EXPLAIN EXTENDED
+SELECT * FROM t3
+WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b);
+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
+2 DEPENDENT SUBQUERY <derived3> ref key1 key1 5 func 2 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+3 DERIVED t1 ALL NULL NULL NULL NULL 3 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select `v1`.`a` from `test`.`v1` join `test`.`t2` where ((`test`.`t2`.`a` = `v1`.`b`) and (<cache>(`test`.`t3`.`a`) = `v1`.`a`)))))
+SELECT * FROM t3
+WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b);
+a
+1
+2
+1
+SET SESSION optimizer_switch=@save_optimizer_switch;
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #804515: materialized derived + ORDER BY
+#
+CREATE TABLE t1 (f1 varchar(1), f2 varchar(1), KEY (f2));
+INSERT INTO t1 VALUES
+('r','x'), ('x','d'), ('x','r'), ('r','f'), ('x','x');
+CREATE TABLE t2 (f1 varchar(1), f2 varchar(1));
+INSERT INTO t2 VALUES ('s','x');
+CREATE TABLE t3 (f1 varchar(1), f2 varchar(1), KEY (f2));
+INSERT INTO t3 VALUES
+(NULL,'x'), (NULL,'f'), ('t','p'), (NULL,'j'), ('g','c');
+CREATE TABLE t4 (f1 int, f2 varchar(1), KEY (f2,f1)) ;
+INSERT INTO t4 VALUES (1,'x'), (5,'r');
+EXPLAIN
+SELECT t.f1 AS f
+FROM (SELECT DISTINCT t1.* FROM t1,t2 WHERE t2.f2 = t1.f2) t,t3,t4
+WHERE t4.f2 = t3.f2 AND t4.f2 = t.f1 ORDER BY f;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using where; Using filesort
+1 PRIMARY t4 ref f2 f2 4 t.f1 1 Using index
+1 PRIMARY t3 ref f2 f2 4 t.f1 2 Using index
+2 DERIVED t2 system NULL NULL NULL NULL 1 Using temporary
+2 DERIVED t1 ref f2 f2 4 const 2 Using where
+SELECT t.f1 AS f
+FROM (SELECT DISTINCT t1.* FROM t1,t2 WHERE t2.f2 = t1.f2) t,t3,t4
+WHERE t4.f2 = t3.f2 AND t4.f2 = t.f1 ORDER BY f;
+f
+x
+DROP TABLE t1,t2,t3,t4;
+#
+# LP bug #806431: join over materialized derived with key
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (0,0),(3,0),(1,0);
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT a,b FROM t1 ;
+SET SESSION optimizer_switch='derived_with_keys=off';
+SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
+a b a b
+0 0 0 0
+0 0 3 0
+0 0 1 0
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY <derived2> ref key0 key0 5 test.t.a 2
+2 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
+a b a b
+0 0 1 0
+0 0 3 0
+0 0 0 0
+SET SESSION optimizer_switch=@save_optimizer_switch;
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# LP bug #806477: left join over merged join with
+# where condition containing f=f
+#
+CREATE TABLE t1 (a int NOT NULL);
+INSERT INTO t1 VALUES (1), (50), (0);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (76,2), (1,NULL);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT t3.b, v1.a
+FROM t3 LEFT JOIN (t2, v1) ON t3.a <> 0
+WHERE v1.a = v1.a OR t3.b <> 0;
+b a
+2 NULL
+EXPLAIN EXTENDED
+SELECT t3.b, v1.a
+FROM t3 LEFT JOIN (t2, v1) ON t3.a <> 0
+WHERE v1.a = v1.a OR t3.b <> 0;
+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
+1 SIMPLE t2 ALL NULL NULL NULL NULL 0 0.00 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t3`.`b` AS `b`,`test`.`t1`.`a` AS `a` from `test`.`t3` left join (`test`.`t2` join `test`.`t1`) on((`test`.`t3`.`a` <> 0)) where ((`test`.`t1`.`a` = `test`.`t1`.`a`) or (`test`.`t3`.`b` <> 0))
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #806510: subquery with outer reference
+# to a derived_table/view
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (4), (NULL);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (8), (0);
+CREATE TABLE t3 (a int, b int) ;
+INSERT INTO t3 VALUES (7,8);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t1 t
+WHERE EXISTS (SELECT t3.a FROM t3, t2
+WHERE t2.a = t3.b AND t.a != 0);
+a
+4
+EXPLAIN
+SELECT * FROM t1 t
+WHERE EXISTS (SELECT t3.a FROM t3, t2
+WHERE t2.a = t3.b AND t.a != 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM (SELECT * FROM t1) t
+WHERE EXISTS (SELECT t3.a FROM t3, t2
+WHERE t2.a = t3.b AND t.a != 0);
+a
+4
+EXPLAIN
+SELECT * FROM (SELECT * FROM t1) t
+WHERE EXISTS (SELECT t3.a FROM t3, t2
+WHERE t2.a = t3.b AND t.a != 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+3 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 1
+3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM v1 t
+WHERE EXISTS (SELECT t3.a FROM t3, t2
+WHERE t2.a = t3.b AND t.a != 0);
+a
+4
+EXPLAIN
+SELECT * FROM v1 t
+WHERE EXISTS (SELECT t3.a FROM t3, t2
+WHERE t2.a = t3.b AND t.a != 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #806097: left join over a view + DISTINCT
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (252,6), (232,0), (174,232);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (232), (174);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (1), (2);
+CREATE VIEW v1 AS SELECT t2.a FROM t3,t2;
+SELECT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0;
+a
+NULL
+232
+174
+232
+174
+NULL
+SELECT DISTINCT t2.a FROM t1 LEFT JOIN (t3,t2) ON t1.b = 0;
+a
+NULL
+232
+174
+EXPLAIN
+SELECT DISTINCT t2.a FROM t1 LEFT JOIN (t3,t2) ON t1.b = 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+SELECT DISTINCT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0;
+a
+NULL
+232
+174
+EXPLAIN
+SELECT DISTINCT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using temporary
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #806504: right join over a view/derived table
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (0), (0);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+a a b
+NULL 0 0
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` semi join (`test`.`t1`) left join `test`.`t2` on((0 <> 0)) where 1
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+a a b
+NULL 0 0
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` semi join (`test`.`t1`) left join `test`.`t2` on((0 <> 0)) where 1
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #809206: DISTINCT in derived table / view
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2 (a varchar(32), b int, KEY (a)) ;
+INSERT INTO t2 VALUES
+('j',28), ('c',29), ('i',26), ('c',29), ('k',27),
+('j',28), ('c',29), ('i',25), ('d',26), ('k',27),
+('n',28), ('d',29), ('m',26), ('e',29), ('p',27),
+('w',28), ('x',29), ('y',25), ('z',26), ('s',27);
+CREATE TABLE t3 (a varchar(32));
+INSERT INTO t3 VALUES ('j'), ('c');
+CREATE VIEW v1 AS SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
+SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
+b
+28
+29
+EXPLAIN
+SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where
+1 SIMPLE t2 ref a a 35 test.t3.a 2
+SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t;
+b
+28
+29
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+2 DERIVED t1 system NULL NULL NULL NULL 1 Using temporary
+2 DERIVED t3 ALL NULL NULL NULL NULL 2 Using where
+2 DERIVED t2 ref a a 35 test.t3.a 2
+SELECT * FROM v1;
+b
+28
+29
+EXPLAIN
+SELECT * FROM v1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+2 DERIVED t1 system NULL NULL NULL NULL 1 Using temporary
+2 DERIVED t3 ALL NULL NULL NULL NULL 2 Using where
+2 DERIVED t2 ref a a 35 test.t3.a 2
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #809179: right join over a derived table / view
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (6,5);
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (1,0);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (6,5);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT t.a,t.b FROM t3 RIGHT JOIN (t1 AS t, t2) ON t2.b != 0
+WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+a b
+6 5
+EXPLAIN EXTENDED
+SELECT t.a,t.b FROM t3 RIGHT JOIN (t1 AS t, t2) ON t2.b != 0
+WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select 6 AS `a`,5 AS `b` from `test`.`t1` `t` join `test`.`t2` left join `test`.`t3` on((0 <> 0)) where (not(<expr_cache><6,5>(<in_optimizer>((6,5),<exists>(select 7,5 having (trigcond(((<cache>(6) = 7) or isnull(7))) and trigcond(((<cache>(5) = 5) or isnull(5))) and trigcond(<is_not_null_test>(7)) and trigcond(<is_not_null_test>(5))))))))
+SELECT t.a,t.b FROM t3 RIGHT JOIN ((SELECT * FROM t1) AS t, t2) ON t2.b != 0
+WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+a b
+6 5
+EXPLAIN EXTENDED
+SELECT t.a,t.b FROM t3 RIGHT JOIN ((SELECT * FROM t1) AS t, t2) ON t2.b != 0
+WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select 6 AS `a`,5 AS `b` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on((0 <> 0)) where (not(<expr_cache><6,5>(<in_optimizer>((6,5),<exists>(select 7,5 having (trigcond(((<cache>(6) = 7) or isnull(7))) and trigcond(((<cache>(5) = 5) or isnull(5))) and trigcond(<is_not_null_test>(7)) and trigcond(<is_not_null_test>(5))))))))
+SELECT t.a,t.b FROM t3 RIGHT JOIN (v1 AS t, t2) ON t2.b != 0
+WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+a b
+6 5
+EXPLAIN EXTENDED
+SELECT t.a,t.b FROM t3 RIGHT JOIN (v1 AS t, t2) ON t2.b != 0
+WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t3 system NULL NULL NULL NULL 1 100.00
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select 6 AS `a`,5 AS `b` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on((0 <> 0)) where (not(<expr_cache><6,5>(<in_optimizer>((6,5),<exists>(select 7,5 having (trigcond(((<cache>(6) = 7) or isnull(7))) and trigcond(((<cache>(5) = 5) or isnull(5))) and trigcond(<is_not_null_test>(7)) and trigcond(<is_not_null_test>(5))))))))
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #794901: insert into a multi-table view
+#
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int);
+CREATE VIEW v1 AS SELECT t1.a FROM t1,t2;
+CREATE VIEW v2 AS SELECT a FROM t2 GROUP BY a;
+CREATE VIEW v3 AS SELECT v1.a FROM v1,v2;
+INSERT INTO v3(a) VALUES (1);
+ERROR HY000: The target table v3 of the INSERT is not insertable-into
+DROP VIEW v1,v2,v3;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #793448: materialized view accessed by two-component key
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (9,3), (2,5);
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (9,3), (3,7), (9,1), (2,5), (2,4), (3,8);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,3), (9,7), (9,1), (2,4);
+CREATE VIEW v1(a,b) AS SELECT a, MAX(b) FROM t2 GROUP BY a;
+CREATE VIEW v2(a,b) AS SELECT a,b FROM t2 UNION SELECT a,b FROM t3;
+SELECT * FROM v1;
+a b
+2 5
+3 8
+9 3
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+a
+9
+2
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1)
+3 DERIVED t2 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
+SELECT * FROM v2;
+a b
+9 3
+3 7
+9 1
+2 5
+2 4
+3 8
+10 3
+9 7
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+a
+9
+2
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1)
+3 DERIVED t2 ALL NULL NULL NULL NULL 6
+4 UNION t3 ALL NULL NULL NULL NULL 4
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #804686: query over a derived table using a view
+# with a degenerated where condition
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (0,0), (1,0), (0,0), (1,1), (1,0);
+CREATE VIEW v1 AS SELECT a,b FROM t1;
+CREATE VIEW v2 AS SELECT a, MAX(b) AS b FROM t1 GROUP BY a;
+SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b<>0;
+b
+SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b<>0;
+b
+SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b;
+b
+SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b;
+b
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b;
+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
+Warnings:
+Note 1003 select `test`.`t1`.`b` AS `b` from `test`.`t1` where 0
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b;
+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
+3 DERIVED t1 ALL NULL NULL NULL NULL 5 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `v2`.`b` AS `b` from `test`.`v2` where 0
+DROP VIEW v1,v2;
+DROP TABLE t1;
+#
+# LP bug #819716: crash with embedded tableless materialized derived
+# with a variable
+#
+set optimizer_switch='derived_merge=off';
+EXPLAIN
+SELECT * FROM (SELECT * FROM (SELECT @b) AS t) AS s;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1
+2 DERIVED <derived3> system NULL NULL NULL NULL 1
+3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
+SELECT * FROM (SELECT * FROM (SELECT @b) AS t) AS s;
+@b
+NULL
+set optimizer_switch='derived_merge=on';
+#
+# LP bug #823826: view over join + IS NULL in WHERE
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (1), (1);
+CREATE TABLE t2 (b int) ;
+INSERT INTO t2 VALUES (9), (NULL), (7);
+CREATE VIEW v1 AS SELECT * FROM t1,t2;
+EXPLAIN
+SELECT * FROM (SELECT * FROM t1,t2) t WHERE b IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM (SELECT * FROM t1,t2) t WHERE b IS NULL;
+a b
+1 NULL
+1 NULL
+EXPLAIN
+SELECT * FROM v1 WHERE b IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM v1 WHERE b IS NULL;
+a b
+1 NULL
+1 NULL
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #823835: a duplicate of #823189 with derived table
+#
+CREATE TABLE t1 (a varchar(32)) ;
+INSERT INTO t1 VALUES ('r'), ('p');
+CREATE TABLE t2 (a int NOT NULL, b varchar(32)) ;
+INSERT INTO t2 VALUES (28,'j');
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (0), (0);
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT * FROM t1) AS t
+WHERE EXISTS (SELECT t2.a FROM t3 RIGHT JOIN t2 ON (t3.a = t2.a)
+WHERE t2.b < t.a);
+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 Using where
+3 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 't.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 28 from `test`.`t2` left join `test`.`t3` on((`test`.`t3`.`a` = 28)) where ('j' < `test`.`t1`.`a`)))
+SELECT * FROM (SELECT * FROM t1) AS t
+WHERE EXISTS (SELECT t2.a FROM t3 RIGHT JOIN t2 ON (t3.a = t2.a)
+WHERE t2.b < t.a);
+a
+r
+p
+DROP TABLE t1,t2,t3;
+#
+# LP bug #824463: nested outer join using a merged view
+# as an inner table
+#
+CREATE TABLE t1 (b int, a int) ;
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (5), (6);
+CREATE TABLE t3 (a int , c int) ;
+INSERT INTO t3 VALUES (22,1), (23,-1);
+CREATE TABLE t4 (a int);
+CREATE TABLE t5 (d int) ;
+INSERT INTO t5 VALUES (0), (7), (3), (5);
+CREATE VIEW v2 AS SELECT * FROM t2;
+CREATE VIEW v3 AS SELECT * FROM t3;
+EXPLAIN EXTENDED
+SELECT STRAIGHT_JOIN *
+FROM ( t2 AS s2
+JOIN
+( t3 AS s3
+LEFT JOIN
+( t4 LEFT JOIN t3 ON t4.a != 0 )
+ON s3.a != 0)
+ON s2.a != 0)
+JOIN t5 ON s3.c != 0 AND t5.d = 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE s2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE s3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 0 0.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select straight_join `test`.`s2`.`a` AS `a`,`test`.`s3`.`a` AS `a`,`test`.`s3`.`c` AS `c`,`test`.`t4`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`test`.`t5`.`d` AS `d` from `test`.`t2` `s2` join `test`.`t3` `s3` left join (`test`.`t4` left join `test`.`t3` on((`test`.`t4`.`a` <> 0))) on((`test`.`s3`.`a` <> 0)) join `test`.`t5` where ((`test`.`t5`.`d` = 0) and (`test`.`s3`.`c` <> 0) and (`test`.`s2`.`a` <> 0))
+SELECT STRAIGHT_JOIN *
+FROM ( t2 AS s2
+JOIN
+( t3 AS s3
+LEFT JOIN
+( t4 LEFT JOIN t3 ON t4.a != 0 )
+ON s3.a != 0)
+ON s2.a != 0)
+JOIN t5 ON s3.c != 0 AND t5.d = 0;
+a a c a a c d
+5 22 1 NULL NULL NULL 0
+6 22 1 NULL NULL NULL 0
+5 23 -1 NULL NULL NULL 0
+6 23 -1 NULL NULL NULL 0
+EXPLAIN EXTENDED
+SELECT STRAIGHT_JOIN *
+FROM t2 AS s2 , t5,
+(t3 LEFT JOIN (t4 LEFT JOIN t3 AS s3 ON t4.a != 0) ON t3.a != 0)
+WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE s2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 0 0.00 Using where
+1 SIMPLE s3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select straight_join `test`.`s2`.`a` AS `a`,`test`.`t5`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`test`.`t4`.`a` AS `a`,`test`.`s3`.`a` AS `a`,`test`.`s3`.`c` AS `c` from `test`.`t2` `s2` join `test`.`t5` join `test`.`t3` left join (`test`.`t4` left join `test`.`t3` `s3` on((`test`.`t4`.`a` <> 0))) on((`test`.`t3`.`a` <> 0)) where ((`test`.`t5`.`d` = 0) and (`test`.`s2`.`a` <> 0) and (`test`.`t3`.`c` <> 0))
+SELECT STRAIGHT_JOIN *
+FROM t2 AS s2 , t5,
+(t3 LEFT JOIN (t4 LEFT JOIN t3 AS s3 ON t4.a != 0) ON t3.a != 0)
+WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+a d a c a a c
+5 0 22 1 NULL NULL NULL
+6 0 22 1 NULL NULL NULL
+5 0 23 -1 NULL NULL NULL
+6 0 23 -1 NULL NULL NULL
+EXPLAIN EXTENDED
+SELECT STRAIGHT_JOIN *
+FROM v2 AS s2 , t5,
+(t3 LEFT JOIN (t4 LEFT JOIN v3 AS s3 ON t4.a != 0) ON t3.a != 0)
+WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t5 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 0 0.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select straight_join `test`.`t2`.`a` AS `a`,`test`.`t5`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c`,`test`.`t4`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`c` AS `c` from `test`.`t2` join `test`.`t5` join `test`.`t3` left join (`test`.`t4` left join (`test`.`t3`) on((`test`.`t4`.`a` <> 0))) on((`test`.`t3`.`a` <> 0)) where ((`test`.`t5`.`d` = 0) and (`test`.`t2`.`a` <> 0) and (`test`.`t3`.`c` <> 0))
+SELECT STRAIGHT_JOIN *
+FROM v2 AS s2 , t5,
+(t3 LEFT JOIN (t4 LEFT JOIN v3 AS s3 ON t4.a != 0) ON t3.a != 0)
+WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+a d a c a a c
+5 0 22 1 NULL NULL NULL
+6 0 22 1 NULL NULL NULL
+5 0 23 -1 NULL NULL NULL
+6 0 23 -1 NULL NULL NULL
+SELECT STRAIGHT_JOIN *
+FROM ( ( t2 AS s2
+LEFT JOIN
+( t3 AS s3
+LEFT JOIN
+( t4 AS s4 JOIN t3 ON s4.a != 0)
+ON s3.a != 0 )
+ON s2.a != 0)
+LEFT JOIN
+t1 AS s1
+ON s1.a != 0)
+JOIN t5 ON s3.c != 0;
+a a c a a c b a d
+5 22 1 NULL NULL NULL NULL NULL 0
+6 22 1 NULL NULL NULL NULL NULL 0
+5 23 -1 NULL NULL NULL NULL NULL 0
+6 23 -1 NULL NULL NULL NULL NULL 0
+5 22 1 NULL NULL NULL NULL NULL 7
+6 22 1 NULL NULL NULL NULL NULL 7
+5 23 -1 NULL NULL NULL NULL NULL 7
+6 23 -1 NULL NULL NULL NULL NULL 7
+5 22 1 NULL NULL NULL NULL NULL 3
+6 22 1 NULL NULL NULL NULL NULL 3
+5 23 -1 NULL NULL NULL NULL NULL 3
+6 23 -1 NULL NULL NULL NULL NULL 3
+5 22 1 NULL NULL NULL NULL NULL 5
+6 22 1 NULL NULL NULL NULL NULL 5
+5 23 -1 NULL NULL NULL NULL NULL 5
+6 23 -1 NULL NULL NULL NULL NULL 5
+SELECT STRAIGHT_JOIN *
+FROM ( ( v2 AS s2
+LEFT JOIN
+( v3 AS s3
+LEFT JOIN
+( t4 AS s4 JOIN v3 ON s4.a != 0)
+ON s3.a != 0 )
+ON s2.a != 0)
+LEFT JOIN
+t1 AS s1
+ON s1.a != 0)
+JOIN t5 ON s3.c != 0;
+a a c a a c b a d
+5 22 1 NULL NULL NULL NULL NULL 0
+6 22 1 NULL NULL NULL NULL NULL 0
+5 23 -1 NULL NULL NULL NULL NULL 0
+6 23 -1 NULL NULL NULL NULL NULL 0
+5 22 1 NULL NULL NULL NULL NULL 7
+6 22 1 NULL NULL NULL NULL NULL 7
+5 23 -1 NULL NULL NULL NULL NULL 7
+6 23 -1 NULL NULL NULL NULL NULL 7
+5 22 1 NULL NULL NULL NULL NULL 3
+6 22 1 NULL NULL NULL NULL NULL 3
+5 23 -1 NULL NULL NULL NULL NULL 3
+6 23 -1 NULL NULL NULL NULL NULL 3
+5 22 1 NULL NULL NULL NULL NULL 5
+6 22 1 NULL NULL NULL NULL NULL 5
+5 23 -1 NULL NULL NULL NULL NULL 5
+6 23 -1 NULL NULL NULL NULL NULL 5
+DROP VIEW v2,v3;
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# LP bug #872735: derived used in a NOT IN subquery
+#
+CREATE TABLE t1 (b int NOT NULL);
+INSERT INTO t1 VALUES (9), (7);
+CREATE TABLE t2 (a int NOT NULL) ;
+INSERT INTO t2 VALUES (1), (2);
+CREATE TABLE t3 (
+a int NOT NULL , c int NOT NULL, d varchar(1) NOT NULL,
+KEY (c,a) , PRIMARY KEY (a)
+);
+INSERT INTO t3 VALUES
+(14,4,'a'), (15,7,'b'), (16,4,'c'), (17,1,'d'), (18,9,'e'),
+(19,4,'f'), (20,8,'g');
+SET SESSION optimizer_switch='derived_merge=on,subquery_cache=off';
+# The following two EXPLAINs must return the same execution plan
+EXPLAIN
+SELECT * FROM t1 , t2
+WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM t3 t);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t ref PRIMARY,c c 4 func 2 Using where; Using index
+EXPLAIN
+SELECT * FROM t1 , t2
+WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t3 ref PRIMARY,c c 4 func 2 Using where; Using index
+SELECT * FROM t1 , t2
+WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t);
+b a
+9 1
+7 1
+9 2
+7 2
+DROP TABLE t1,t2,t3;
+#
+# LP bug #874006: materialized view used in IN subquery
+#
+CREATE TABLE t3 (a int NOT NULL, b varchar(1), c varchar(1));
+INSERT INTO t3 VALUES (19,NULL,NULL), (20,'r','r');
+CREATE TABLE t1 (a int, b varchar(1) , c varchar(1));
+INSERT INTO t1 VALUES (1,NULL,NULL), (5,'r','r'), (7,'y','y');
+CREATE TABLE t2 (a int NOT NULL , b int, c varchar(1));
+INSERT INTO t2 VALUES (4,3,'r');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Start temporary
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 Using where; End temporary; Using join buffer (flat, BNL join)
+3 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+a b c
+20 r r
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY <derived3> ref key1 key1 10 const,const 0 Start temporary
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+3 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+a b c
+20 r r
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #873263: materialized view used in correlated IN subquery
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (5,4), (9,8);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (4,5), (5,1);
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.b,test.t1.a 2 FirstMatch(t1)
+3 DERIVED t2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+a b
+5 4
+DROP VIEW v2;
+DROP TABLE t1,t2;
+#
+# LP bug #877316: query over a view with correlated subquery in WHERE
+#
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (18,2), (19,9);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (10,8), (5,10);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT t1.a FROM t1
+WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < t1.b);
+a
+19
+EXPLAIN
+SELECT t1.a FROM t1
+WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < t1.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT v1.a FROM v1
+WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < v1.b);
+a
+19
+EXPLAIN
+SELECT v1.a FROM v1
+WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < v1.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #878199: join of two materialized views
+#
+CREATE TABLE t1 (a int, b varchar(1)) ;
+INSERT INTO t1 VALUES (7,'c'), (3,'h'), (7,'c');
+CREATE TABLE t2 (b varchar(1)) ;
+INSERT INTO t2 VALUES ('p'), ('c'), ('j'), ('c'), ('p');
+CREATE VIEW v1 AS SELECT * FROM t1 GROUP BY a,b;
+CREATE VIEW v2 AS SELECT * FROM t2 GROUP BY b;
+SET SESSION optimizer_switch = 'derived_with_keys=on';
+SELECT v1.a FROM v1,v2 WHERE v2.b = v1.b ORDER BY 1;
+a
+7
+EXPLAIN
+SELECT v1.a FROM v1,v2 WHERE v2.b = v1.b ORDER BY 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL key0 NULL NULL NULL 3 Using where; Using filesort
+1 PRIMARY <derived3> ref key0 key0 5 v1.b 2
+3 DERIVED t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
+2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+#
+# Bug #743378: join over merged view employing BNL
+#
+CREATE TABLE t1 ( d varchar(1) NOT NULL) ;
+INSERT INTO t1 VALUES ('j'),('v'),('c');
+CREATE TABLE t2 (h time NOT NULL, d varchar(1) NOT NULL) ;
+INSERT INTO t2 VALUES ('05:03:03','w'),('02:59:24','d'),('00:01:58','e');
+CREATE TABLE t3 (
+b int NOT NULL, e varchar(1) NOT NULL, d varchar(1) NOT NULL, KEY (e,b)
+);
+INSERT INTO t3 VALUES (4,'x','x'),(9,'w','w'),(4,'d','d'),(8,'e','e');
+CREATE TABLE t4 (i int NOT NULL, m varchar(1) NOT NULL) ;
+INSERT INTO t4 VALUES (8,'m'),(9,'d'),(2,'s'),(4,'r'),(8,'m');
+CREATE TABLE t5 (
+a int NOT NULL, c int NOT NULL, b int NOT NULL, f date NOT NULL,
+g date NOT NULL, h time NOT NULL, j time NOT NULL, k datetime NOT NULL
+);
+INSERT INTO t5 VALUES
+(1,4,0,'0000-00-00','0000-00-00','21:22:34','21:22:34','2002-02-13 17:30'),
+(2,6,8,'2004-09-18','2004-09-18','10:50:38','10:50:38','2008-09-27 00:34');
+CREATE VIEW v3 AS SELECT t3.*, t4.i FROM t3, t4, t5;
+SET SESSION join_cache_level = 1;
+SET SESSION join_buffer_size = 512;
+EXPLAIN
+SELECT t2.d FROM t1,t2,v3 WHERE v3.e = t2.d AND v3.i < 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 3
+1 SIMPLE t3 ref e e 3 test.t2.d 1 Using index
+1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using join buffer (flat, BNL join)
+1 SIMPLE t4 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
+SELECT t2.d FROM t1,t2,v3 WHERE v3.e = t2.d AND v3.i < 3;
+d
+w
+d
+e
+w
+d
+e
+w
+d
+e
+w
+d
+e
+w
+d
+e
+w
+d
+e
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION join_buffer_size = DEFAULT;
+DROP VIEW v3;
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# Bug #879882: right join within mergeable derived table
+#
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('c'), ('a');
+CREATE TABLE t2 (a int, b int, c varchar(1));
+INSERT INTO t2 VALUES (29,8,'c'), (39,7,'b');
+CREATE TABLE t3 (b int);
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b AND t.c = t1.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t3 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on(multiple equal(NULL, `test`.`t2`.`a`)) where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and `test`.`t2`.`b`)
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b AND t.c = t1.a;
+b c a
+8 c c
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b <> 0 AND t.c = t1.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t3 system NULL NULL NULL NULL 0 0.00 const row not found
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on(multiple equal(NULL, `test`.`t2`.`a`)) where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t2`.`b` <> 0))
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b <> 0 AND t.c = t1.a;
+b c a
+8 c c
+INSERT INTO t3 VALUES (100), (200);
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b AND t.c = t1.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on((`test`.`t3`.`b` = `test`.`t2`.`a`)) where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and `test`.`t2`.`b`)
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b AND t.c = t1.a;
+b c a
+8 c c
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b <> 0 AND t.c = t1.a;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` left join `test`.`t3` on((`test`.`t3`.`b` = `test`.`t2`.`a`)) where ((`test`.`t2`.`c` = `test`.`t1`.`a`) and (`test`.`t2`.`b` <> 0))
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+WHERE t.b <> 0 AND t.c = t1.a;
+b c a
+8 c c
+DROP TABLE t1,t2,t3;
+#
+# Bug #880724: materialized const view as inner table of outer join
+#
+CREATE TABLE t1 (a int, b varchar(1));
+INSERT INTO t1 VALUES (9,NULL), (6,'r'), (7,'c');
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (6);
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+SET SESSION optimizer_switch = 'derived_with_keys=on';
+SET SESSION join_cache_level = 4;
+EXPLAIN
+SELECT t1.b,v2.a FROM t1 LEFT JOIN v2 ON v2.a = t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 1 Using where
+2 DERIVED t2 system NULL NULL NULL NULL 1
+SELECT t1.b,v2.a FROM t1 LEFT JOIN v2 ON v2.a = t1.a;
+b a
+NULL NULL
+r 6
+c NULL
+CREATE TABLE t3 (a int, b varchar(1));
+INSERT INTO t3 VALUES (8,'x'), (5,'r'), (9,'y');
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b <> ANY (SELECT t1.b FROM t1 LEFT JOIN v2 ON v2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 1 Using where
+3 DERIVED t2 system NULL NULL NULL NULL 1
+SELECT * FROM t3
+WHERE t3.b <> ANY (SELECT t1.b FROM t1 LEFT JOIN v2 ON v2.a = t1.a);
+a b
+8 x
+5 r
+9 y
+SET SESSION join_cache_level = default;
+DROP VIEW v2;
+DROP TABLE t1,t2,t3;
+#
+# Bug #881449: OUTER JOIN usin a merged view within IN subquery
+#
+CREATE TABLE t1 (a varchar(1)) ;
+INSERT INTO t1 VALUES ('y'), ('x');
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (1), (2);
+CREATE TABLE t3 (a int, b varchar(1)) ;
+INSERT INTO t3 VALUES (1,'x');
+CREATE VIEW v3 AS SELECT * FROM t3;
+SET SESSION optimizer_switch='semijoin=on';
+EXPLAIN
+SELECT * FROM t1 WHERE a IN (SELECT v3.b FROM t2 RIGHT JOIN v3 ON v3.a = t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+1 PRIMARY t2 const PRIMARY PRIMARY 4 const 1 Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1 WHERE a IN (SELECT v3.b FROM t2 RIGHT JOIN v3 ON v3.a = t2.a);
+a
+x
+set optimizer_switch= @save_optimizer_switch;
+DROP VIEW v3;
+DROP TABLE t1,t2,t3;
+#
+# Bug #874035: view as an inner table of a materialized derived
+#
+CREATE TABLE t2 (a int NOT NULL);
+INSERT INTO t2 VALUES (7), (4);
+CREATE TABLE t1 (b int NOT NULL);
+INSERT INTO t1 VALUES (5), (7);
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
+SET SESSION optimizer_switch='derived_merge=off';
+PREPARE st1 FROM
+'SELECT * FROM (SELECT * FROM t2 LEFT JOIN v1 ON t2.a = v1.b) AS t';
+EXECUTE st1;
+a b
+7 7
+4 NULL
+EXECUTE st1;
+a b
+7 7
+4 NULL
+DEALLOCATE PREPARE st1;
+DROP VIEW v1;
+DROP TABLE t1,t2;
+SET SESSION optimizer_switch='derived_merge=on';
+#
+# LP bug #879939: assertion in ha_maria::enable_indexes
+# with derived_with_keys=on
+#
+CREATE TABLE t2 (a varchar(3));
+INSERT INTO t2 VALUES ('USA'), ('USA'), ('USA'), ('USA'), ('USA');
+CREATE TABLE t1 (a varchar(3), b varchar(35));
+INSERT INTO t1 VALUES
+('USA','Lansing'), ('USA','Laredo'), ('USA','Las Vegas'),
+('USA','Lexington-Fayett'), ('USA','Lincoln'), ('USA','Little Rock'),
+('USA','Livonia'), ('USA','Long Beach'), ('USA','Los Angeles'),
+('USA','Louisville'), ('USA','Lowell'), ('USA','Lubbock'),
+('USA','Macon'), ('USA','Madison'), ('USA','Manchester'),
+('USA','McAllen'), ('USA','Memphis'), ('USA','Mesa'),
+('USA','Mesquite'), ('USA','Metairie'), ('USA','Miami');
+CREATE TABLE t3 (a varchar(35));
+INSERT INTO t3 VALUES ('Miami');
+SET optimizer_switch = 'derived_with_keys=on';
+SET @@tmp_table_size=1024*4;
+explain SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 system NULL NULL NULL NULL 1
+1 SIMPLE t2 ALL NULL NULL NULL NULL 5
+1 SIMPLE t1 ALL NULL NULL NULL NULL 21 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
+a b a
+USA Miami Miami
+USA Miami Miami
+USA Miami Miami
+USA Miami Miami
+USA Miami Miami
+SET @@tmp_table_size=1024*1024*16;
+SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
+a b a
+USA Miami Miami
+USA Miami Miami
+USA Miami Miami
+USA Miami Miami
+USA Miami Miami
+SET @@tmp_table_size=default;
+drop table t1,t2,t3;
+#
+# BUG#882994: Crash in QUICK_RANGE_SELECT::reset with derived_with_keys
+#
+CREATE TABLE t2 (
+pk varchar(33),
+col_varchar_key varchar(3) NOT NULL,
+col_varchar_nokey varchar(52) NOT NULL);
+INSERT INTO t2 VALUES ('NICSpanish','NIC','Spanish'),
+('NERHausa','NER','Hausa'),('NGAJoruba','NGA','Joruba'),
+('NIUNiue','NIU','Niue'),('NFKEnglish','NFK','English'),
+('NORNorwegian','NOR','Norwegian'),('CIVAkan','CIV','Akan'),
+('OMNArabic','OMN','Arabic'),('PAKPunjabi','PAK','Punjabi'),
+('PLWPalau','PLW','Palau'),('PANSpanish','PAN','Spanish'),
+('PNGPapuan Langua','PNG','Papuan Languages'), ('PRYSpanish','PRY','Spanish'),
+('PERSpanish','PER','Spanish'), ('PCNPitcairnese','PCN','Pitcairnese'),
+('MNPPhilippene La','MNP','Philippene Langu'),('PRTPortuguese','PRT','Portuguese'),
+('PRISpanish','PRI','Spanish'),('POLPolish','POL','Polish'),('GNQFang','GNQ','Fang');
+CREATE TABLE t1 ( col_varchar_nokey varchar(52) NOT NULL ) ;
+INSERT INTO t1 VALUES ('Chinese'),('English'),('French'),('German'),
+('Italian'),('Japanese'),('Korean'),('Polish'),('Portuguese'),('Spanish'),
+('Tagalog'),('Vietnamese');
+CREATE TABLE t3 ( col_varchar_key varchar(52)) ;
+INSERT INTO t3 VALUES ('United States');
+set @tmp_882994= @@max_heap_table_size;
+set max_heap_table_size=1;
+SELECT *
+FROM t3 JOIN
+( SELECT t2.* FROM t1, t2 ) AS alias2
+ON ( alias2.col_varchar_nokey = t3.col_varchar_key )
+ORDER BY CONCAT(alias2.col_varchar_nokey);
+col_varchar_key pk col_varchar_key col_varchar_nokey
+set max_heap_table_size= @tmp_882994;
+drop table t1,t2,t3;
+set optimizer_switch=@exit_optimizer_switch;
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index d18af9fd4e1..955120a86a2 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -13,7 +13,7 @@ id str
3 foo
explain select * from t1 where str is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref str str 11 const 1 Using index condition
+1 SIMPLE t1 ref str str 11 const 1 Using where
explain select * from t1 where str="foo";
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const str str 11 const 1
@@ -171,7 +171,7 @@ DROP TABLE t1;
# Bug#48295:
# explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode
#
-CREATE TABLE t1 (f1 INT);
+CREATE TABLE t1 (f1 INT not null);
SELECT @@session.sql_mode INTO @old_sql_mode;
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
EXPLAIN EXTENDED SELECT 1 FROM t1
@@ -267,7 +267,7 @@ WHERE t1.f1 GROUP BY t1.f1));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
2 SUBQUERY a system NULL NULL NULL NULL 1
-2 SUBQUERY t1 fulltext f1 f1 0 1 Using where
+2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where
PREPARE stmt FROM
'EXPLAIN SELECT 1 FROM t1
WHERE 1 > ALL((SELECT 1 FROM t1 RIGHT OUTER JOIN t1 a
@@ -277,12 +277,12 @@ EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
2 SUBQUERY a system NULL NULL NULL NULL 1
-2 SUBQUERY t1 fulltext f1 f1 0 1 Using where
+2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
2 SUBQUERY a system NULL NULL NULL NULL 1
-2 SUBQUERY t1 fulltext f1 f1 0 1 Using where
+2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where
DEALLOCATE PREPARE stmt;
PREPARE stmt FROM
'EXPLAIN SELECT 1 FROM t1
@@ -293,12 +293,12 @@ EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
2 SUBQUERY a system NULL NULL NULL NULL 1
-2 SUBQUERY t1 fulltext f1 f1 0 1 Using where
+2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where
EXECUTE stmt;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
2 SUBQUERY a system NULL NULL NULL NULL 1
-2 SUBQUERY t1 fulltext f1 f1 0 1 Using where
+2 SUBQUERY t1 fulltext f1_2,f1 f1 0 1 Using where
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
End of 5.1 tests.
@@ -312,7 +312,8 @@ INSERT INTO t2 VALUES (8);
EXPLAIN EXTENDED
SELECT * FROM ( SELECT t1.a FROM t1,t2 WHERE t2.a = t1.a ) AS t;
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
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 0.00 const row not found
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL no matching row in const table
Warnings:
-Note 1003 select NULL AS `a` from `test`.`t1` join `test`.`t2` where 0
+Note 1003 select NULL AS `a` from (select NULL AS `a` from `test`.`t1` join `test`.`t2` where 0) `t`
DROP TABLE t1,t2;
diff --git a/mysql-test/r/feedback_plugin_install.result b/mysql-test/r/feedback_plugin_install.result
new file mode 100644
index 00000000000..4b3b0226fae
--- /dev/null
+++ b/mysql-test/r/feedback_plugin_install.result
@@ -0,0 +1,13 @@
+install plugin feedback soname 'feedback.so';
+select plugin_status from information_schema.plugins where plugin_name='feedback';
+plugin_status
+ACTIVE
+select * from information_schema.feedback where variable_name like 'feed%'
+ and variable_name not like '%_uid';
+VARIABLE_NAME VARIABLE_VALUE
+FEEDBACK 1.0
+FEEDBACK_SEND_RETRY_WAIT 60
+FEEDBACK_SEND_TIMEOUT 60
+FEEDBACK_URL http://mariadb.org/feedback_plugin/post
+FEEDBACK_USER_INFO mysql-test
+uninstall plugin feedback;
diff --git a/mysql-test/r/feedback_plugin_load.result b/mysql-test/r/feedback_plugin_load.result
new file mode 100644
index 00000000000..bc02b920a11
--- /dev/null
+++ b/mysql-test/r/feedback_plugin_load.result
@@ -0,0 +1,11 @@
+select plugin_status from information_schema.plugins where plugin_name='feedback';
+plugin_status
+ACTIVE
+select * from information_schema.feedback where variable_name like 'feed%'
+ and variable_name not like '%_uid';
+VARIABLE_NAME VARIABLE_VALUE
+FEEDBACK 1.0
+FEEDBACK_SEND_RETRY_WAIT 60
+FEEDBACK_SEND_TIMEOUT 60
+FEEDBACK_URL http://mariadb.org/feedback_plugin/post
+FEEDBACK_USER_INFO mysql-test
diff --git a/mysql-test/r/feedback_plugin_send.result b/mysql-test/r/feedback_plugin_send.result
new file mode 100644
index 00000000000..22379e26248
--- /dev/null
+++ b/mysql-test/r/feedback_plugin_send.result
@@ -0,0 +1,15 @@
+select plugin_status from information_schema.plugins where plugin_name='feedback';
+plugin_status
+ACTIVE
+select * from information_schema.feedback where variable_name like 'feed%'
+ and variable_name not like '%_uid';
+VARIABLE_NAME VARIABLE_VALUE
+FEEDBACK 1.0
+FEEDBACK_SEND_RETRY_WAIT 60
+FEEDBACK_SEND_TIMEOUT 60
+FEEDBACK_URL http://mariadb.org/feedback_plugin/post
+FEEDBACK_USER_INFO mysql-test
+feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent
+feedback plugin: server replied 'ok'
+feedback plugin: report to 'http://mariadb.org/feedback_plugin/post' was sent
+feedback plugin: server replied 'ok'
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index 9d9e738b696..33ec3d1f39c 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -497,6 +497,8 @@ DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(255), b INT, FULLTEXT(a), KEY(b));
INSERT INTO t1 VALUES('test', 1),('test', 1),('test', 1),('test', 1),
('test', 1),('test', 2),('test', 3),('test', 4);
+INSERT INTO t1 VALUES('test', 5),('test', 6),('test', 7),('test', 8),
+('test', 5),('test', 6),('test', 7),('test', 8);
EXPLAIN SELECT * FROM t1
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
id select_type table type possible_keys key key_len ref rows Extra
@@ -512,15 +514,15 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT * FROM t1 IGNORE INDEX(a)
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref b b 5 const 4 Using where
+1 SIMPLE t1 ref b b 5 const 5 Using where
EXPLAIN SELECT * FROM t1 USE INDEX(b)
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref b b 5 const 4 Using where
+1 SIMPLE t1 ref b b 5 const 5 Using where
EXPLAIN SELECT * FROM t1 FORCE INDEX(b)
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref b b 5 const 4 Using where
+1 SIMPLE t1 ref b b 5 const 5 Using where
DROP TABLE t1;
create table t1(a text,b date,fulltext index(a))engine=myisam;
insert into t1 set a='water',b='2008-08-04';
diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result
index 24e146159ea..a24784ace4b 100644
--- a/mysql-test/r/func_group.result
+++ b/mysql-test/r/func_group.result
@@ -1811,6 +1811,15 @@ MAX(f1)
2001
DROP TABLE t1;
#
+# LP BUG#813418 - incorrect optimisation of max/min by index for
+# negated BETWEEN
+CREATE TABLE t1 (a int, KEY (a));
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+SELECT MAX(a) FROM t1 WHERE a NOT BETWEEN 3 AND 9;
+MAX(a)
+10
+drop table t1;
+#
End of 5.1 tests
#
# BUG#46680 - Assertion failed in file item_subselect.cc,
@@ -1928,8 +1937,9 @@ HAVING ('m') IN (
SELECT v
FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY empty1 system NULL NULL NULL NULL 0 const row not found
+1 PRIMARY <derived2> system NULL NULL NULL NULL 0 const row not found
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
#
# 5) Test that subquery materialization is setup for query with
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index 77e6bac09da..779049f8b4c 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -241,7 +241,7 @@ insert into t2 select C.a*2+1, 'yes' from t1 C;
explain
select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range a a 5 NULL 12 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 range a a 5 NULL 12 Using where
select * from t2 where a NOT IN (0, 2,4,6,8,10,12,14,16,18);
a filler
1 yes
@@ -256,10 +256,10 @@ a filler
19 yes
explain select * from t2 force index(a) where a NOT IN (2,2,2,2,2,2);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range a a 5 NULL 912 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 range a a 5 NULL 912 Using where
explain select * from t2 force index(a) where a <> 2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range a a 5 NULL 912 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 range a a 5 NULL 912 Using where
drop table t2;
create table t2 (a datetime, filler char(200), key(a));
insert into t2 select '2006-04-25 10:00:00' + interval C.a minute,
@@ -271,7 +271,7 @@ select * from t2 where a NOT IN (
'2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00',
'2006-04-25 10:06:00', '2006-04-25 10:08:00');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range a a 9 NULL 18 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 range a a 9 NULL 18 Using where
select * from t2 where a NOT IN (
'2006-04-25 10:00:00','2006-04-25 10:02:00','2006-04-25 10:04:00',
'2006-04-25 10:06:00', '2006-04-25 10:08:00');
@@ -295,7 +295,7 @@ insert into t2 values ('fon', '1'), ('fop','1'), ('barbaq','1'),
('barbas','1'), ('bazbazbay', '1'),('zz','1');
explain select * from t2 where a not in('foo','barbar', 'bazbazbaz');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range a a 13 NULL 7 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 range a a 13 NULL 7 Using where
drop table t2;
create table t2 (a decimal(10,5), filler char(200), key(a));
insert into t2 select 345.67890, 'no' from t1 A, t1 B;
@@ -306,7 +306,7 @@ insert into t2 values (0, '1'), (22334.123,'1'), (33333,'1'),
explain
select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range a a 7 NULL 7 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 range a a 7 NULL 7 Using where
select * from t2 where a not in (345.67890, 43245.34, 64224.56344);
a filler
0.00000 1
@@ -544,9 +544,15 @@ id select_type table type possible_keys key key_len ref rows Extra
select f2 from t2 where f2 in ('a','b');
f2
0
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
+Warning 1292 Truncated incorrect DOUBLE value: 'b'
explain select f2 from t2 where f2 in ('a','b');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index t2f2 t2f2 5 NULL 3 Using where; Using index
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
+Warning 1292 Truncated incorrect DOUBLE value: 'b'
select f2 from t2 where f2 in (1,'b');
f2
0
@@ -624,16 +630,16 @@ INSERT INTO t1 (c_int) SELECT 0 FROM t1;
INSERT INTO t1 (c_int) SELECT 0 FROM t1;
EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_int c_int 4 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL, 1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_int c_int 4 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_int c_int 4 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_int IN (1, NULL, 2, NULL, 3, NULL);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_int c_int 4 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_int c_int 4 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_int IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -642,10 +648,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_decimal c_decimal 3 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_decimal c_decimal 3 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL, 1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_decimal c_decimal 3 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_decimal c_decimal 3 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_decimal IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -654,10 +660,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE c_float IN (1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_float c_float 4 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_float c_float 4 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL, 1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_float c_float 4 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_float c_float 4 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_float IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -666,10 +672,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE c_bit IN (1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_bit c_bit 2 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_bit c_bit 2 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL, 1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_bit c_bit 2 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_bit c_bit 2 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_bit IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -679,11 +685,11 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT * FROM t1 WHERE c_date
IN ('2009-09-01', '2009-09-02', '2009-09-03');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_date c_date 3 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_date c_date 3 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_date
IN (NULL, '2009-09-01', '2009-09-02', '2009-09-03');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_date c_date 3 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_date c_date 3 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_date IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -693,11 +699,11 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT * FROM t1 WHERE c_datetime
IN ('2009-09-01 00:00:01', '2009-09-02 00:00:01', '2009-09-03 00:00:01');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_datetime c_datetime 8 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_datetime c_datetime 8 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_datetime
IN (NULL, '2009-09-01 00:00:01', '2009-09-02 00:00:01', '2009-09-03 00:00:01');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_datetime c_datetime 8 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_datetime c_datetime 8 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_datetime IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -707,11 +713,11 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT * FROM t1 WHERE c_timestamp
IN ('2009-09-01 00:00:01', '2009-09-01 00:00:02', '2009-09-01 00:00:03');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_timestamp c_timestamp 4 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_timestamp c_timestamp 4 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_timestamp
IN (NULL, '2009-09-01 00:00:01', '2009-09-01 00:00:02', '2009-09-01 00:00:03');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_timestamp c_timestamp 4 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_timestamp c_timestamp 4 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_timestamp IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -720,10 +726,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE c_year IN (1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_year c_year 1 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_year c_year 1 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL, 1, 2, 3);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_year c_year 1 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_year c_year 1 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_year IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -732,10 +738,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
EXPLAIN SELECT * FROM t1 WHERE c_char IN ('1', '2', '3');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_char c_char 10 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_char c_char 10 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL, '1', '2', '3');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c_char c_char 10 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c_char c_char 10 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE c_char IN (NULL);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -771,3 +777,18 @@ SELECT 1 IN (YEAR(FROM_UNIXTIME(NULL)) ,1);
1
#
End of 5.1 tests
+create table t1 (a bigint, b int);
+insert t1 values (1,1),(2,2),(3,3);
+select * from t1 where a in ('2.1');
+a b
+2 2
+select * from t1 where b in ('2.1');
+a b
+select * from t1 where a='2.1';
+a b
+2 2
+select * from t1 where b='2.1';
+a b
+select * from t1 where IF(1,a,a)='2.1';
+a b
+drop table t1;
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 6c84ebaa18b..f23026096a5 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -2549,12 +2549,14 @@ create table t1(f1 tinyint default null)engine=myisam;
insert into t1 values (-1),(null);
explain select 1 as a from t1,(select decode(f1,f1) as b from t1) a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 2
explain select 1 as a from t1,(select encode(f1,f1) as b from t1) a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 2
-1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 2
drop table t1;
#
# Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index e511da4588e..cb177137476 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -27,6 +27,10 @@ sec_to_time('9001.1') sec_to_time('1234567890123.123')
02:30:01.100000 838:59:59.999999
Warnings:
Warning 1292 Truncated incorrect time value: '1234567890123.123'
+select sec_to_time(-9001.1), sec_to_time(-9001.1) / 1,
+sec_to_time(-9001.1) / 1e0, sec_to_time(-9001) div 1;
+sec_to_time(-9001.1) sec_to_time(-9001.1) / 1 sec_to_time(-9001.1) / 1e0 sec_to_time(-9001) div 1
+-02:30:01.1 -23001.10000 -23001.1 -23001
select sec_to_time(90011e-1), sec_to_time(1234567890123e30);
sec_to_time(90011e-1) sec_to_time(1234567890123e30)
02:30:01.100000 838:59:59.999999
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index 33376b22bc6..8bb3ad9c250 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -1898,8 +1898,8 @@ SELECT a, AVG(t1.b),
FROM t1 GROUP BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL a 10 NULL 9 Using index
-3 DEPENDENT SUBQUERY t12 ref a a 10 func,func 2 Using index condition
-2 DEPENDENT SUBQUERY t11 ref a a 10 func,func 2 Using index condition
+3 DEPENDENT SUBQUERY t12 ref a a 10 func,func 2 Using where
+2 DEPENDENT SUBQUERY t11 ref a a 10 func,func 2 Using where
SELECT a, AVG(t1.b),
(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c,
(SELECT t12.c FROM t1 t12 WHERE t12.a = t1.a AND t12.b = AVG(t1.b)) AS t12c
@@ -1909,3 +1909,18 @@ a AVG(t1.b) t11c t12c
2 2.0000 7 7
DROP TABLE t1;
# End of 5.1 tests
+#
+# BUG#872702: Crash in add_ref_to_table_cond() when grouping by a PK
+#
+CREATE TABLE t1 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (14),(15),(16),(17),(18),(19),(20);
+CREATE TABLE t2 (a int) ;
+SELECT a
+FROM t1
+WHERE a = (
+SELECT t2.a
+FROM t2
+) OR t1.a = 73
+GROUP BY 1;
+a
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index 0b3df689089..76bd6d70e4c 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -876,10 +876,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
explain select a1,a2,b, max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
+1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
+1 SIMPLE t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 17 Using where; Using index for group-by
@@ -924,7 +924,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
explain select a1,a2,b, max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
+1 SIMPLE t2 range NULL idx_t2_1 146 NULL # Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
@@ -2412,7 +2412,7 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer1 JOIN t1 AS t1_outer2
ON t1_outer1.a = (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2)
AND t1_outer1.b = t1_outer2.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_outer1 ref a a 5 const 1 Using index
+1 PRIMARY t1_outer1 ref a a 5 const 2 Using where; Using index
1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer (flat, BNL join)
2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
EXPLAIN SELECT (SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x
@@ -2749,7 +2749,7 @@ NULL
EXPLAIN
SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0);
id select_type table type possible_keys key key_len ref rows Extra
-x x x x x x x x x Impossible WHERE noticed after reading const tables
+x x x x x x x x x Using where; Using index
x x x x x x x x x Using where; Using index
SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0);
MIN( a )
@@ -2821,7 +2821,7 @@ NULL
EXPLAIN
SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0);
id select_type table type possible_keys key key_len ref rows Extra
-x x x x x x x x x Impossible WHERE noticed after reading const tables
+x x x x x x x x x Using where; Using index
x x x x x x x x x Using where; Using index
SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0);
MIN( a )
@@ -2900,7 +2900,7 @@ NULL
EXPLAIN
SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0);
id select_type table type possible_keys key key_len ref rows Extra
-x x x x x x x x x Impossible WHERE noticed after reading const tables
+x x x x x x x x x Using where; Using index
x x x x x x x x x Using where; Using index
SELECT MIN( a ) FROM t1 WHERE a = (SELECT a FROM t1 WHERE a < 0);
MIN( a )
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index fc2df2b7fc2..e631c7dbe5a 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -570,3 +570,27 @@ ORDER BY t1.f1;
f1
DROP TABLE t1,t2;
End of 5.1 tests
+#
+# LP bug #791761: MAX over an empty join + HAVING
+#
+CREATE TABLE t1 (a int, b int , KEY (b)) ;
+INSERT INTO t1 VALUES (3,1);
+CREATE TABLE t2 (a int NOT NULL ) ;
+INSERT INTO t2 VALUES (29);
+SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) <> 6;
+MAX(t1.b)
+1
+SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) IS NULL;
+MAX(t1.b)
+EXPLAIN
+SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6;
+MAX(t1.b)
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (NULL);
+SELECT MAX(t1.b) AS f FROM t1 JOIN t2 ON t2.a != 0
+WHERE (SELECT f3 FROM t3) <> 0 HAVING f <> 6 ;
+f
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/r/index_intersect.result b/mysql-test/r/index_intersect.result
index bc053c49748..e38828dcf89 100644
--- a/mysql-test/r/index_intersect.result
+++ b/mysql-test/r/index_intersect.result
@@ -74,12 +74,12 @@ EXPLAIN
SELECT * FROM City
WHERE Name LIKE 'M%' AND Population > 300000;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population,Name Name 35 NULL # Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range Population,Name Name 35 NULL # Using where
EXPLAIN
SELECT * FROM City
WHERE Name LIKE 'M%' AND Population > 7000000;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population,Name Population 4 NULL # Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range Population,Name Population 4 NULL # Using where
SELECT * FROM City USE INDEX ()
WHERE Name LIKE 'C%' AND Population > 1000000;
ID Name Country Population
@@ -334,8 +334,8 @@ ID Name Country Population
SELECT * FROM City
WHERE Name LIKE 'M%' AND Population > 7000000;
ID Name Country Population
-1024 Mumbai (Bombay) IND 10500000
3580 Moscow RUS 8389200
+1024 Mumbai (Bombay) IND 10500000
SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N';
COUNT(*)
301
@@ -371,7 +371,7 @@ EXPLAIN
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population,Name,Country Name # NULL # Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range Population,Name,Country Name # NULL # Using where
SELECT * FROM City USE INDEX ()
WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
ID Name Country Population
@@ -410,18 +410,18 @@ ID Name Country Population
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
ID Name Country Population
-1895 Harbin CHN 4289800
-1904 Jinan CHN 2278100
-1905 Hangzhou CHN 2190500
1914 Guiyang CHN 1465200
+1928 Handan CHN 840000
+1905 Hangzhou CHN 2190500
+1895 Harbin CHN 4289800
1916 Hefei CHN 1369100
-1923 Jilin CHN 1040000
+1950 Hegang CHN 520000
1927 Hohhot CHN 916700
-1928 Handan CHN 840000
1937 Huainan CHN 700000
-1938 Jixi CHN 683885
+1923 Jilin CHN 1040000
+1904 Jinan CHN 2278100
1944 Jinzhou CHN 570000
-1950 Hegang CHN 520000
+1938 Jixi CHN 683885
SELECT COUNT(*) FROM City WHERE ID BETWEEN 501 AND 1000;
COUNT(*)
500
@@ -462,7 +462,7 @@ EXPLAIN
SELECT * FROM City
WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using where
EXPLAIN
SELECT * FROM City
WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
@@ -472,7 +472,7 @@ EXPLAIN
SELECT * FROM City
WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY,Population,Country Country 3 NULL # Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range PRIMARY,Population,Country Country 3 NULL # Using where
EXPLAIN
SELECT * FROM City
WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000
@@ -484,7 +484,7 @@ SELECT * FROM City
WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
AND Country BETWEEN 'S' AND 'Z' ;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using where
SELECT * FROM City USE INDEX ()
WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
ID Name Country Population
@@ -733,7 +733,7 @@ EXPLAIN
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population,Country,Name Name 35 NULL # Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range Population,Country,Name Name 35 NULL # Using where
EXPLAIN
SELECT * FROM City
WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
@@ -744,7 +744,7 @@ SELECT * FROM City
WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
AND Country BETWEEN 'S' AND 'Z';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL # Using where
SELECT * FROM City WHERE
Name LIKE 'C%' AND Population > 1000000;
ID Name Country Population
@@ -785,14 +785,14 @@ ID Name Country Population
SELECT * FROM City
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
ID Name Country Population
-1895 Harbin CHN 4289800
-1905 Hangzhou CHN 2190500
1914 Guiyang CHN 1465200
+1928 Handan CHN 840000
+1905 Hangzhou CHN 2190500
+1895 Harbin CHN 4289800
1916 Hefei CHN 1369100
+1950 Hegang CHN 520000
1927 Hohhot CHN 916700
-1928 Handan CHN 840000
1937 Huainan CHN 700000
-1950 Hegang CHN 520000
SELECT * FROM City
WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
ID Name Country Population
@@ -1035,12 +1035,12 @@ EXPLAIN
SELECT * FROM t1
WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,f4 f4 35 NULL # Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY,f4 f4 35 NULL # Using where
SELECT * FROM t1
WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
f1 f4 f5
-994 r 2
996 A 2
998 a 0
+994 r 2
DROP TABLE t1;
SET SESSION optimizer_switch='index_merge_sort_intersection=on';
diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result
index d935cdbddbc..b484afca73b 100644
--- a/mysql-test/r/index_merge_innodb.result
+++ b/mysql-test/r/index_merge_innodb.result
@@ -691,7 +691,8 @@ SELECT COUNT(*) FROM
(SELECT * FROM t1 FORCE INDEX(primary,idx)
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 11419 Using sort_union(idx,PRIMARY); Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11419
+2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 11419 Using sort_union(idx,PRIMARY); Using where
SELECT COUNT(*) FROM
(SELECT * FROM t1 FORCE INDEX(primary,idx)
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
@@ -702,7 +703,8 @@ SELECT COUNT(*) FROM
(SELECT * FROM t1 IGNORE INDEX(idx)
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL PRIMARY NULL NULL NULL # Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL #
+2 DERIVED t1 ALL PRIMARY NULL NULL NULL # Using where
SELECT COUNT(*) FROM
(SELECT * FROM t1 IGNORE INDEX(idx)
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result
index 8682219054f..ea578accaaa 100644
--- a/mysql-test/r/index_merge_myisam.result
+++ b/mysql-test/r/index_merge_myisam.result
@@ -21,7 +21,7 @@ Table Op Msg_type Msg_text
test.t0 analyze status OK
explain select * from t0 where key1 < 3 or key1 > 1020;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 range i1 i1 4 NULL 78 Using index condition; Rowid-ordered scan
+1 SIMPLE t0 range i1 i1 4 NULL 78 Using where
explain
select * from t0 where key1 < 3 or key2 > 1020;
id select_type table type possible_keys key key_len ref rows Extra
@@ -74,7 +74,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 17 Using sort_union(i1,i2); Using where
explain select * from t0 where key2 = 45 or key1 <=> null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 range i1,i2 i2 4 NULL 1 Using where; Rowid-ordered scan
+1 SIMPLE t0 range i1,i2 i2 4 NULL 1 Using where
explain select * from t0 where key2 = 45 or key1 is not null;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ALL i1,i2 NULL NULL NULL 1024 Using where
@@ -277,7 +277,7 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select * from t0,t1 where t0.key1 < 3 and
(t1.key1 = t0.key1 or t1.key8 = t0.key1);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t0 range i1 i1 4 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t0 range i1 i1 4 NULL 3 Using where
1 SIMPLE t1 ALL i1,i8 NULL NULL NULL 1024 Range checked for each record (index map: 0x81)
explain select * from t1 where key1=3 or key2=4
union select * from t1 where key1<4 or key3=5;
@@ -287,7 +287,8 @@ id select_type table type possible_keys key key_len ref rows Extra
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL
explain select * from (select * from t1 where key1 = 3 or key2 =3) as Z where key8 >5;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge i1,i2,i8 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using where
+2 DERIVED t1 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where
create table t3 like t0;
insert into t3 select * from t0;
alter table t3 add key9 int not null, add index i9(key9);
@@ -1378,19 +1379,19 @@ primary key (pk1, pk2)
);
explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 7 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 7 Using where
select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
pk1 pk2 key1 key2 pktail1ok pktail2ok pktail3bad pktail4bad pktail5bad pk2copy badkey filler1 filler2
-1 19 0 0 0 0 0 0 0 19 0 filler-data-19 filler2
-1 18 0 0 0 0 0 0 0 18 0 filler-data-18 filler2
-1 17 0 0 0 0 0 0 0 17 0 filler-data-17 filler2
-1 16 0 0 0 0 0 0 0 16 0 filler-data-16 filler2
-1 15 0 0 0 0 0 0 0 15 0 filler-data-15 filler2
-1 14 0 0 0 0 0 0 0 14 0 filler-data-14 filler2
-1 13 0 0 0 0 0 0 0 13 0 filler-data-13 filler2
-1 12 0 0 0 0 0 0 0 12 0 filler-data-12 filler2
-1 11 0 0 0 0 0 0 0 11 0 filler-data-11 filler2
1 10 0 0 0 0 0 0 0 10 0 filler-data-10 filler2
+1 11 0 0 0 0 0 0 0 11 0 filler-data-11 filler2
+1 12 0 0 0 0 0 0 0 12 0 filler-data-12 filler2
+1 13 0 0 0 0 0 0 0 13 0 filler-data-13 filler2
+1 14 0 0 0 0 0 0 0 14 0 filler-data-14 filler2
+1 15 0 0 0 0 0 0 0 15 0 filler-data-15 filler2
+1 16 0 0 0 0 0 0 0 16 0 filler-data-16 filler2
+1 17 0 0 0 0 0 0 0 17 0 filler-data-17 filler2
+1 18 0 0 0 0 0 0 0 18 0 filler-data-18 filler2
+1 19 0 0 0 0 0 0 0 19 0 filler-data-19 filler2
explain select pk1,pk2 from t1 where key1 = 10 and key2=10 and 2*pk1+1 < 2*96+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge key1,key2 key1,key2 4,4 NULL 1 Using intersect(key1,key2); Using where
@@ -1593,4 +1594,24 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index_merge a,b,c a,c 5,5 NULL 54 Using sort_union(a,c); Using where
set optimizer_switch=default;
drop table t0, t1;
+#
+# BUG#834514 Assertion `!table || (!table->read_set || bitmap_is_set(...' with aggregates
+#
+CREATE TABLE t1 ( a int , b int, c int, KEY (b), PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (1,4,0),(5,0,0),(6,7,0),(7,7,0),(8,1,0),(9,7,0),(10,1,0);
+CREATE TABLE t2 ( b int, c int, KEY (c,b)) ;
+INSERT INTO t2 VALUES (7,0),(1,0),(7,0),(1,0);
+CREATE TABLE t3 ( a int ) ;
+SELECT COUNT(DISTINCT t2.b), CONCAT(t1.c)
+FROM t1, t2
+WHERE (t2.c = t1.c)
+AND (
+t1.b IN ( 4 )
+OR t1.a = 137
+AND EXISTS ( SELECT a FROM t3 )
+)
+GROUP BY 2;
+COUNT(DISTINCT t2.b) CONCAT(t1.c)
+2 0
+DROP TABLE t1,t2,t3;
set optimizer_switch= @optimizer_switch_save;
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 87675143853..1f56ee4d53b 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1288,7 +1288,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE tables ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases; Using filesort
explain select * from (select table_name from information_schema.tables) as a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE tables ALL NULL NULL NULL NULL NULL Skip_open_table; Scanned all databases
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED tables ALL NULL NULL NULL NULL NULL Skip_open_table; Scanned all databases
drop view v1;
create table t1 (f1 int(11));
create table t2 (f1 int(11), f2 int(11));
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 6134f671e2e..3b69791d373 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1,3 +1,8 @@
+set @innodb_test_tmp=@@optimizer_switch;
+set optimizer_switch =
+if(@innodb_test_dont_touch_optimizer_switch,
+@@optimizer_switch,
+'mrr=on,mrr_sort_keys=on,index_condition_pushdown=on');
drop table if exists t1,t2,t3,t4;
drop database if exists mysqltest;
create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) engine=innodb;
@@ -778,7 +783,7 @@ create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h
insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
explain select * from t1 where a > 0 and a < 50;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using where
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using index condition
drop table t1;
create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) engine=innodb;
insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
@@ -3303,3 +3308,4 @@ Variable_name Value
Handler_update 1
Variable_name Value
Handler_delete 1
+set optimizer_switch=@innodb_test_tmp;
diff --git a/mysql-test/r/innodb_bug878769.result b/mysql-test/r/innodb_bug878769.result
new file mode 100644
index 00000000000..db7ba3d2ee4
--- /dev/null
+++ b/mysql-test/r/innodb_bug878769.result
@@ -0,0 +1,57 @@
+drop table if exists t1,t2;
+#
+# Bug #878769: valgrind complains when using join cache
+# to join an InnoDB table without primary key
+#
+CREATE TABLE t1 (
+col_int_key int(11), col_time_key time, col_varchar_key varchar(1),
+KEY (col_int_key), KEY (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT IGNORE INTO t1 VALUES
+(7,'10:19:31','d'),(1,'14:40:36','r'),(7,'04:37:47','f'),(9,'19:34:06','y'),
+(2,'00:00:00','m'),(4,'00:13:25','q'),(0,'03:47:16',NULL),(4,'01:41:48','d'),
+(8,'00:00:00','g'),(NULL,'22:32:04','x'),(NULL,'16:44:14','f'),
+(0,'17:38:37','p'),(NULL,'08:46:48','j'),(8,'14:11:27','c');
+CREATE TABLE t2 (
+col_int_nokey int(11), col_int_key int(11),
+col_datetime_key datetime, col_datetime_nokey datetime,
+col_varchar_key varchar(1), col_varchar_nokey varchar(1),
+KEY (col_int_key), KEY (col_varchar_key,col_int_key)
+);
+INSERT IGNORE INTO t2 VALUES
+(150,62,'2008-01-03 10:33:32','2008-01-03 10:33:32','v','v'),
+(2,1,'2007-10-09 19:53:04','2007-10-09 19:53:04',NULL,NULL),
+(5,0,'2001-11-08 21:02:12','2001-11-08 21:02:12','x','x'),
+(3,7,'2003-04-01 00:00','2003-04-01 00:00','i','i'),
+(1,7,'1900-01-01 00:00','1900-01-01 00:00:00','e','e'),
+(NULL,7,'2005-04-04 01:21','2005-04-04 01:21','s','s'),
+(2,1,'1900-01-01 00:00','1900-01-01 00:00','j','j'),
+(8,0,'2004-04-28 21:44','2004-04-28 21:44','a','a'),
+(6,8,'2001-04-18 00:00','2001-04-18 00:00:00','y','y'),
+(8,1,'2008-12-18 19:39:55','2008-12-18 19:39:55',NULL,NULL),
+(3,1,'2000-08-01 12:19:39','2000-08-01 12:19:39','r','r'),
+(3,9,'2004-09-25 21:29:06','2004-09-25 21:29:06','v','v');
+set session optimizer_switch='mrr=on,mrr_sort_keys=on';
+set session join_cache_level=6;
+EXPLAIN
+SELECT t1.col_time_key, t1.col_varchar_key
+FROM t2 STRAIGHT_JOIN t1 ON t1.col_int_key = t2.col_int_key
+GROUP BY 1,2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index col_int_key col_int_key 5 NULL 12 Using where; Using index; Using temporary; Using filesort
+1 SIMPLE t1 ref col_int_key col_int_key 5 test.t2.col_int_key 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+SELECT t1.col_time_key, t1.col_varchar_key
+FROM t2 STRAIGHT_JOIN t1 ON t1.col_int_key = t2.col_int_key
+GROUP BY 1,2;
+col_time_key col_varchar_key
+00:00:00 g
+03:47:16 NULL
+04:37:47 f
+10:19:31 d
+14:11:27 c
+14:40:36 r
+17:38:37 p
+19:34:06 y
+set session optimizer_switch=default;
+set session join_cache_level=default;
+DROP TABLE t1,t2;
diff --git a/mysql-test/r/innodb_icp.result b/mysql-test/r/innodb_icp.result
index e4d81a9a3d5..739035b005c 100644
--- a/mysql-test/r/innodb_icp.result
+++ b/mysql-test/r/innodb_icp.result
@@ -1,5 +1,7 @@
set @save_storage_engine= @@storage_engine;
set storage_engine=InnoDB;
+set @innodb_icp_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
#
# Bug#36981 - "innodb crash when selecting for update"
#
@@ -81,6 +83,150 @@ c1 c2 c3 c4
DROP TABLE t1;
#
+# Bug#43617 - Innodb returns wrong results with timestamp's range value
+# in IN clause
+# (Note: Fixed by patch for BUG#42580)
+#
+CREATE TABLE t1(
+c1 TIMESTAMP NOT NULL,
+c2 TIMESTAMP NULL,
+c3 DATE,
+c4 DATETIME,
+PRIMARY KEY(c1),
+UNIQUE INDEX(c2)
+);
+INSERT INTO t1 VALUES
+('0000-00-00 00:00:00','0000-00-00 00:00:00','2008-01-04','2008-01-05 00:00:00'),
+('1971-01-01 00:00:01','1980-01-01 00:00:01','2009-01-01','2009-01-02 00:00:00'),
+('1999-01-01 00:00:00','1999-01-01 00:00:00', NULL, NULL),
+('2007-05-23 09:15:28','2007-05-23 09:15:28','2007-05-24','2007-05-24 09:15:28'),
+('2007-05-27 00:00:00','2007-05-25 00:00:00','2007-05-26','2007-05-26 00:00:00'),
+('2008-01-01 00:00:00', NULL, '2008-01-02','2008-01-03 00:00:00'),
+('2009-01-29 11:11:27','2009-01-29 11:11:27','2009-01-29','2009-01-29 11:11:27'),
+('2038-01-09 03:14:07','2038-01-09 03:14:07','2009-01-05','2009-01-06 00:00:00');
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 LIMIT 2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC LIMIT 2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+DROP TABLE t1;
+#
+# BUG#43618: MyISAM&Maria returns wrong results with 'between'
+# on timestamp
+#
+CREATE TABLE t1(
+ts TIMESTAMP NOT NULL,
+c char NULL,
+PRIMARY KEY(ts)
+);
+INSERT INTO t1 VALUES
+('1971-01-01','a'),
+('2007-05-25','b'),
+('2008-01-01','c'),
+('2038-01-09','d');
+
+# Execute select with invalid timestamp, desc ordering
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+ts c
+2008-01-01 00:00:00 c
+2007-05-25 00:00:00 b
+
+# Should use index condition
+EXPLAIN
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition
+
+DROP TABLE t1;
+#
+# BUG#49906: Assertion failed - Field_varstring::val_str in field.cc
+# (Note: Fixed by patch for LP BUG#625841)
+#
+CREATE TABLE t1 (
+f1 VARCHAR(1024),
+f2 VARCHAR(10),
+INDEX test_idx USING BTREE (f2,f1(5))
+);
+INSERT INTO t1 VALUES ('a','c'), ('b','d');
+SELECT f1
+FROM t1
+WHERE f2 LIKE 'd'
+ORDER BY f1;
+f1
+b
+DROP TABLE t1;
+#
+# Bug#52660 - "Perf. regr. using ICP for MyISAM on range queries on
+# an index containing TEXT"
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 SELECT A.a + 10*(B.a) FROM t1 A, t1 B;
+CREATE TABLE t3 (
+c1 TINYTEXT NOT NULL,
+i1 INT NOT NULL,
+KEY (c1(6),i1)
+);
+INSERT INTO t3 SELECT CONCAT('c-',1000+t2.a,'=w'), 1 FROM t2;
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range c1 c1 8 NULL 3 Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+c1
+c-1004=w
+c-1005=w
+c-1006=w
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range c1 c1 12 NULL 2 Using index condition; Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+c1
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 ALL c1 NULL NULL NULL 100 Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+c1
+c-1004=w
+c-1005=w
+c-1006=w
+DROP TABLE t1, t2, t3;
+#
# Bug#40992 - InnoDB: Crash when engine_condition_pushdown is on
#
CREATE TABLE t (
@@ -200,4 +346,360 @@ COUNT(*)
12
DROP PROCEDURE insert_data;
DROP TABLE t1, t2, t3;
+#
+# Bug#57372 "Multi-table updates and deletes fail when running with ICP
+# against InnoDB"
+#
+CREATE TABLE t1 (
+a INT KEY,
+b INT
+);
+CREATE TABLE t2 (
+a INT KEY,
+b INT
+);
+INSERT INTO t1 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105);
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+UPDATE t1, t2
+SET t1.a = t1.a + 100, t2.b = t1.a + 10
+WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b - 100;
+SELECT * FROM t1;
+a b
+1 101
+102 102
+103 103
+104 104
+5 105
+SELECT * FROM t2;
+a b
+1 1
+2 12
+3 13
+4 14
+5 5
+DROP TABLE t1, t2;
+#
+# Bug#52605 - "Adding LIMIT 1 clause to query with complex range
+# predicate causes wrong results"
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT,
+PRIMARY KEY (pk),
+KEY k1 (c1)
+);
+INSERT INTO t1 VALUES (1,NULL);
+INSERT INTO t1 VALUES (2,6);
+INSERT INTO t1 VALUES (3,NULL);
+INSERT INTO t1 VALUES (4,6);
+INSERT INTO t1 VALUES (5,NULL);
+INSERT INTO t1 VALUES (6,NULL);
+INSERT INTO t1 VALUES (7,9);
+INSERT INTO t1 VALUES (8,0);
+SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+pk c1
+4 6
+EXPLAIN SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,k1 k1 5 NULL 3 Using where; Using index
+DROP TABLE t1;
+#
+# Bug#59259 "Incorrect rows returned for a correlated subquery
+# when ICP is on"
+#
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using index
+2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index condition
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+pk i
+12 5
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1, t2;
+#
+# Bug #58816 "Extra temporary duplicate rows in result set when
+# switching ICP off"
+#
+set @save_optimizer_switch= @@optimizer_switch;
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1);
+EXPLAIN SELECT pk, c1 FROM t1 WHERE pk <> 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using index condition
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT pk, c1 FROM t1 WHERE pk <> 3;
+pk c1
+1 9
+2 7
+4 3
+5 1
+DROP TABLE t1;
+set optimizer_switch= @save_optimizer_switch;
+#
+# Bug#58837: ICP crash or valgrind error due to uninitialized
+# value in innobase_index_cond
+#
+CREATE TABLE t1 (
+t1_int INT,
+t1_time TIME
+);
+CREATE TABLE t2 (
+t2_int int PRIMARY KEY,
+t2_int2 INT
+);
+INSERT INTO t2 VALUES ();
+INSERT INTO t1 VALUES ();
+SELECT * FROM t1 AS t1a
+WHERE NOT EXISTS (SELECT * FROM t1 AS t1b
+WHERE t1b.t1_int NOT IN
+(SELECT t2.t2_int FROM t2
+WHERE t1b.t1_time LIKE t1b.t1_int
+OR t1b.t1_time <> t2.t2_int2
+AND 6=7));
+t1_int t1_time
+DROP TABLE t1,t2;
+#
+# Bug#59186: Wrong results of join when ICP is enabled
+# (fixed by the patch for LP bug #694092)
+#
+CREATE TABLE t1 (
+pk INTEGER NOT NULL,
+c1 VARCHAR(3) NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'y'),(0,'or');
+CREATE TABLE t2 (
+pk INTEGER NOT NULL,
+c1 VARCHAR(3) NOT NULL,
+c2 VARCHAR(6) NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (6,'y','RPOYT'),(10,'m','JINQE');
+EXPLAIN
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+(t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Using where
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Using join buffer (flat, BNL join)
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+(t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+c2
+DROP TABLE t1, t2;
+#
+# Bug#58838: "Wrong results with HAVING + LIMIT without GROUP BY when
+# ICP is enabled".
+# (Fixed by the patches for LP bugs #668644, #702322)
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT,
+PRIMARY KEY (pk),
+KEY col_int_key (c1)
+);
+INSERT INTO t1 VALUES (1,37),(2,8),(3,-25),(4,NULL),(5,55);
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 0;
+pk
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 1;
+pk
+3
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 2;
+pk
+3
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 5;
+pk
+3
+DROP TABLE t1;
+#
+# Bug#59483 "Crash on INSERT/REPLACE in
+# rec_convert_dtuple_to_rec_comp with ICP on"
+#
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT PRIMARY KEY,
+i1 INTEGER,
+c1 CHAR(6),
+i2 INTEGER NOT NULL,
+KEY (i2)
+);
+INSERT INTO t1 VALUES
+(NULL, 4, 'that', 8),
+(NULL, 1, 'she', 6),
+(NULL, 6, 'tell', 2);
+SELECT * FROM t1 WHERE i2 IN (3, 6) LIMIT 2 FOR UPDATE;
+pk i1 c1 i2
+2 1 she 6
+INSERT INTO t1 (i2) VALUES (1);
+DROP TABLE t1;
+#
+# Bug #11766678 - 59843:
+# USING UNINITIALISED VALUE IN USES_INDEX_FIELDS_ONLY
+#
+CREATE TABLE t1 (
+col999 FLOAT NOT NULL,
+COL1000 VARBINARY(179) NOT NULL,
+col1003 DATE DEFAULT NULL,
+KEY idx4267 (col1000, col1003)
+);
+INSERT INTO t1 VALUES (),();
+Warnings:
+Warning 1364 Field 'col999' doesn't have a default value
+Warning 1364 Field 'COL1000' doesn't have a default value
+SELECT col999 FROM t1 WHERE col1000 = "3" AND col1003 <=> sysdate();
+col999
+DROP TABLE t1;
+#
+# BUG#12822678 - ICP WITH STRAIGHT_JOIN
+#
+CREATE TABLE t1 (
+i1 INTEGER NOT NULL,
+d1 DOUBLE,
+KEY k1 (d1)
+);
+INSERT INTO t1 VALUES (10,1), (17,NULL), (22,NULL);
+CREATE TABLE t2 (
+pk INTEGER NOT NULL,
+i1 INTEGER NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (4,1);
+EXPLAIN
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL k1 9 NULL 3 Using index
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using where
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+d1 pk i1
+1 4 1
+DROP TABLE t1, t2;
+#
+# BUG#778434 Wrong result with in_to_exists=on in maria-5.3-mwl89
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0);
+CREATE TABLE t2 ( f10 int) ;
+INSERT IGNORE INTO t2 VALUES (0);
+CREATE TABLE t3 ( f1 int NOT NULL , f10 int, PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES (6,0),(10,0);
+CREATE TABLE t4 ( f11 int) ;
+INSERT IGNORE INTO t4 VALUES
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(NULL),
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+set @tmp_778434=@@optimizer_switch;
+SET optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off,semijoin=off';
+SELECT * FROM t1 INNER JOIN t2 ON t2.f10 = t1.f11
+WHERE (6, 234) IN (
+SELECT t3.f1, t3.f1
+FROM t3 JOIN t4 ON t4.f11 = t3.f10
+);
+f11 f10
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch= @tmp_778434;
+#
+# Bug#885168: ICP for one index + potential ORDER BY for another
+#
+CREATE TABLE t1 (a varchar(64), b varchar(10), INDEX(a), INDEX(b)) ;
+INSERT INTO t1 VALUES
+('Ohio','Iowa'), ('k','d'), ('bdkpj','mbdkpjdanp'), ('d','xdmbdkpjda'),
+('fkxdmbdkpjdanpje','o'), ('f','Pennsylvan'), ('Virginia','ei');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range b b 13 NULL 2 Using where; Rowid-ordered scan; Using filesort
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+a b
+d xdmbdkpjda
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range b b 13 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using filesort
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+a b
+d xdmbdkpjda
+DROP TABLE t1;
+#
+# Bug#886145: join with ICP + ORDER BY
+#
+CREATE TABLE t1 (b int NOT NULL, c int, a varchar(1024), PRIMARY KEY (b));
+INSERT INTO t1 VALUES (1,4,'Ill');
+CREATE TABLE t2 (a varchar(1024), KEY (a(512)));
+INSERT INTO t2 VALUES
+('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort
+1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+b c
+1 4
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Using filesort
+1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+b c
+1 4
+DROP TABLE t1,t2;
+#
+# Bug#879871: InnoDB: possible ICP + GROUP BY primary index
+#
+CREATE TABLE t1 (
+a int NOT NULL, b int, c varchar(1), d varchar(1),
+PRIMARY KEY (a), KEY c (c,b)
+);
+INSERT INTO t1 VALUES (10,8,'g','g');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+a
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+a
+DROP TABLE t1;
+set optimizer_switch=@innodb_icp_tmp;
set storage_engine= @save_storage_engine;
diff --git a/mysql-test/r/innodb_mrr.result b/mysql-test/r/innodb_mrr.result
index e4993016723..f56d55f7da2 100644
--- a/mysql-test/r/innodb_mrr.result
+++ b/mysql-test/r/innodb_mrr.result
@@ -1,6 +1,8 @@
drop table if exists t1,t2,t3,t4;
set @save_storage_engine= @@storage_engine;
set storage_engine=InnoDB;
+set @innodb_mrr_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
create table t1(a int);
show create table t1;
Table Create Table
@@ -184,7 +186,7 @@ explain
select * from t4 where a IS NULL and b IS NULL and (c IS NULL or c='no-such-row1'
or c='no-such-row2');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 range idx1 idx1 29 NULL 16 Using index condition; Rowid-ordered scan
+1 SIMPLE t4 range idx1 idx1 29 NULL 16 Using index condition; Using where; Rowid-ordered scan
select * from t4 where a IS NULL and b IS NULL and (c IS NULL or c='no-such-row1'
or c='no-such-row2');
a b c filler
@@ -206,7 +208,7 @@ NULL NULL NULL NULL-1
explain
select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 range idx1 idx1 29 NULL 32 Using index condition; Rowid-ordered scan
+1 SIMPLE t4 range idx1 idx1 29 NULL 32 Using index condition; Using where; Rowid-ordered scan
select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
a b c filler
b-1 NULL c-1 NULL-15
@@ -726,6 +728,7 @@ JA USA
DROP TABLE t1,t2;
#
# Testcase backport: Bug#43249
+# (Note: Fixed by patch for BUG#42580)
#
CREATE TABLE t1(c1 TIME NOT NULL, c2 TIME NULL, c3 DATE, PRIMARY KEY(c1), UNIQUE INDEX(c2)) engine=innodb;
INSERT INTO t1 VALUES('8:29:45',NULL,'2009-02-01');
@@ -764,4 +767,5 @@ t1 AS alias3 FORCE KEY (f2) ON alias3.f2 = alias2.f2 AND alias3.f4 = alias2.f3
count(*)
361
set join_cache_level=@_save_join_cache_level;
+set optimizer_switch= @innodb_mrr_tmp;
drop table t1;
diff --git a/mysql-test/r/innodb_mrr_cpk.result b/mysql-test/r/innodb_mrr_cpk.result
index 138bef49cea..81536f2a43b 100644
--- a/mysql-test/r/innodb_mrr_cpk.result
+++ b/mysql-test/r/innodb_mrr_cpk.result
@@ -1,4 +1,6 @@
drop table if exists t0,t1,t2,t3;
+set @innodb_mrr_cpk_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set @save_join_cache_level=@@join_cache_level;
set join_cache_level=6;
set @save_storage_engine=@@storage_engine;
@@ -145,4 +147,5 @@ set optimizer_switch='index_condition_pushdown=on';
drop table t1,t2;
set @@join_cache_level= @save_join_cache_level;
set storage_engine=@save_storage_engine;
+set optimizer_switch=@innodb_mrr_cpk_tmp;
drop table t0;
diff --git a/mysql-test/r/innodb_no_mrricp.result b/mysql-test/r/innodb_no_mrricp.result
new file mode 100644
index 00000000000..df0045ae6b1
--- /dev/null
+++ b/mysql-test/r/innodb_no_mrricp.result
@@ -0,0 +1,3316 @@
+set @innodb_with_mrricp=@@optimizer_switch;
+set optimizer_switch='mrr=off,mrr_sort_keys=off,index_condition_pushdown=off';
+set @innodb_test_dont_touch_optimizer_switch=1;
+set @innodb_test_tmp=@@optimizer_switch;
+set optimizer_switch =
+if(@innodb_test_dont_touch_optimizer_switch,
+@@optimizer_switch,
+'mrr=on,mrr_sort_keys=on,index_condition_pushdown=on');
+drop table if exists t1,t2,t3,t4;
+drop database if exists mysqltest;
+create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) engine=innodb;
+insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt');
+select id, code, name from t1 order by id;
+id code name
+1 1 Tim
+2 1 Monty
+3 2 David
+4 2 Erik
+5 3 Sasha
+6 3 Jeremy
+7 4 Matt
+update ignore t1 set id = 8, name = 'Sinisa' where id < 3;
+select id, code, name from t1 order by id;
+id code name
+2 1 Monty
+3 2 David
+4 2 Erik
+5 3 Sasha
+6 3 Jeremy
+7 4 Matt
+8 1 Sinisa
+update ignore t1 set id = id + 10, name = 'Ralph' where id < 4;
+select id, code, name from t1 order by id;
+id code name
+3 2 David
+4 2 Erik
+5 3 Sasha
+6 3 Jeremy
+7 4 Matt
+8 1 Sinisa
+12 1 Ralph
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+) engine=innodb;
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2);
+update t1 set parent_id=parent_id+100;
+select * from t1 where parent_id=102;
+id parent_id level
+8 102 2
+9 102 2
+15 102 2
+update t1 set id=id+1000;
+update t1 set id=1024 where id=1009;
+Got one of the listed errors
+select * from t1;
+id parent_id level
+1001 100 0
+1002 101 1
+1003 101 1
+1004 101 1
+1005 101 1
+1006 101 1
+1007 101 1
+1008 102 2
+1009 102 2
+1015 102 2
+1016 103 2
+1017 103 2
+1018 103 2
+1019 103 2
+1020 103 2
+1021 104 2
+1022 104 2
+1024 104 2
+1025 105 2
+1026 105 2
+1027 105 2
+1028 105 2
+1029 105 2
+1030 105 2
+1031 106 2
+1032 106 2
+1033 106 2
+1034 106 2
+1035 106 2
+1036 107 2
+1037 107 2
+1038 107 2
+1040 107 2
+1157 100 0
+1179 105 2
+1183 104 2
+1193 105 2
+1202 107 2
+1203 107 2
+update ignore t1 set id=id+1;
+select * from t1;
+id parent_id level
+1001 100 0
+1002 101 1
+1003 101 1
+1004 101 1
+1005 101 1
+1006 101 1
+1007 101 1
+1008 102 2
+1010 102 2
+1015 102 2
+1016 103 2
+1017 103 2
+1018 103 2
+1019 103 2
+1020 103 2
+1021 104 2
+1023 104 2
+1024 104 2
+1025 105 2
+1026 105 2
+1027 105 2
+1028 105 2
+1029 105 2
+1030 105 2
+1031 106 2
+1032 106 2
+1033 106 2
+1034 106 2
+1035 106 2
+1036 107 2
+1037 107 2
+1039 107 2
+1041 107 2
+1158 100 0
+1180 105 2
+1184 104 2
+1194 105 2
+1202 107 2
+1204 107 2
+update ignore t1 set id=1023 where id=1010;
+select * from t1 where parent_id=102;
+id parent_id level
+1008 102 2
+1010 102 2
+1015 102 2
+explain select level from t1 where level=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref level level 1 const # Using index
+explain select level,id from t1 where level=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref level level 1 const # Using index
+explain select level,id,parent_id from t1 where level=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref level level 1 const #
+select level,id from t1 where level=1;
+level id
+1 1002
+1 1003
+1 1004
+1 1005
+1 1006
+1 1007
+select level,id,parent_id from t1 where level=1;
+level id parent_id
+1 1002 101
+1 1003 101
+1 1004 101
+1 1005 101
+1 1006 101
+1 1007 101
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize status OK
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 id A # NULL NULL BTREE
+t1 1 parent_id 1 parent_id A # NULL NULL BTREE
+t1 1 level 1 level A # NULL NULL BTREE
+drop table t1;
+CREATE TABLE t1 (
+gesuchnr int(11) DEFAULT '0' NOT NULL,
+benutzer_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (gesuchnr,benutzer_id)
+) engine=innodb;
+replace into t1 (gesuchnr,benutzer_id) values (2,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+replace into t1 (gesuchnr,benutzer_id) values (1,1);
+select * from t1;
+gesuchnr benutzer_id
+1 1
+2 1
+drop table t1;
+create table t1 (a int) engine=innodb;
+insert into t1 values (1), (2);
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize status OK
+delete from t1 where a = 1;
+select * from t1;
+a
+2
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+create table t1 (a int,b varchar(20)) engine=innodb;
+insert into t1 values (1,""), (2,"testing");
+delete from t1 where a = 1;
+select * from t1;
+a b
+2 testing
+create index skr on t1 (a);
+insert into t1 values (3,""), (4,"testing");
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 skr 1 a A # NULL NULL YES BTREE
+drop table t1;
+create table t1 (a int,b varchar(20),key(a)) engine=innodb;
+insert into t1 values (1,""), (2,"testing");
+select * from t1 where a = 1;
+a b
+1
+drop table t1;
+create table t1 (n int not null primary key) engine=innodb;
+set autocommit=0;
+insert into t1 values (4);
+rollback;
+select n, "after rollback" from t1;
+n after rollback
+insert into t1 values (4);
+commit;
+select n, "after commit" from t1;
+n after commit
+4 after commit
+commit;
+insert into t1 values (5);
+insert into t1 values (4);
+ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
+commit;
+select n, "after commit" from t1;
+n after commit
+4 after commit
+5 after commit
+set autocommit=1;
+insert into t1 values (6);
+insert into t1 values (4);
+ERROR 23000: Duplicate entry '4' for key 'PRIMARY'
+select n from t1;
+n
+4
+5
+6
+set autocommit=0;
+begin;
+savepoint `my_savepoint`;
+insert into t1 values (7);
+savepoint `savept2`;
+insert into t1 values (3);
+select n from t1;
+n
+3
+4
+5
+6
+7
+savepoint savept3;
+rollback to savepoint savept2;
+rollback to savepoint savept3;
+ERROR 42000: SAVEPOINT savept3 does not exist
+rollback to savepoint savept2;
+release savepoint `my_savepoint`;
+select n from t1;
+n
+4
+5
+6
+7
+rollback to savepoint `my_savepoint`;
+ERROR 42000: SAVEPOINT my_savepoint does not exist
+rollback to savepoint savept2;
+ERROR 42000: SAVEPOINT savept2 does not exist
+insert into t1 values (8);
+savepoint sv;
+commit;
+savepoint sv;
+set autocommit=1;
+rollback;
+drop table t1;
+create table t1 (n int not null primary key) engine=innodb;
+start transaction;
+insert into t1 values (4);
+flush tables with read lock;
+commit;
+unlock tables;
+commit;
+select * from t1;
+n
+4
+drop table t1;
+create table t1 ( id int NOT NULL PRIMARY KEY, nom varchar(64)) engine=innodb;
+begin;
+insert into t1 values(1,'hamdouni');
+select id as afterbegin_id,nom as afterbegin_nom from t1;
+afterbegin_id afterbegin_nom
+1 hamdouni
+rollback;
+select id as afterrollback_id,nom as afterrollback_nom from t1;
+afterrollback_id afterrollback_nom
+set autocommit=0;
+insert into t1 values(2,'mysql');
+select id as afterautocommit0_id,nom as afterautocommit0_nom from t1;
+afterautocommit0_id afterautocommit0_nom
+2 mysql
+rollback;
+select id as afterrollback_id,nom as afterrollback_nom from t1;
+afterrollback_id afterrollback_nom
+set autocommit=1;
+drop table t1;
+CREATE TABLE t1 (id char(8) not null primary key, val int not null) engine=innodb;
+insert into t1 values ('pippo', 12);
+insert into t1 values ('pippo', 12);
+ERROR 23000: Duplicate entry 'pippo' for key 'PRIMARY'
+delete from t1;
+delete from t1 where id = 'pippo';
+select * from t1;
+id val
+insert into t1 values ('pippo', 12);
+set autocommit=0;
+delete from t1;
+rollback;
+select * from t1;
+id val
+pippo 12
+delete from t1;
+commit;
+select * from t1;
+id val
+drop table t1;
+create table t1 (a integer) engine=innodb;
+start transaction;
+rename table t1 to t2;
+create table t1 (b integer) engine=innodb;
+insert into t1 values (1);
+rollback;
+drop table t1;
+rename table t2 to t1;
+drop table t1;
+set autocommit=1;
+CREATE TABLE t1 (ID INTEGER NOT NULL PRIMARY KEY, NAME VARCHAR(64)) ENGINE=innodb;
+INSERT INTO t1 VALUES (1, 'Jochen');
+select * from t1;
+ID NAME
+1 Jochen
+drop table t1;
+CREATE TABLE t1 ( _userid VARCHAR(60) NOT NULL PRIMARY KEY) ENGINE=innodb;
+set autocommit=0;
+INSERT INTO t1 SET _userid='marc@anyware.co.uk';
+COMMIT;
+SELECT * FROM t1;
+_userid
+marc@anyware.co.uk
+SELECT _userid FROM t1 WHERE _userid='marc@anyware.co.uk';
+_userid
+marc@anyware.co.uk
+drop table t1;
+set autocommit=1;
+CREATE TABLE t1 (
+user_id int(10) DEFAULT '0' NOT NULL,
+name varchar(100),
+phone varchar(100),
+ref_email varchar(100) DEFAULT '' NOT NULL,
+detail varchar(200),
+PRIMARY KEY (user_id,ref_email)
+)engine=innodb;
+INSERT INTO t1 VALUES (10292,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10292,'shirish','2333604','shirish@yahoo.com','ddsds'),(10292,'sonali','323232','sonali@bolly.com','filmstar');
+select * from t1 where user_id=10292;
+user_id name phone ref_email detail
+10292 sanjeev 29153373 sansh777@hotmail.com xxx
+10292 shirish 2333604 shirish@yahoo.com ddsds
+10292 sonali 323232 sonali@bolly.com filmstar
+INSERT INTO t1 VALUES (10291,'sanjeev','29153373','sansh777@hotmail.com','xxx'),(10293,'shirish','2333604','shirish@yahoo.com','ddsds');
+select * from t1 where user_id=10292;
+user_id name phone ref_email detail
+10292 sanjeev 29153373 sansh777@hotmail.com xxx
+10292 shirish 2333604 shirish@yahoo.com ddsds
+10292 sonali 323232 sonali@bolly.com filmstar
+select * from t1 where user_id>=10292;
+user_id name phone ref_email detail
+10292 sanjeev 29153373 sansh777@hotmail.com xxx
+10292 shirish 2333604 shirish@yahoo.com ddsds
+10292 sonali 323232 sonali@bolly.com filmstar
+10293 shirish 2333604 shirish@yahoo.com ddsds
+select * from t1 where user_id>10292;
+user_id name phone ref_email detail
+10293 shirish 2333604 shirish@yahoo.com ddsds
+select * from t1 where user_id<10292;
+user_id name phone ref_email detail
+10291 sanjeev 29153373 sansh777@hotmail.com xxx
+drop table t1;
+CREATE TABLE t1 (a int not null, b int not null,c int not null,
+key(a),primary key(a,b), unique(c),key(a),unique(b));
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A # NULL NULL BTREE
+t1 0 PRIMARY 2 b A # NULL NULL BTREE
+t1 0 c 1 c A # NULL NULL BTREE
+t1 0 b 1 b A # NULL NULL BTREE
+t1 1 a 1 a A # NULL NULL BTREE
+t1 1 a_2 1 a A # NULL NULL BTREE
+drop table t1;
+create table t1 (col1 int not null, col2 char(4) not null, primary key(col1));
+alter table t1 engine=innodb;
+insert into t1 values ('1','1'),('5','2'),('2','3'),('3','4'),('4','4');
+select * from t1;
+col1 col2
+1 1
+2 3
+3 4
+4 4
+5 2
+update t1 set col2='7' where col1='4';
+select * from t1;
+col1 col2
+1 1
+2 3
+3 4
+4 7
+5 2
+alter table t1 add co3 int not null;
+select * from t1;
+col1 col2 co3
+1 1 0
+2 3 0
+3 4 0
+4 7 0
+5 2 0
+update t1 set col2='9' where col1='2';
+select * from t1;
+col1 col2 co3
+1 1 0
+2 9 0
+3 4 0
+4 7 0
+5 2 0
+drop table t1;
+create table t1 (a int not null , b int, primary key (a)) engine = innodb;
+create table t2 (a int not null , b int, primary key (a)) engine = myisam;
+insert into t1 VALUES (1,3) , (2,3), (3,3);
+select * from t1;
+a b
+1 3
+2 3
+3 3
+insert into t2 select * from t1;
+select * from t2;
+a b
+1 3
+2 3
+3 3
+delete from t1 where b = 3;
+select * from t1;
+a b
+insert into t1 select * from t2;
+select * from t1;
+a b
+1 3
+2 3
+3 3
+select * from t2;
+a b
+1 3
+2 3
+3 3
+drop table t1,t2;
+CREATE TABLE t1 (
+user_name varchar(12),
+password text,
+subscribed char(1),
+user_id int(11) DEFAULT '0' NOT NULL,
+quota bigint(20),
+weight double,
+access_date date,
+access_time time,
+approved datetime,
+dummy_primary_key int(11) NOT NULL auto_increment,
+PRIMARY KEY (dummy_primary_key)
+) ENGINE=innodb;
+INSERT INTO t1 VALUES ('user_0','somepassword','N',0,0,0,'2000-09-07','23:06:59','2000-09-07 23:06:59',1);
+INSERT INTO t1 VALUES ('user_1','somepassword','Y',1,1,1,'2000-09-07','23:06:59','2000-09-07 23:06:59',2);
+INSERT INTO t1 VALUES ('user_2','somepassword','N',2,2,1.4142135623731,'2000-09-07','23:06:59','2000-09-07 23:06:59',3);
+INSERT INTO t1 VALUES ('user_3','somepassword','Y',3,3,1.7320508075689,'2000-09-07','23:06:59','2000-09-07 23:06:59',4);
+INSERT INTO t1 VALUES ('user_4','somepassword','N',4,4,2,'2000-09-07','23:06:59','2000-09-07 23:06:59',5);
+select user_name, password , subscribed, user_id, quota, weight, access_date, access_time, approved, dummy_primary_key from t1 order by user_name;
+user_name password subscribed user_id quota weight access_date access_time approved dummy_primary_key
+user_0 somepassword N 0 0 0 2000-09-07 23:06:59 2000-09-07 23:06:59 1
+user_1 somepassword Y 1 1 1 2000-09-07 23:06:59 2000-09-07 23:06:59 2
+user_2 somepassword N 2 2 1.4142135623731 2000-09-07 23:06:59 2000-09-07 23:06:59 3
+user_3 somepassword Y 3 3 1.7320508075689 2000-09-07 23:06:59 2000-09-07 23:06:59 4
+user_4 somepassword N 4 4 2 2000-09-07 23:06:59 2000-09-07 23:06:59 5
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+) engine=innodb;
+INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1);
+INSERT INTO t1 values (179,5,2);
+update t1 set parent_id=parent_id+100;
+select * from t1 where parent_id=102;
+id parent_id level
+8 102 2
+9 102 2
+15 102 2
+update t1 set id=id+1000;
+update t1 set id=1024 where id=1009;
+select * from t1;
+id parent_id level
+1001 100 0
+1003 101 1
+1004 101 1
+1008 102 2
+1024 102 2
+1017 103 2
+1022 104 2
+1024 104 2
+1028 105 2
+1029 105 2
+1030 105 2
+1031 106 2
+1032 106 2
+1033 106 2
+1203 107 2
+1202 107 2
+1020 103 2
+1157 100 0
+1193 105 2
+1040 107 2
+1002 101 1
+1015 102 2
+1006 101 1
+1034 106 2
+1035 106 2
+1016 103 2
+1007 101 1
+1036 107 2
+1018 103 2
+1026 105 2
+1027 105 2
+1183 104 2
+1038 107 2
+1025 105 2
+1037 107 2
+1021 104 2
+1019 103 2
+1005 101 1
+1179 105 2
+update ignore t1 set id=id+1;
+select * from t1;
+id parent_id level
+1002 100 0
+1004 101 1
+1005 101 1
+1009 102 2
+1025 102 2
+1018 103 2
+1023 104 2
+1025 104 2
+1029 105 2
+1030 105 2
+1031 105 2
+1032 106 2
+1033 106 2
+1034 106 2
+1204 107 2
+1203 107 2
+1021 103 2
+1158 100 0
+1194 105 2
+1041 107 2
+1003 101 1
+1016 102 2
+1007 101 1
+1035 106 2
+1036 106 2
+1017 103 2
+1008 101 1
+1037 107 2
+1019 103 2
+1027 105 2
+1028 105 2
+1184 104 2
+1039 107 2
+1026 105 2
+1038 107 2
+1022 104 2
+1020 103 2
+1006 101 1
+1180 105 2
+update ignore t1 set id=1023 where id=1010;
+select * from t1 where parent_id=102;
+id parent_id level
+1009 102 2
+1025 102 2
+1016 102 2
+explain select level from t1 where level=1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref level level 1 const # Using index
+select level,id from t1 where level=1;
+level id
+1 1004
+1 1005
+1 1003
+1 1007
+1 1008
+1 1006
+select level,id,parent_id from t1 where level=1;
+level id parent_id
+1 1004 101
+1 1005 101
+1 1003 101
+1 1007 101
+1 1008 101
+1 1006 101
+select level,id from t1 where level=1 order by id;
+level id
+1 1003
+1 1004
+1 1005
+1 1006
+1 1007
+1 1008
+delete from t1 where level=1;
+select * from t1;
+id parent_id level
+1002 100 0
+1009 102 2
+1025 102 2
+1018 103 2
+1023 104 2
+1025 104 2
+1029 105 2
+1030 105 2
+1031 105 2
+1032 106 2
+1033 106 2
+1034 106 2
+1204 107 2
+1203 107 2
+1021 103 2
+1158 100 0
+1194 105 2
+1041 107 2
+1016 102 2
+1035 106 2
+1036 106 2
+1017 103 2
+1037 107 2
+1019 103 2
+1027 105 2
+1028 105 2
+1184 104 2
+1039 107 2
+1026 105 2
+1038 107 2
+1022 104 2
+1020 103 2
+1180 105 2
+drop table t1;
+CREATE TABLE t1 (
+sca_code char(6) NOT NULL,
+cat_code char(6) NOT NULL,
+sca_desc varchar(50),
+lan_code char(2) NOT NULL,
+sca_pic varchar(100),
+sca_sdesc varchar(50),
+sca_sch_desc varchar(16),
+PRIMARY KEY (sca_code, cat_code, lan_code),
+INDEX sca_pic (sca_pic)
+) engine = innodb ;
+INSERT INTO t1 ( sca_code, cat_code, sca_desc, lan_code, sca_pic, sca_sdesc, sca_sch_desc) VALUES ( 'PD', 'J', 'PENDANT', 'EN', NULL, NULL, 'PENDANT'),( 'RI', 'J', 'RING', 'EN', NULL, NULL, 'RING'),( 'QQ', 'N', 'RING', 'EN', 'not null', NULL, 'RING');
+select count(*) from t1 where sca_code = 'PD';
+count(*)
+1
+select count(*) from t1 where sca_code <= 'PD';
+count(*)
+1
+select count(*) from t1 where sca_pic is null;
+count(*)
+2
+alter table t1 drop index sca_pic;
+alter table t1 add index sca_pic (cat_code, sca_pic);
+select count(*) from t1 where sca_code='PD' and sca_pic is null;
+count(*)
+1
+select count(*) from t1 where cat_code='E';
+count(*)
+0
+alter table t1 drop index sca_pic;
+alter table t1 add index (sca_pic, cat_code);
+select count(*) from t1 where sca_code='PD' and sca_pic is null;
+count(*)
+1
+select count(*) from t1 where sca_pic >= 'n';
+count(*)
+1
+select sca_pic from t1 where sca_pic is null;
+sca_pic
+NULL
+NULL
+update t1 set sca_pic="test" where sca_pic is null;
+delete from t1 where sca_code='pd';
+drop table t1;
+set @a:=now();
+CREATE TABLE t1 (a int not null, b timestamp not null, primary key (a)) engine=innodb;
+insert into t1 (a) values(1),(2),(3);
+select t1.a from t1 natural join t1 as t2 where t1.b >= @a order by t1.a;
+a
+1
+2
+3
+select a from t1 natural join t1 as t2 where b >= @a order by a;
+a
+1
+2
+3
+update t1 set a=5 where a=1;
+select a from t1;
+a
+2
+3
+5
+drop table t1;
+create table t1 (a varchar(100) not null, primary key(a), b int not null) engine=innodb;
+insert into t1 values("hello",1),("world",2);
+select * from t1 order by b desc;
+a b
+world 2
+hello 1
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize status OK
+show keys from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 0 PRIMARY 1 a A # NULL NULL BTREE
+drop table t1;
+create table t1 (i int, j int ) ENGINE=innodb;
+insert into t1 values (1,2);
+select * from t1 where i=1 and j=2;
+i j
+1 2
+create index ax1 on t1 (i,j);
+select * from t1 where i=1 and j=2;
+i j
+1 2
+drop table t1;
+CREATE TABLE t1 (
+a int3 unsigned NOT NULL,
+b int1 unsigned NOT NULL,
+UNIQUE (a, b)
+) ENGINE = innodb;
+INSERT INTO t1 VALUES (1, 1);
+SELECT MIN(B),MAX(b) FROM t1 WHERE t1.a = 1;
+MIN(B) MAX(b)
+1 1
+drop table t1;
+CREATE TABLE t1 (a int unsigned NOT NULL) engine=innodb;
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1;
+a
+1
+DROP TABLE t1;
+create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h int, i int, j int, k int, l int, m int, n int, o int, p int, q int, r int, s int, t int, u int, v int, w int, x int, y int, z int, a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, b1 int, b2 int, b3 int, b4 int, b5 int, b6 int) engine = innodb;
+insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1);
+explain select * from t1 where a > 0 and a < 50;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using where
+drop table t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) engine=innodb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
+LOCK TABLES t1 WRITE;
+insert into t1 values (99,1,2,'D'),(1,1,2,'D');
+ERROR 23000: Duplicate entry '1-1' for key 'PRIMARY'
+select id from t1;
+id
+0
+1
+2
+select id from t1;
+id
+0
+1
+2
+UNLOCK TABLES;
+DROP TABLE t1;
+create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) engine=innodb;
+insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL');
+LOCK TABLES t1 WRITE;
+begin;
+insert into t1 values (99,1,2,'D'),(1,1,2,'D');
+ERROR 23000: Duplicate entry '1-1' for key 'PRIMARY'
+select id from t1;
+id
+0
+1
+2
+insert ignore into t1 values (100,1,2,'D'),(1,1,99,'D');
+commit;
+select id,id3 from t1;
+id id3
+0 0
+1 1
+2 2
+100 2
+UNLOCK TABLES;
+DROP TABLE t1;
+create table t1 (a char(20), unique (a(5))) engine=innodb;
+drop table t1;
+create table t1 (a char(20), index (a(5))) engine=innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` char(20) DEFAULT NULL,
+ KEY `a` (`a`(5))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+create temporary table t1 (a int not null auto_increment, primary key(a)) engine=innodb;
+insert into t1 values (NULL),(NULL),(NULL);
+delete from t1 where a=3;
+insert into t1 values (NULL);
+select * from t1;
+a
+1
+2
+4
+alter table t1 add b int;
+select * from t1;
+a b
+1 NULL
+2 NULL
+4 NULL
+drop table t1;
+create table t1
+(
+id int auto_increment primary key,
+name varchar(32) not null,
+value text not null,
+uid int not null,
+unique key(name,uid)
+) engine=innodb;
+insert into t1 values (1,'one','one value',101),
+(2,'two','two value',102),(3,'three','three value',103);
+set insert_id=5;
+replace into t1 (value,name,uid) values ('other value','two',102);
+delete from t1 where uid=102;
+set insert_id=5;
+replace into t1 (value,name,uid) values ('other value','two',102);
+set insert_id=6;
+replace into t1 (value,name,uid) values ('other value','two',102);
+select * from t1;
+id name value uid
+1 one one value 101
+3 three three value 103
+6 two other value 102
+drop table t1;
+create database mysqltest;
+create table mysqltest.t1 (a int not null) engine= innodb;
+insert into mysqltest.t1 values(1);
+create table mysqltest.t2 (a int not null) engine= myisam;
+insert into mysqltest.t2 values(1);
+create table mysqltest.t3 (a int not null) engine= heap;
+insert into mysqltest.t3 values(1);
+commit;
+drop database mysqltest;
+show tables from mysqltest;
+ERROR 42000: Unknown database 'mysqltest'
+set autocommit=0;
+create table t1 (a int not null) engine= innodb;
+insert into t1 values(1),(2);
+truncate table t1;
+commit;
+truncate table t1;
+truncate table t1;
+select * from t1;
+a
+insert into t1 values(1),(2);
+delete from t1;
+select * from t1;
+a
+commit;
+drop table t1;
+set autocommit=1;
+create table t1 (a int not null) engine= innodb;
+insert into t1 values(1),(2);
+truncate table t1;
+insert into t1 values(1),(2);
+select * from t1;
+a
+1
+2
+truncate table t1;
+insert into t1 values(1),(2);
+delete from t1;
+select * from t1;
+a
+drop table t1;
+create table t1 (a int not null, b int not null, c int not null, primary key (a),key(b)) engine=innodb;
+insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4);
+explain select * from t1 order by a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 4 NULL #
+explain select * from t1 order by b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL # Using filesort
+explain select * from t1 order by c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL # Using filesort
+explain select a from t1 order by a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 4 NULL # Using index
+explain select b from t1 order by b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL b 4 NULL # Using index
+explain select a,b from t1 order by b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL b 4 NULL # Using index
+explain select a,b from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL b 4 NULL # Using index
+explain select a,b,c from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL #
+drop table t1;
+create table t1 (t int not null default 1, key (t)) engine=innodb;
+desc t1;
+Field Type Null Key Default Extra
+t int(11) NO MUL 1
+drop table t1;
+CREATE TABLE t1 (
+number bigint(20) NOT NULL default '0',
+cname char(15) NOT NULL default '',
+carrier_id smallint(6) NOT NULL default '0',
+privacy tinyint(4) NOT NULL default '0',
+last_mod_date timestamp NOT NULL,
+last_mod_id smallint(6) NOT NULL default '0',
+last_app_date timestamp NOT NULL,
+last_app_id smallint(6) default '-1',
+version smallint(6) NOT NULL default '0',
+assigned_scps int(11) default '0',
+status tinyint(4) default '0'
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (4077711111,'SeanWheeler',90,2,20020111112846,500,00000000000000,-1,2,3,1);
+INSERT INTO t1 VALUES (9197722223,'berry',90,3,20020111112809,500,20020102114532,501,4,10,0);
+INSERT INTO t1 VALUES (650,'San Francisco',0,0,20011227111336,342,00000000000000,-1,1,24,1);
+INSERT INTO t1 VALUES (302467,'Sue\'s Subshop',90,3,20020109113241,500,20020102115111,501,7,24,0);
+INSERT INTO t1 VALUES (6014911113,'SudzCarwash',520,1,20020102115234,500,20020102115259,501,33,32768,0);
+INSERT INTO t1 VALUES (333,'tubs',99,2,20020109113440,501,20020109113440,500,3,10,0);
+CREATE TABLE t2 (
+number bigint(20) NOT NULL default '0',
+cname char(15) NOT NULL default '',
+carrier_id smallint(6) NOT NULL default '0',
+privacy tinyint(4) NOT NULL default '0',
+last_mod_date timestamp NOT NULL,
+last_mod_id smallint(6) NOT NULL default '0',
+last_app_date timestamp NOT NULL,
+last_app_id smallint(6) default '-1',
+version smallint(6) NOT NULL default '0',
+assigned_scps int(11) default '0',
+status tinyint(4) default '0'
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (4077711111,'SeanWheeler',0,2,20020111112853,500,00000000000000,-1,2,3,1);
+INSERT INTO t2 VALUES (9197722223,'berry',90,3,20020111112818,500,20020102114532,501,4,10,0);
+INSERT INTO t2 VALUES (650,'San Francisco',90,0,20020109113158,342,00000000000000,-1,1,24,1);
+INSERT INTO t2 VALUES (333,'tubs',99,2,20020109113453,501,20020109113453,500,3,10,0);
+select * from t1;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+4077711111 SeanWheeler 90 2 2002-01-11 11:28:46 500 0000-00-00 00:00:00 -1 2 3 1
+9197722223 berry 90 3 2002-01-11 11:28:09 500 2002-01-02 11:45:32 501 4 10 0
+650 San Francisco 0 0 2001-12-27 11:13:36 342 0000-00-00 00:00:00 -1 1 24 1
+302467 Sue's Subshop 90 3 2002-01-09 11:32:41 500 2002-01-02 11:51:11 501 7 24 0
+6014911113 SudzCarwash 520 1 2002-01-02 11:52:34 500 2002-01-02 11:52:59 501 33 32768 0
+333 tubs 99 2 2002-01-09 11:34:40 501 2002-01-09 11:34:40 500 3 10 0
+select * from t2;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+4077711111 SeanWheeler 0 2 2002-01-11 11:28:53 500 0000-00-00 00:00:00 -1 2 3 1
+9197722223 berry 90 3 2002-01-11 11:28:18 500 2002-01-02 11:45:32 501 4 10 0
+650 San Francisco 90 0 2002-01-09 11:31:58 342 0000-00-00 00:00:00 -1 1 24 1
+333 tubs 99 2 2002-01-09 11:34:53 501 2002-01-09 11:34:53 500 3 10 0
+delete t1, t2 from t1 left join t2 on t1.number=t2.number where (t1.carrier_id=90 and t1.number=t2.number) or (t2.carrier_id=90 and t1.number=t2.number) or (t1.carrier_id=90 and t2.number is null);
+select * from t1;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+6014911113 SudzCarwash 520 1 2002-01-02 11:52:34 500 2002-01-02 11:52:59 501 33 32768 0
+333 tubs 99 2 2002-01-09 11:34:40 501 2002-01-09 11:34:40 500 3 10 0
+select * from t2;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+333 tubs 99 2 2002-01-09 11:34:53 501 2002-01-09 11:34:53 500 3 10 0
+select * from t2;
+number cname carrier_id privacy last_mod_date last_mod_id last_app_date last_app_id version assigned_scps status
+333 tubs 99 2 2002-01-09 11:34:53 501 2002-01-09 11:34:53 500 3 10 0
+drop table t1,t2;
+create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) engine=innodb;
+BEGIN;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+SELECT @@tx_isolation,@@global.tx_isolation;
+@@tx_isolation @@global.tx_isolation
+SERIALIZABLE REPEATABLE-READ
+insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David');
+select id, code, name from t1 order by id;
+id code name
+1 1 Tim
+2 1 Monty
+3 2 David
+COMMIT;
+BEGIN;
+SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+insert into t1 (code, name) values (2, 'Erik'), (3, 'Sasha');
+select id, code, name from t1 order by id;
+id code name
+1 1 Tim
+2 1 Monty
+3 2 David
+4 2 Erik
+5 3 Sasha
+COMMIT;
+SET binlog_format='MIXED';
+BEGIN;
+SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
+insert into t1 (code, name) values (3, 'Jeremy'), (4, 'Matt');
+select id, code, name from t1 order by id;
+id code name
+1 1 Tim
+2 1 Monty
+3 2 David
+4 2 Erik
+5 3 Sasha
+6 3 Jeremy
+7 4 Matt
+COMMIT;
+DROP TABLE t1;
+create table t1 (n int(10), d int(10)) engine=innodb;
+create table t2 (n int(10), d int(10)) engine=innodb;
+insert into t1 values(1,1),(1,2);
+insert into t2 values(1,10),(2,20);
+UPDATE t1,t2 SET t1.d=t2.d,t2.d=30 WHERE t1.n=t2.n;
+select * from t1;
+n d
+1 10
+1 10
+select * from t2;
+n d
+1 30
+2 20
+drop table t1,t2;
+drop table if exists t1, t2;
+CREATE TABLE t1 (a int, PRIMARY KEY (a));
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
+create trigger trg_del_t2 after delete on t2 for each row
+insert into t1 values (1);
+insert into t1 values (1);
+insert into t2 values (1),(2);
+delete t2 from t2;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+select count(*) from t2 /* must be 2 as restored after rollback caused by the error */;
+count(*)
+2
+drop table t1, t2;
+drop table if exists t1, t2;
+CREATE TABLE t1 (a int, PRIMARY KEY (a));
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB;
+create trigger trg_del_t2 after delete on t2 for each row
+insert into t1 values (1);
+insert into t1 values (1);
+insert into t2 values (1),(2);
+delete t2 from t2;
+ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+select count(*) from t2 /* must be 2 as restored after rollback caused by the error */;
+count(*)
+2
+drop table t1, t2;
+create table t1 (a int, b int) engine=innodb;
+insert into t1 values(20,null);
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a;
+b ifnull(t2.b,"this is null")
+NULL this is null
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a order by 1;
+b ifnull(t2.b,"this is null")
+NULL this is null
+insert into t1 values(10,null);
+select t2.b, ifnull(t2.b,"this is null") from t1 as t2 left join t1 as t3 on
+t2.b=t3.a order by 1;
+b ifnull(t2.b,"this is null")
+NULL this is null
+NULL this is null
+drop table t1;
+create table t1 (a varchar(10) not null) engine=myisam;
+create table t2 (b varchar(10) not null unique) engine=innodb;
+select t1.a from t1,t2 where t1.a=t2.b;
+a
+drop table t1,t2;
+create table t1 (a int not null, b int, primary key (a)) engine = innodb;
+create table t2 (a int not null, b int, primary key (a)) engine = innodb;
+insert into t1 values (10, 20);
+insert into t2 values (10, 20);
+update t1, t2 set t1.b = 150, t2.b = t1.b where t2.a = t1.a and t1.a = 10;
+drop table t1,t2;
+CREATE TABLE t1 (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB;
+CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE CASCADE ) ENGINE=INNODB;
+insert into t1 set id=1;
+insert into t2 set id=1, t1_id=1;
+delete t1,t2 from t1,t2 where t1.id=t2.t1_id;
+select * from t1;
+id
+select * from t2;
+id t1_id
+drop table t2,t1;
+CREATE TABLE t1(id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB;
+CREATE TABLE t2(id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id) ) ENGINE=INNODB;
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(1, 1);
+SELECT * from t1;
+id
+1
+UPDATE t1,t2 SET t1.id=t1.id+1, t2.t1_id=t1.id+1;
+SELECT * from t1;
+id
+2
+UPDATE t1,t2 SET t1.id=t1.id+1 where t1.id!=t2.id;
+SELECT * from t1;
+id
+3
+DROP TABLE t1,t2;
+set autocommit=0;
+CREATE TABLE t1 (id CHAR(15) NOT NULL, value CHAR(40) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;
+CREATE TABLE t2 (id CHAR(15) NOT NULL, value CHAR(40) NOT NULL, PRIMARY KEY(id)) ENGINE=InnoDB;
+CREATE TABLE t3 (id1 CHAR(15) NOT NULL, id2 CHAR(15) NOT NULL, PRIMARY KEY(id1, id2)) ENGINE=InnoDB;
+INSERT INTO t3 VALUES("my-test-1", "my-test-2");
+COMMIT;
+INSERT INTO t1 VALUES("this-key", "will disappear");
+INSERT INTO t2 VALUES("this-key", "will also disappear");
+DELETE FROM t3 WHERE id1="my-test-1";
+SELECT * FROM t1;
+id value
+this-key will disappear
+SELECT * FROM t2;
+id value
+this-key will also disappear
+SELECT * FROM t3;
+id1 id2
+ROLLBACK;
+SELECT * FROM t1;
+id value
+SELECT * FROM t2;
+id value
+SELECT * FROM t3;
+id1 id2
+my-test-1 my-test-2
+SELECT * FROM t3 WHERE id1="my-test-1" LOCK IN SHARE MODE;
+id1 id2
+my-test-1 my-test-2
+COMMIT;
+set autocommit=1;
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int not null primary key, b int not null, unique (b)) engine=innodb;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+UPDATE t1 set a=a+100 where b between 2 and 3 and a < 1000;
+SELECT * from t1;
+a b
+1 1
+102 2
+103 3
+4 4
+5 5
+6 6
+7 7
+8 8
+9 9
+drop table t1;
+CREATE TABLE t1 (a int not null primary key, b int not null, key (b)) engine=innodb;
+CREATE TABLE t2 (a int not null primary key, b int not null, key (b)) engine=innodb;
+INSERT INTO t1 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(10,10),(11,11),(12,12);
+INSERT INTO t2 values (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
+update t1,t2 set t1.a=t1.a+100;
+select * from t1;
+a b
+101 1
+102 2
+103 3
+104 4
+105 5
+106 6
+107 7
+108 8
+109 9
+110 10
+111 11
+112 12
+update t1,t2 set t1.a=t1.a+100 where t1.a=101;
+select * from t1;
+a b
+201 1
+102 2
+103 3
+104 4
+105 5
+106 6
+107 7
+108 8
+109 9
+110 10
+111 11
+112 12
+update t1,t2 set t1.b=t1.b+10 where t1.b=2;
+select * from t1;
+a b
+201 1
+103 3
+104 4
+105 5
+106 6
+107 7
+108 8
+109 9
+110 10
+111 11
+102 12
+112 12
+update t1,t2 set t1.b=t1.b+2,t2.b=t1.b+10 where t1.b between 3 and 5 and t1.a=t2.a+100;
+select * from t1;
+a b
+201 1
+103 5
+104 6
+106 6
+105 7
+107 7
+108 8
+109 9
+110 10
+111 11
+102 12
+112 12
+select * from t2;
+a b
+1 1
+2 2
+6 6
+7 7
+8 8
+9 9
+3 13
+4 14
+5 15
+drop table t1,t2;
+CREATE TABLE t2 ( NEXT_T BIGINT NOT NULL PRIMARY KEY) ENGINE=MyISAM;
+CREATE TABLE t1 ( B_ID INTEGER NOT NULL PRIMARY KEY) ENGINE=InnoDB;
+SET AUTOCOMMIT=0;
+INSERT INTO t1 ( B_ID ) VALUES ( 1 );
+INSERT INTO t2 ( NEXT_T ) VALUES ( 1 );
+ROLLBACK;
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+SELECT * FROM t1;
+B_ID
+drop table t1,t2;
+create table t1 ( pk int primary key, parent int not null, child int not null, index (parent) ) engine = innodb;
+insert into t1 values (1,0,4), (2,1,3), (3,2,1), (4,1,2);
+select distinct parent,child from t1 order by parent;
+parent child
+0 4
+1 2
+1 3
+2 1
+drop table t1;
+create table t1 (a int not null auto_increment primary key, b int, c int, key(c)) engine=innodb;
+create table t2 (a int not null auto_increment primary key, b int);
+insert into t1 (b) values (null),(null),(null),(null),(null),(null),(null);
+insert into t2 (a) select b from t1;
+insert into t1 (b) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+insert into t2 (a) select b from t1;
+insert into t1 (a) select b from t2;
+select count(*) from t1;
+count(*)
+623
+explain select * from t1 where c between 1 and 2500;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range c c 5 NULL # Using where
+update t1 set c=a;
+explain select * from t1 where c between 1 and 2500;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL c NULL NULL NULL # Using where
+drop table t1,t2;
+create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) engine=innodb;
+insert into t1 (id) values (null),(null),(null),(null),(null);
+update t1 set fk=69 where fk is null order by id limit 1;
+SELECT * from t1;
+id fk
+2 NULL
+3 NULL
+4 NULL
+5 NULL
+1 69
+drop table t1;
+create table t1 (a int not null, b int not null, key (a));
+insert into t1 values (1,1),(1,2),(1,3),(3,1),(3,2),(3,3),(3,1),(3,2),(3,3),(2,1),(2,2),(2,3);
+SET @tmp=0;
+update t1 set b=(@tmp:=@tmp+1) order by a;
+update t1 set b=99 where a=1 order by b asc limit 1;
+update t1 set b=100 where a=1 order by b desc limit 2;
+update t1 set a=a+10+b where a=1 order by b;
+select * from t1 order by a,b;
+a b
+2 4
+2 5
+2 6
+3 7
+3 8
+3 9
+3 10
+3 11
+3 12
+13 2
+111 100
+111 100
+drop table t1;
+create table t1 ( c char(8) not null ) engine=innodb;
+insert into t1 values ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9');
+insert into t1 values ('A'),('B'),('C'),('D'),('E'),('F');
+alter table t1 add b char(8) not null;
+alter table t1 add a char(8) not null;
+alter table t1 add primary key (a,b,c);
+update t1 set a=c, b=c;
+create table t2 (c char(8) not null, b char(8) not null, a char(8) not null, primary key(a,b,c)) engine=innodb;
+insert into t2 select * from t1;
+delete t1,t2 from t2,t1 where t1.a<'B' and t2.b=t1.b;
+drop table t1,t2;
+SET AUTOCOMMIT=1;
+create table t1 (a integer auto_increment primary key) engine=innodb;
+insert into t1 (a) values (NULL),(NULL);
+truncate table t1;
+insert into t1 (a) values (NULL),(NULL);
+SELECT * from t1;
+a
+1
+2
+drop table t1;
+CREATE TABLE t1 (`id 1` INT NOT NULL, PRIMARY KEY (`id 1`)) ENGINE=INNODB;
+CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id), FOREIGN KEY (`t1_id`) REFERENCES `t1`(`id 1`) ON DELETE CASCADE ) ENGINE=INNODB;
+drop table t2,t1;
+create table `t1` (`id` int( 11 ) not null ,primary key ( `id` )) engine = innodb;
+insert into `t1`values ( 1 ) ;
+create table `t2` (`id` int( 11 ) not null default '0',unique key `id` ( `id` ) ,constraint `t1_id_fk` foreign key ( `id` ) references `t1` (`id` )) engine = innodb;
+insert into `t2`values ( 1 ) ;
+create table `t3` (`id` int( 11 ) not null default '0',key `id` ( `id` ) ,constraint `t2_id_fk` foreign key ( `id` ) references `t2` (`id` )) engine = innodb;
+insert into `t3`values ( 1 ) ;
+delete t3,t2,t1 from t1,t2,t3 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+update t1,t2,t3 set t3.id=5, t2.id=6, t1.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`))
+update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
+ERROR 42S22: Unknown column 't1.id' in 'where clause'
+drop table t3,t2,t1;
+create table t1(
+id int primary key,
+pid int,
+index(pid),
+foreign key(pid) references t1(id) on delete cascade) engine=innodb;
+insert into t1 values(0,0),(1,0),(2,1),(3,2),(4,3),(5,4),(6,5),(7,6),
+(8,7),(9,8),(10,9),(11,10),(12,11),(13,12),(14,13),(15,14);
+delete from t1 where id=0;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t1`, CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `t1` (`id`) ON DELETE CASCADE)
+delete from t1 where id=15;
+delete from t1 where id=0;
+drop table t1;
+CREATE TABLE t1 (col1 int(1))ENGINE=InnoDB;
+CREATE TABLE t2 (col1 int(1),stamp TIMESTAMP,INDEX stamp_idx
+(stamp))ENGINE=InnoDB;
+insert into t1 values (1),(2),(3);
+insert into t2 values (1, 20020204130000),(2, 20020204130000),(4,20020204310000 ),(5,20020204230000);
+Warnings:
+Warning 1265 Data truncated for column 'stamp' at row 3
+SELECT col1 FROM t1 UNION SELECT col1 FROM t2 WHERE stamp <
+'20020204120000' GROUP BY col1;
+col1
+1
+2
+3
+4
+drop table t1,t2;
+CREATE TABLE t1 (
+`id` int(10) unsigned NOT NULL auto_increment,
+`id_object` int(10) unsigned default '0',
+`id_version` int(10) unsigned NOT NULL default '1',
+`label` varchar(100) NOT NULL default '',
+`description` text,
+PRIMARY KEY (`id`),
+KEY `id_object` (`id_object`),
+KEY `id_version` (`id_version`)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES("6", "3382", "9", "Test", NULL), ("7", "102", "5", "Le Pekin (Test)", NULL),("584", "1794", "4", "Test de resto", NULL),("837", "1822", "6", "Test 3", NULL),("1119", "3524", "1", "Societe Test", NULL),("1122", "3525", "1", "Fournisseur Test", NULL);
+CREATE TABLE t2 (
+`id` int(10) unsigned NOT NULL auto_increment,
+`id_version` int(10) unsigned NOT NULL default '1',
+PRIMARY KEY (`id`),
+KEY `id_version` (`id_version`)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES("3524", "1"),("3525", "1"),("1794", "4"),("102", "5"),("1822", "6"),("3382", "9");
+SELECT t2.id, t1.`label` FROM t2 INNER JOIN
+(SELECT t1.id_object as id_object FROM t1 WHERE t1.`label` LIKE '%test%') AS lbl
+ON (t2.id = lbl.id_object) INNER JOIN t1 ON (t2.id = t1.id_object);
+id label
+3382 Test
+102 Le Pekin (Test)
+1794 Test de resto
+1822 Test 3
+3524 Societe Test
+3525 Fournisseur Test
+drop table t1,t2;
+create table t1 (a int, b varchar(200), c text not null) checksum=1 engine=myisam;
+create table t2 (a int, b varchar(200), c text not null) checksum=0 engine=innodb;
+create table t3 (a int, b varchar(200), c text not null) checksum=1 engine=innodb;
+insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, "");
+insert t2 select * from t1;
+insert t3 select * from t1;
+checksum table t1, t2, t3, t4 quick;
+Table Checksum
+test.t1 3442722830
+test.t2 NULL
+test.t3 NULL
+test.t4 NULL
+Warnings:
+Error 1146 Table 'test.t4' doesn't exist
+checksum table t1, t2, t3, t4;
+Table Checksum
+test.t1 3442722830
+test.t2 3442722830
+test.t3 3442722830
+test.t4 NULL
+Warnings:
+Error 1146 Table 'test.t4' doesn't exist
+checksum table t1, t2, t3, t4 extended;
+Table Checksum
+test.t1 3442722830
+test.t2 3442722830
+test.t3 3442722830
+test.t4 NULL
+Warnings:
+Error 1146 Table 'test.t4' doesn't exist
+drop table t1,t2,t3;
+create table t1 (id int, name char(10) not null, name2 char(10) not null) engine=innodb;
+insert into t1 values(1,'first','fff'),(2,'second','sss'),(3,'third','ttt');
+select trim(name2) from t1 union all select trim(name) from t1 union all select trim(id) from t1;
+trim(name2)
+fff
+sss
+ttt
+first
+second
+third
+1
+2
+3
+drop table t1;
+create table t1 (a int) engine=innodb;
+create table t2 like t1;
+drop table t1,t2;
+create table t1 (id int(11) not null, id2 int(11) not null, unique (id,id2)) engine=innodb;
+create table t2 (id int(11) not null, constraint t1_id_fk foreign key ( id ) references t1 (id)) engine = innodb;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL,
+ `id2` int(11) NOT NULL,
+ UNIQUE KEY `id` (`id`,`id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ KEY `t1_id_fk` (`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+create index id on t2 (id);
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ KEY `id` (`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+create index id2 on t2 (id);
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ KEY `id` (`id`),
+ KEY `id2` (`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop index id2 on t2;
+drop index id on t2;
+ERROR HY000: Cannot drop index 'id': needed in a foreign key constraint
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ KEY `id` (`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id,id2) references t1 (id,id2)) engine = innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `id2` int(11) NOT NULL,
+ KEY `t1_id_fk` (`id`,`id2`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`, `id2`) REFERENCES `t1` (`id`, `id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+create unique index id on t2 (id,id2);
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `id2` int(11) NOT NULL,
+ UNIQUE KEY `id` (`id`,`id2`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`, `id2`) REFERENCES `t1` (`id`, `id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2),constraint t1_id_fk foreign key (id2,id) references t1 (id,id2)) engine = innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `id2` int(11) NOT NULL,
+ UNIQUE KEY `id` (`id`,`id2`),
+ KEY `t1_id_fk` (`id2`,`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id2`, `id`) REFERENCES `t1` (`id`, `id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2), constraint t1_id_fk foreign key (id) references t1 (id)) engine = innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `id2` int(11) NOT NULL,
+ UNIQUE KEY `id` (`id`,`id2`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2),constraint t1_id_fk foreign key (id2,id) references t1 (id,id2)) engine = innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `id2` int(11) NOT NULL,
+ UNIQUE KEY `id` (`id`,`id2`),
+ KEY `t1_id_fk` (`id2`,`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id2`, `id`) REFERENCES `t1` (`id`, `id2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null auto_increment, id2 int(11) not null, constraint t1_id_fk foreign key (id) references t1 (id), primary key (id), index (id,id2)) engine = innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `id2` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `id` (`id`,`id2`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null auto_increment, id2 int(11) not null, constraint t1_id_fk foreign key (id) references t1 (id)) engine= innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `id2` int(11) NOT NULL,
+ KEY `t1_id_fk` (`id`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+alter table t2 add index id_test (id), add index id_test2 (id,id2);
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `id2` int(11) NOT NULL,
+ KEY `id_test` (`id`),
+ KEY `id_test2` (`id`,`id2`),
+ CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb;
+ERROR 42000: Incorrect foreign key definition for 't1_id_fk': Key reference and table reference don't match
+create table t2 (a int auto_increment primary key, b int, index(b), foreign key (b) references t1(id), unique(b)) engine=innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) NOT NULL AUTO_INCREMENT,
+ `b` int(11) DEFAULT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b_2` (`b`),
+ KEY `b` (`b`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2;
+create table t2 (a int auto_increment primary key, b int, foreign key (b) references t1(id), foreign key (b) references t1(id), unique(b)) engine=innodb;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) NOT NULL AUTO_INCREMENT,
+ `b` int(11) DEFAULT NULL,
+ PRIMARY KEY (`a`),
+ UNIQUE KEY `b` (`b`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`id`),
+ CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`b`) REFERENCES `t1` (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t2, t1;
+create table t1 (c char(10), index (c,c)) engine=innodb;
+ERROR 42S21: Duplicate column name 'c'
+create table t1 (c1 char(10), c2 char(10), index (c1,c2,c1)) engine=innodb;
+ERROR 42S21: Duplicate column name 'c1'
+create table t1 (c1 char(10), c2 char(10), index (c1,c1,c2)) engine=innodb;
+ERROR 42S21: Duplicate column name 'c1'
+create table t1 (c1 char(10), c2 char(10), index (c2,c1,c1)) engine=innodb;
+ERROR 42S21: Duplicate column name 'c1'
+create table t1 (c1 char(10), c2 char(10)) engine=innodb;
+alter table t1 add key (c1,c1);
+ERROR 42S21: Duplicate column name 'c1'
+alter table t1 add key (c2,c1,c1);
+ERROR 42S21: Duplicate column name 'c1'
+alter table t1 add key (c1,c2,c1);
+ERROR 42S21: Duplicate column name 'c1'
+alter table t1 add key (c1,c1,c2);
+ERROR 42S21: Duplicate column name 'c1'
+drop table t1;
+create table t1(a int(1) , b int(1)) engine=innodb;
+insert into t1 values ('1111', '3333');
+select distinct concat(a, b) from t1;
+concat(a, b)
+11113333
+drop table t1;
+CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB;
+SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE);
+ERROR HY000: The used table type doesn't support FULLTEXT indexes
+DROP TABLE t1;
+CREATE TABLE t1 (a_id tinyint(4) NOT NULL default '0', PRIMARY KEY (a_id)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(2),(3);
+CREATE TABLE t2 (b_id tinyint(4) NOT NULL default '0',b_a tinyint(4) NOT NULL default '0', PRIMARY KEY (b_id), KEY (b_a),
+CONSTRAINT fk_b_a FOREIGN KEY (b_a) REFERENCES t1 (a_id) ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (1,1),(2,1),(3,1),(4,2),(5,2);
+SELECT * FROM (SELECT t1.*,GROUP_CONCAT(t2.b_id SEPARATOR ',') as b_list FROM (t1 LEFT JOIN (t2) on t1.a_id = t2.b_a) GROUP BY t1.a_id ) AS xyz;
+a_id b_list
+1 1,2,3
+2 4,5
+3 NULL
+DROP TABLE t2;
+DROP TABLE t1;
+create temporary table t1 (a int) engine=innodb;
+insert into t1 values (4711);
+truncate t1;
+insert into t1 values (42);
+select * from t1;
+a
+42
+drop table t1;
+create table t1 (a int) engine=innodb;
+insert into t1 values (4711);
+truncate t1;
+insert into t1 values (42);
+select * from t1;
+a
+42
+drop table t1;
+create table t1 (a int not null, b int not null, c blob not null, d int not null, e int, primary key (a,b,c(255),d)) engine=innodb;
+insert into t1 values (2,2,"b",2,2),(1,1,"a",1,1),(3,3,"ab",3,3);
+select * from t1 order by a,b,c,d;
+a b c d e
+1 1 a 1 1
+2 2 b 2 2
+3 3 ab 3 3
+explain select * from t1 order by a,b,c,d;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using filesort
+drop table t1;
+create table t1 (a char(1), b char(1), key(a, b)) engine=innodb;
+insert into t1 values ('8', '6'), ('4', '7');
+select min(a) from t1;
+min(a)
+4
+select min(b) from t1 where a='8';
+min(b)
+6
+drop table t1;
+create table t1 (x bigint unsigned not null primary key) engine=innodb;
+insert into t1(x) values (0xfffffffffffffff0),(0xfffffffffffffff1);
+select * from t1;
+x
+18446744073709551600
+18446744073709551601
+select count(*) from t1 where x>0;
+count(*)
+2
+select count(*) from t1 where x=0;
+count(*)
+0
+select count(*) from t1 where x<0;
+count(*)
+0
+select count(*) from t1 where x < -16;
+count(*)
+0
+select count(*) from t1 where x = -16;
+count(*)
+0
+explain select count(*) from t1 where x > -16;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index PRIMARY PRIMARY 8 NULL 2 Using where; Using index
+select count(*) from t1 where x > -16;
+count(*)
+2
+select * from t1 where x > -16;
+x
+18446744073709551600
+18446744073709551601
+select count(*) from t1 where x = 18446744073709551601;
+count(*)
+1
+drop table t1;
+SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_buffer_pool_pages_total';
+variable_value
+8191
+SELECT variable_value FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_page_size';
+variable_value
+16384
+SELECT variable_value - @innodb_rows_deleted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_deleted';
+variable_value - @innodb_rows_deleted_orig
+71
+SELECT variable_value - @innodb_rows_inserted_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_inserted';
+variable_value - @innodb_rows_inserted_orig
+1084
+SELECT variable_value - @innodb_rows_updated_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_rows_updated';
+variable_value - @innodb_rows_updated_orig
+885
+SELECT variable_value - @innodb_row_lock_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_waits';
+variable_value - @innodb_row_lock_waits_orig
+0
+SELECT variable_value - @innodb_row_lock_current_waits_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_current_waits';
+variable_value - @innodb_row_lock_current_waits_orig
+0
+SELECT variable_value - @innodb_row_lock_time_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time';
+variable_value - @innodb_row_lock_time_orig
+0
+SELECT variable_value - @innodb_row_lock_time_max_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_max';
+variable_value - @innodb_row_lock_time_max_orig
+0
+SELECT variable_value - @innodb_row_lock_time_avg_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg';
+variable_value - @innodb_row_lock_time_avg_orig
+0
+SET @innodb_sync_spin_loops_orig = @@innodb_sync_spin_loops;
+show variables like "innodb_sync_spin_loops";
+Variable_name Value
+innodb_sync_spin_loops 30
+set global innodb_sync_spin_loops=1000;
+show variables like "innodb_sync_spin_loops";
+Variable_name Value
+innodb_sync_spin_loops 1000
+set global innodb_sync_spin_loops=0;
+show variables like "innodb_sync_spin_loops";
+Variable_name Value
+innodb_sync_spin_loops 0
+set global innodb_sync_spin_loops=20;
+show variables like "innodb_sync_spin_loops";
+Variable_name Value
+innodb_sync_spin_loops 20
+set global innodb_sync_spin_loops=@innodb_sync_spin_loops_orig;
+SET @old_innodb_thread_concurrency= @@global.innodb_thread_concurrency;
+show variables like "innodb_thread_concurrency";
+Variable_name Value
+innodb_thread_concurrency 0
+set global innodb_thread_concurrency=1001;
+Warnings:
+Warning 1292 Truncated incorrect thread_concurrency value: '1001'
+show variables like "innodb_thread_concurrency";
+Variable_name Value
+innodb_thread_concurrency 1000
+set global innodb_thread_concurrency=0;
+show variables like "innodb_thread_concurrency";
+Variable_name Value
+innodb_thread_concurrency 0
+set global innodb_thread_concurrency=16;
+show variables like "innodb_thread_concurrency";
+Variable_name Value
+innodb_thread_concurrency 16
+SET @@global.innodb_thread_concurrency= @old_innodb_thread_concurrency;
+show variables like "innodb_concurrency_tickets";
+Variable_name Value
+innodb_concurrency_tickets 500
+set global innodb_concurrency_tickets=1000;
+show variables like "innodb_concurrency_tickets";
+Variable_name Value
+innodb_concurrency_tickets 1000
+set global innodb_concurrency_tickets=0;
+Warnings:
+Warning 1292 Truncated incorrect concurrency_tickets value: '0'
+show variables like "innodb_concurrency_tickets";
+Variable_name Value
+innodb_concurrency_tickets 1
+set global innodb_concurrency_tickets=500;
+show variables like "innodb_concurrency_tickets";
+Variable_name Value
+innodb_concurrency_tickets 500
+show variables like "innodb_thread_sleep_delay";
+Variable_name Value
+innodb_thread_sleep_delay 10000
+set global innodb_thread_sleep_delay=100000;
+show variables like "innodb_thread_sleep_delay";
+Variable_name Value
+innodb_thread_sleep_delay 100000
+set global innodb_thread_sleep_delay=0;
+show variables like "innodb_thread_sleep_delay";
+Variable_name Value
+innodb_thread_sleep_delay 0
+set global innodb_thread_sleep_delay=10000;
+show variables like "innodb_thread_sleep_delay";
+Variable_name Value
+innodb_thread_sleep_delay 10000
+set storage_engine=INNODB;
+drop table if exists t1,t2,t3;
+--- Testing varchar ---
+--- Testing varchar ---
+create table t1 (v varchar(10), c char(10), t text);
+insert into t1 values('+ ', '+ ', '+ ');
+set @a=repeat(' ',20);
+insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
+Warnings:
+Note 1265 Data truncated for column 'v' at row 1
+select concat('*',v,'*',c,'*',t,'*') from t1;
+concat('*',v,'*',c,'*',t,'*')
+*+ *+*+ *
+*+ *+*+ *
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+create table t2 like t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+create table t3 select * from t1;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+alter table t1 modify c varchar(10);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` varchar(10) DEFAULT NULL,
+ `t` text
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+alter table t1 modify v char(10);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` char(10) DEFAULT NULL,
+ `c` varchar(10) DEFAULT NULL,
+ `t` text
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+alter table t1 modify t varchar(10);
+Warnings:
+Note 1265 Data truncated for column 't' at row 2
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` char(10) DEFAULT NULL,
+ `c` varchar(10) DEFAULT NULL,
+ `t` varchar(10) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+select concat('*',v,'*',c,'*',t,'*') from t1;
+concat('*',v,'*',c,'*',t,'*')
+*+*+*+ *
+*+*+*+ *
+drop table t1,t2,t3;
+create table t1 (v varchar(10), c char(10), t text, key(v), key(c), key(t(10)));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `v` (`v`),
+ KEY `c` (`c`),
+ KEY `t` (`t`(10))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+select count(*) from t1;
+count(*)
+270
+insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1)));
+select count(*) from t1 where v='a';
+count(*)
+10
+select count(*) from t1 where c='a';
+count(*)
+10
+select count(*) from t1 where t='a';
+count(*)
+10
+select count(*) from t1 where v='a ';
+count(*)
+10
+select count(*) from t1 where c='a ';
+count(*)
+10
+select count(*) from t1 where t='a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+count(*)
+10
+select count(*) from t1 where v like 'a%';
+count(*)
+11
+select count(*) from t1 where c like 'a%';
+count(*)
+11
+select count(*) from t1 where t like 'a%';
+count(*)
+11
+select count(*) from t1 where v like 'a %';
+count(*)
+9
+explain select count(*) from t1 where v='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
+explain select count(*) from t1 where c='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref c c 11 const # Using where; Using index
+explain select count(*) from t1 where t='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref t t 13 const # Using where
+explain select count(*) from t1 where v like 'a%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range v v 13 NULL # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
+alter table t1 add unique(v);
+ERROR 23000: Duplicate entry '{ ' for key 'v_2'
+alter table t1 add key(v);
+select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a';
+qq
+*a*a*a*
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+explain select * from t1 where v='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v,v_2 # 13 const # Using where
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(c) from t1 group by v limit 10;
+v count(c)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(c) from t1 group by v limit 10;
+v count(c)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select c,count(*) from t1 group by c limit 10;
+c count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select c,count(t) from t1 group by c limit 10;
+c count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result c,count(t) from t1 group by c limit 10;
+c count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select t,count(*) from t1 group by t limit 10;
+t count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select t,count(t) from t1 group by t limit 10;
+t count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result t,count(t) from t1 group by t limit 10;
+t count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+alter table t1 modify v varchar(300), drop key v, drop key v_2, add key v (v);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(300) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `c` (`c`),
+ KEY `t` (`t`(10)),
+ KEY `v` (`v`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+select count(*) from t1 where v='a';
+count(*)
+10
+select count(*) from t1 where v='a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+count(*)
+10
+select count(*) from t1 where v like 'a%';
+count(*)
+11
+select count(*) from t1 where v like 'a %';
+count(*)
+9
+explain select count(*) from t1 where v='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
+explain select count(*) from t1 where v like 'a%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range v v 303 NULL # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
+explain select * from t1 where v='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+alter table t1 drop key v, add key v (v(30));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(300) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `c` (`c`),
+ KEY `t` (`t`(10)),
+ KEY `v` (`v`(30))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+select count(*) from t1 where v='a';
+count(*)
+10
+select count(*) from t1 where v='a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+count(*)
+10
+select count(*) from t1 where v like 'a%';
+count(*)
+11
+select count(*) from t1 where v like 'a %';
+count(*)
+9
+explain select count(*) from t1 where v='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+explain select count(*) from t1 where v like 'a%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range v v 33 NULL # Using where
+explain select count(*) from t1 where v between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+explain select * from t1 where v='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+alter table t1 modify v varchar(600), drop key v, add key v (v);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(600) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `c` (`c`),
+ KEY `t` (`t`(10)),
+ KEY `v` (`v`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+drop table t1;
+create table t1 (a char(10), unique (a));
+insert into t1 values ('a ');
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a' for key 'a'
+alter table t1 modify a varchar(10);
+insert into t1 values ('a '),('a '),('a '),('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+update t1 set a='a ' where a like 'a%';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+update t1 set a='abc ' where a like 'a ';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+update t1 set a='a ' where a like 'a %';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+update t1 set a='a ' where a like 'a ';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+drop table t1;
+create table t1 (v varchar(10), c char(10), t text, key(v(5)), key(c(5)), key(t(5)));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `v` (`v`(5)),
+ KEY `c` (`c`(5)),
+ KEY `t` (`t`(5))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (v char(10) character set utf8);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` char(10) CHARACTER SET utf8 DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (v varchar(10), c char(10)) row_format=fixed;
+Warnings:
+Warning 1478 InnoDB: assuming ROW_FORMAT=COMPACT.
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED
+insert into t1 values('a','a'),('a ','a ');
+select concat('*',v,'*',c,'*') from t1;
+concat('*',v,'*',c,'*')
+*a*a*
+*a *a*
+drop table t1;
+create table t1 (v varchar(65530), key(v(10)));
+insert into t1 values(repeat('a',65530));
+select length(v) from t1 where v=repeat('a',65530);
+length(v)
+65530
+drop table t1;
+create table t1(a int, b varchar(12), key ba(b, a));
+insert into t1 values (1, 'A'), (20, NULL);
+explain select * from t1 where a=20 and b is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref ba ba 20 const,const 1 Using where; Using index
+select * from t1 where a=20 and b is null;
+a b
+20 NULL
+drop table t1;
+create table t1 (v varchar(65530), key(v));
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+drop table t1;
+create table t1 (v varchar(65536));
+Warnings:
+Note 1246 Converting column 'v' from VARCHAR to TEXT
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` mediumtext
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (v varchar(65530) character set utf8);
+Warnings:
+Note 1246 Converting column 'v' from VARCHAR to TEXT
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` mediumtext CHARACTER SET utf8
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1;
+set storage_engine=MyISAM;
+create table t1 (v varchar(16384)) engine=innodb;
+drop table t1;
+create table t1 (a char(1), b char(1), key(a, b)) engine=innodb;
+insert into t1 values ('8', '6'), ('4', '7');
+select min(a) from t1;
+min(a)
+4
+select min(b) from t1 where a='8';
+min(b)
+6
+drop table t1;
+CREATE TABLE t1 ( `a` int(11) NOT NULL auto_increment, `b` int(11) default NULL,PRIMARY KEY (`a`),UNIQUE KEY `b` (`b`)) ENGINE=innodb;
+insert into t1 (b) values (1);
+replace into t1 (b) values (2), (1), (3);
+select * from t1;
+a b
+3 1
+2 2
+4 3
+truncate table t1;
+insert into t1 (b) values (1);
+replace into t1 (b) values (2);
+replace into t1 (b) values (1);
+replace into t1 (b) values (3);
+select * from t1;
+a b
+3 1
+2 2
+4 3
+drop table t1;
+create table t1 (rowid int not null auto_increment, val int not null,primary
+key (rowid), unique(val)) engine=innodb;
+replace into t1 (val) values ('1'),('2');
+replace into t1 (val) values ('1'),('2');
+insert into t1 (val) values ('1'),('2');
+ERROR 23000: Duplicate entry '1' for key 'val'
+select * from t1;
+rowid val
+3 1
+4 2
+drop table t1;
+create table t1 (a int not null auto_increment primary key, val int) engine=InnoDB;
+insert into t1 (val) values (1);
+update t1 set a=2 where a=1;
+insert into t1 (val) values (1);
+ERROR 23000: Duplicate entry '2' for key 'PRIMARY'
+select * from t1;
+a val
+2 1
+drop table t1;
+CREATE TABLE t1 (GRADE DECIMAL(4) NOT NULL, PRIMARY KEY (GRADE)) ENGINE=INNODB;
+INSERT INTO t1 (GRADE) VALUES (151),(252),(343);
+SELECT GRADE FROM t1 WHERE GRADE > 160 AND GRADE < 300;
+GRADE
+252
+SELECT GRADE FROM t1 WHERE GRADE= 151;
+GRADE
+151
+DROP TABLE t1;
+create table t1 (f1 varchar(10), f2 varchar(10), primary key (f1,f2)) engine=innodb;
+create table t2 (f3 varchar(10), f4 varchar(10), key (f4)) engine=innodb;
+insert into t2 values ('aa','cc');
+insert into t1 values ('aa','bb'),('aa','cc');
+delete t1 from t1,t2 where f1=f3 and f4='cc';
+select * from t1;
+f1 f2
+drop table t1,t2;
+CREATE TABLE t1 (
+id INTEGER NOT NULL AUTO_INCREMENT, PRIMARY KEY (id)
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+id INTEGER NOT NULL,
+FOREIGN KEY (id) REFERENCES t1 (id)
+) ENGINE=InnoDB;
+INSERT INTO t1 (id) VALUES (NULL);
+SELECT * FROM t1;
+id
+1
+TRUNCATE t1;
+INSERT INTO t1 (id) VALUES (NULL);
+SELECT * FROM t1;
+id
+1
+DELETE FROM t1;
+TRUNCATE t1;
+INSERT INTO t1 (id) VALUES (NULL);
+SELECT * FROM t1;
+id
+1
+DROP TABLE t2, t1;
+CREATE TABLE t1
+(
+id INT PRIMARY KEY
+) ENGINE=InnoDB;
+CREATE TEMPORARY TABLE t2
+(
+id INT NOT NULL PRIMARY KEY,
+b INT,
+FOREIGN KEY (b) REFERENCES test.t1(id)
+) ENGINE=InnoDB;
+Got one of the listed errors
+DROP TABLE t1;
+create table t1 (col1 varchar(2000), index (col1(767)))
+character set = latin1 engine = innodb;
+create table t2 (col1 char(255), index (col1))
+character set = latin1 engine = innodb;
+create table t3 (col1 binary(255), index (col1))
+character set = latin1 engine = innodb;
+create table t4 (col1 varchar(767), index (col1))
+character set = latin1 engine = innodb;
+create table t5 (col1 varchar(767) primary key)
+character set = latin1 engine = innodb;
+create table t6 (col1 varbinary(767) primary key)
+character set = latin1 engine = innodb;
+create table t7 (col1 text, index(col1(767)))
+character set = latin1 engine = innodb;
+create table t8 (col1 blob, index(col1(767)))
+character set = latin1 engine = innodb;
+create table t9 (col1 varchar(512), col2 varchar(512), index(col1, col2))
+character set = latin1 engine = innodb;
+show create table t9;
+Table Create Table
+t9 CREATE TABLE `t9` (
+ `col1` varchar(512) DEFAULT NULL,
+ `col2` varchar(512) DEFAULT NULL,
+ KEY `col1` (`col1`,`col2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1, t2, t3, t4, t5, t6, t7, t8, t9;
+create table t1 (col1 varchar(768), index(col1))
+character set = latin1 engine = innodb;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+create table t2 (col1 varbinary(768), index(col1))
+character set = latin1 engine = innodb;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+create table t3 (col1 text, index(col1(768)))
+character set = latin1 engine = innodb;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+create table t4 (col1 blob, index(col1(768)))
+character set = latin1 engine = innodb;
+Warnings:
+Warning 1071 Specified key was too long; max key length is 767 bytes
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `col1` varchar(768) DEFAULT NULL,
+ KEY `col1` (`col1`(767))
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1, t2, t3, t4;
+create table t1 (col1 varchar(768) primary key)
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+create table t2 (col1 varbinary(768) primary key)
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+create table t3 (col1 text, primary key(col1(768)))
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+create table t4 (col1 blob, primary key(col1(768)))
+character set = latin1 engine = innodb;
+ERROR 42000: Specified key was too long; max key length is 767 bytes
+CREATE TABLE t1
+(
+id INT PRIMARY KEY
+) ENGINE=InnoDB;
+CREATE TABLE t2
+(
+v INT,
+CONSTRAINT c1 FOREIGN KEY (v) REFERENCES t1(id)
+) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+INSERT INTO t1 VALUES(1);
+INSERT INTO t2 VALUES(1);
+DELETE FROM t1 WHERE id = 1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+DROP TABLE t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails
+SET FOREIGN_KEY_CHECKS=0;
+DROP TABLE t1;
+SET FOREIGN_KEY_CHECKS=1;
+INSERT INTO t2 VALUES(3);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c1` FOREIGN KEY (`v`) REFERENCES `t1` (`id`))
+DROP TABLE t2;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
+set autocommit=0;
+checksum table t1;
+Table Checksum
+test.t1 1531596814
+insert into t1 values(3);
+checksum table t1;
+Table Checksum
+test.t1 1531596814
+commit;
+checksum table t1;
+Table Checksum
+test.t1 2050879373
+commit;
+drop table t1;
+create table t1(a int not null) engine=innodb DEFAULT CHARSET=latin1;
+insert into t1 values (1),(2);
+set autocommit=1;
+checksum table t1;
+Table Checksum
+test.t1 1531596814
+set autocommit=1;
+insert into t1 values(3);
+checksum table t1;
+Table Checksum
+test.t1 2050879373
+drop table t1;
+set foreign_key_checks=0;
+create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
+create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
+ERROR HY000: Can't create table 'test.t1' (errno: 150)
+set foreign_key_checks=1;
+drop table t2;
+set foreign_key_checks=0;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
+ERROR HY000: Can't create table 'test.t2' (errno: 150)
+set foreign_key_checks=1;
+drop table t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb;
+create table t1(a varchar(10) primary key) engine = innodb;
+alter table t1 modify column a int;
+Got one of the listed errors
+set foreign_key_checks=1;
+drop table t2,t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+alter table t1 convert to character set utf8;
+set foreign_key_checks=1;
+drop table t2,t1;
+set foreign_key_checks=0;
+create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
+create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
+rename table t3 to t1;
+ERROR HY000: Error on rename of './test/t3' to './test/t1' (errno: 150)
+set foreign_key_checks=1;
+drop table t2,t3;
+create table t1(a int primary key) row_format=redundant engine=innodb;
+create table t2(a int primary key,constraint foreign key(a)references t1(a)) row_format=compact engine=innodb;
+create table t3(a int primary key) row_format=compact engine=innodb;
+create table t4(a int primary key,constraint foreign key(a)references t3(a)) row_format=redundant engine=innodb;
+insert into t1 values(1);
+insert into t3 values(1);
+insert into t2 values(2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+insert into t4 values(2);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+insert into t2 values(1);
+insert into t4 values(1);
+update t1 set a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+update t2 set a=2;
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+update t3 set a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+update t4 set a=2;
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+truncate t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t1` (`a`))
+truncate t3;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t4`, CONSTRAINT `t4_ibfk_1` FOREIGN KEY (`a`) REFERENCES `t3` (`a`))
+truncate t2;
+truncate t4;
+truncate t1;
+truncate t3;
+drop table t4,t3,t2,t1;
+create table t1 (a varchar(255) character set utf8,
+b varchar(255) character set utf8,
+c varchar(255) character set utf8,
+d varchar(255) character set utf8,
+key (a,b,c,d)) engine=innodb;
+drop table t1;
+create table t1 (a varchar(255) character set utf8,
+b varchar(255) character set utf8,
+c varchar(255) character set utf8,
+d varchar(255) character set utf8,
+e varchar(255) character set utf8,
+key (a,b,c,d,e)) engine=innodb;
+ERROR 42000: Specified key was too long; max key length is 3072 bytes
+create table t1 (s1 varbinary(2),primary key (s1)) engine=innodb;
+create table t2 (s1 binary(2),primary key (s1)) engine=innodb;
+create table t3 (s1 varchar(2) binary,primary key (s1)) engine=innodb;
+create table t4 (s1 char(2) binary,primary key (s1)) engine=innodb;
+insert into t1 values (0x41),(0x4120),(0x4100);
+insert into t2 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A' for key 'PRIMARY'
+insert into t2 values (0x41),(0x4120);
+insert into t3 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A ' for key 'PRIMARY'
+insert into t3 values (0x41),(0x4100);
+insert into t4 values (0x41),(0x4120),(0x4100);
+ERROR 23000: Duplicate entry 'A' for key 'PRIMARY'
+insert into t4 values (0x41),(0x4100);
+select hex(s1) from t1;
+hex(s1)
+41
+4100
+4120
+select hex(s1) from t2;
+hex(s1)
+4100
+4120
+select hex(s1) from t3;
+hex(s1)
+4100
+41
+select hex(s1) from t4;
+hex(s1)
+4100
+41
+drop table t1,t2,t3,t4;
+create table t1 (a int primary key,s1 varbinary(3) not null unique) engine=innodb;
+create table t2 (s1 binary(2) not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+insert into t1 values(1,0x4100),(2,0x41),(3,0x4120),(4,0x42);
+insert into t2 values(0x42);
+ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+insert into t2 values(0x41);
+select hex(s1) from t2;
+hex(s1)
+4100
+update t1 set s1=0x123456 where a=2;
+select hex(s1) from t2;
+hex(s1)
+4100
+update t1 set s1=0x12 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x12345678 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x123457 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+update t1 set s1=0x1220 where a=1;
+select hex(s1) from t2;
+hex(s1)
+1220
+update t1 set s1=0x1200 where a=1;
+select hex(s1) from t2;
+hex(s1)
+1200
+update t1 set s1=0x4200 where a=1;
+select hex(s1) from t2;
+hex(s1)
+4200
+delete from t1 where a=1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+delete from t1 where a=2;
+update t2 set s1=0x4120;
+delete from t1;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+delete from t1 where a!=3;
+select a,hex(s1) from t1;
+a hex(s1)
+3 4120
+select hex(s1) from t2;
+hex(s1)
+4120
+drop table t2,t1;
+create table t1 (a int primary key,s1 varchar(2) binary not null unique) engine=innodb;
+create table t2 (s1 char(2) binary not null, constraint c foreign key(s1) references t1(s1) on update cascade) engine=innodb;
+insert into t1 values(1,0x4100),(2,0x41);
+insert into t2 values(0x41);
+select hex(s1) from t2;
+hex(s1)
+41
+update t1 set s1=0x1234 where a=1;
+select hex(s1) from t2;
+hex(s1)
+41
+update t1 set s1=0x12 where a=2;
+select hex(s1) from t2;
+hex(s1)
+12
+delete from t1 where a=1;
+delete from t1 where a=2;
+ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `c` FOREIGN KEY (`s1`) REFERENCES `t1` (`s1`) ON UPDATE CASCADE)
+select a,hex(s1) from t1;
+a hex(s1)
+2 12
+select hex(s1) from t2;
+hex(s1)
+12
+drop table t2,t1;
+CREATE TABLE t1(a INT, PRIMARY KEY(a)) ENGINE=InnoDB;
+CREATE TABLE t2(a INT) ENGINE=InnoDB;
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_1;
+ALTER TABLE t2 ADD CONSTRAINT t2_ibfk_0 FOREIGN KEY (a) REFERENCES t1(a);
+ALTER TABLE t2 DROP FOREIGN KEY t2_ibfk_0;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ KEY `t2_ibfk_0` (`a`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t2,t1;
+create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+insert into t1(a) values (1),(2),(3);
+commit;
+set autocommit = 0;
+update t1 set b = 5 where a = 2;
+create trigger t1t before insert on t1 for each row begin set NEW.b = NEW.a * 10 + 5, NEW.c = NEW.a / 10; end |
+set autocommit = 0;
+insert into t1(a) values (10),(20),(30),(40),(50),(60),(70),(80),(90),(100),
+(11),(21),(31),(41),(51),(61),(71),(81),(91),(101),
+(12),(22),(32),(42),(52),(62),(72),(82),(92),(102),
+(13),(23),(33),(43),(53),(63),(73),(83),(93),(103),
+(14),(24),(34),(44),(54),(64),(74),(84),(94),(104);
+commit;
+commit;
+drop trigger t1t;
+drop table t1;
+create table t1(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t2(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t3(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t4(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+create table t5(a int not null, b int, c int, d int, primary key(a)) engine=innodb;
+insert into t1(a) values (1),(2),(3);
+insert into t2(a) values (1),(2),(3);
+insert into t3(a) values (1),(2),(3);
+insert into t4(a) values (1),(2),(3);
+insert into t3(a) values (5),(7),(8);
+insert into t4(a) values (5),(7),(8);
+insert into t5(a) values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
+create trigger t1t before insert on t1 for each row begin
+INSERT INTO t2 SET a = NEW.a;
+end |
+create trigger t2t before insert on t2 for each row begin
+DELETE FROM t3 WHERE a = NEW.a;
+end |
+create trigger t3t before delete on t3 for each row begin
+UPDATE t4 SET b = b + 1 WHERE a = OLD.a;
+end |
+create trigger t4t before update on t4 for each row begin
+UPDATE t5 SET b = b + 1 where a = NEW.a;
+end |
+commit;
+set autocommit = 0;
+update t1 set b = b + 5 where a = 1;
+update t2 set b = b + 5 where a = 1;
+update t3 set b = b + 5 where a = 1;
+update t4 set b = b + 5 where a = 1;
+insert into t5(a) values(20);
+set autocommit = 0;
+insert into t1(a) values(7);
+insert into t2(a) values(8);
+delete from t2 where a = 3;
+update t4 set b = b + 1 where a = 3;
+commit;
+drop trigger t1t;
+drop trigger t2t;
+drop trigger t3t;
+drop trigger t4t;
+drop table t1, t2, t3, t4, t5;
+CREATE TABLE t1 (
+field1 varchar(8) NOT NULL DEFAULT '',
+field2 varchar(8) NOT NULL DEFAULT '',
+PRIMARY KEY (field1, field2)
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+field1 varchar(8) NOT NULL DEFAULT '' PRIMARY KEY,
+FOREIGN KEY (field1) REFERENCES t1 (field1)
+ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('old', 'somevalu');
+INSERT INTO t1 VALUES ('other', 'anyvalue');
+INSERT INTO t2 VALUES ('old');
+INSERT INTO t2 VALUES ('other');
+UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu';
+ERROR 23000: Upholding foreign key constraints for table 't1', entry 'other-somevalu', key 1 would lead to a duplicate entry
+DROP TABLE t2;
+DROP TABLE t1;
+create table t1 (
+c1 bigint not null,
+c2 bigint not null,
+primary key (c1),
+unique key (c2)
+) engine=innodb;
+create table t2 (
+c1 bigint not null,
+primary key (c1)
+) engine=innodb;
+alter table t1 add constraint c2_fk foreign key (c2)
+references t2(c1) on delete cascade;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` bigint(20) NOT NULL,
+ `c2` bigint(20) NOT NULL,
+ PRIMARY KEY (`c1`),
+ UNIQUE KEY `c2` (`c2`),
+ CONSTRAINT `c2_fk` FOREIGN KEY (`c2`) REFERENCES `t2` (`c1`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+alter table t1 drop foreign key c2_fk;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` bigint(20) NOT NULL,
+ `c2` bigint(20) NOT NULL,
+ PRIMARY KEY (`c1`),
+ UNIQUE KEY `c2` (`c2`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+drop table t1, t2;
+create table t1(a date) engine=innodb;
+create table t2(a date, key(a)) engine=innodb;
+insert into t1 values('2005-10-01');
+insert into t2 values('2005-10-01');
+select * from t1, t2
+where t2.a between t1.a - interval 2 day and t1.a + interval 2 day;
+a a
+2005-10-01 2005-10-01
+drop table t1, t2;
+create table t1 (id int not null, f_id int not null, f int not null,
+primary key(f_id, id)) engine=innodb;
+create table t2 (id int not null,s_id int not null,s varchar(200),
+primary key(id)) engine=innodb;
+INSERT INTO t1 VALUES (8, 1, 3);
+INSERT INTO t1 VALUES (1, 2, 1);
+INSERT INTO t2 VALUES (1, 0, '');
+INSERT INTO t2 VALUES (8, 1, '');
+commit;
+DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
+WHERE mm.id IS NULL;
+select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
+where mm.id is null lock in share mode;
+id f_id f
+drop table t1,t2;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3);
+commit;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+update t1 set b = 5 where b = 1;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+select * from t1 where a = 7 and b = 3 for update;
+a b
+7 3
+commit;
+commit;
+drop table t1;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2);
+commit;
+set autocommit = 0;
+select * from t1 lock in share mode;
+a b
+1 1
+2 2
+3 1
+4 2
+5 1
+6 2
+update t1 set b = 5 where b = 1;
+set autocommit = 0;
+select * from t1 where a = 2 and b = 2 for update;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+commit;
+drop table t1;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values (1,2),(5,3),(4,2);
+create table t2(d int not null, e int, primary key(d)) engine=innodb;
+insert into t2 values (8,6),(12,1),(3,1);
+commit;
+set autocommit = 0;
+select * from t2 for update;
+d e
+3 1
+8 6
+12 1
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+insert into t1 select * from t2;
+update t1 set b = (select e from t2 where a = d);
+create table t3(d int not null, e int, primary key(d)) engine=innodb
+select * from t2;
+commit;
+commit;
+drop table t1, t2, t3;
+create table t1(a int not null, b int, primary key(a)) engine=innodb;
+insert into t1 values (1,2),(5,3),(4,2);
+create table t2(a int not null, b int, primary key(a)) engine=innodb;
+insert into t2 values (8,6),(12,1),(3,1);
+create table t3(d int not null, b int, primary key(d)) engine=innodb;
+insert into t3 values (8,6),(12,1),(3,1);
+create table t5(a int not null, b int, primary key(a)) engine=innodb;
+insert into t5 values (1,2),(5,3),(4,2);
+create table t6(d int not null, e int, primary key(d)) engine=innodb;
+insert into t6 values (8,6),(12,1),(3,1);
+create table t8(a int not null, b int, primary key(a)) engine=innodb;
+insert into t8 values (1,2),(5,3),(4,2);
+create table t9(d int not null, e int, primary key(d)) engine=innodb;
+insert into t9 values (8,6),(12,1),(3,1);
+commit;
+set autocommit = 0;
+select * from t2 for update;
+a b
+3 1
+8 6
+12 1
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+insert into t1 select * from t2;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+update t3 set b = (select b from t2 where a = d);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+create table t4(a int not null, b int, primary key(a)) engine=innodb select * from t2;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+insert into t5 (select * from t2 lock in share mode);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+update t6 set e = (select b from t2 where a = d lock in share mode);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+create table t7(a int not null, b int, primary key(a)) engine=innodb select * from t2 lock in share mode;
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+insert into t8 (select * from t2 for update);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+update t9 set e = (select b from t2 where a = d for update);
+SET binlog_format='MIXED';
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
+create table t10(a int not null, b int, primary key(a)) engine=innodb select * from t2 for update;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+commit;
+drop table t1, t2, t3, t5, t6, t8, t9;
+CREATE TABLE t1 (DB_ROW_ID int) engine=innodb;
+ERROR 42000: Incorrect column name 'DB_ROW_ID'
+CREATE TABLE t1 (
+a BIGINT(20) NOT NULL,
+PRIMARY KEY (a)
+) ENGINE=INNODB DEFAULT CHARSET=UTF8;
+CREATE TABLE t2 (
+a BIGINT(20) NOT NULL,
+b VARCHAR(128) NOT NULL,
+c TEXT NOT NULL,
+PRIMARY KEY (a,b),
+KEY idx_t2_b_c (b,c(200)),
+CONSTRAINT t_fk FOREIGN KEY (a) REFERENCES t1 (a)
+ON DELETE CASCADE
+) ENGINE=INNODB DEFAULT CHARSET=UTF8;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1, 'bar', 'vbar');
+INSERT INTO t2 VALUES (1, 'BAR2', 'VBAR');
+INSERT INTO t2 VALUES (1, 'bar_bar', 'bibi');
+INSERT INTO t2 VALUES (1, 'customer_over', '1');
+SELECT * FROM t2 WHERE b = 'customer_over';
+a b c
+1 customer_over 1
+SELECT * FROM t2 WHERE BINARY b = 'customer_over';
+a b c
+1 customer_over 1
+SELECT DISTINCT p0.a FROM t2 p0 WHERE p0.b = 'customer_over';
+a
+1
+/* Bang: Empty result set, above was expected: */
+SELECT DISTINCT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
+a
+1
+SELECT p0.a FROM t2 p0 WHERE BINARY p0.b = 'customer_over';
+a
+1
+drop table t2, t1;
+CREATE TABLE t1 ( a int ) ENGINE=innodb;
+BEGIN;
+INSERT INTO t1 VALUES (1);
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
+test.t1 optimize status OK
+DROP TABLE t1;
+CREATE TABLE t1 (id int PRIMARY KEY, f int NOT NULL, INDEX(f)) ENGINE=InnoDB;
+CREATE TABLE t2 (id int PRIMARY KEY, f INT NOT NULL,
+CONSTRAINT t2_t1 FOREIGN KEY (id) REFERENCES t1 (id)
+ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB;
+ALTER TABLE t2 ADD FOREIGN KEY (f) REFERENCES t1 (f) ON
+DELETE CASCADE ON UPDATE CASCADE;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `id` int(11) NOT NULL,
+ `f` int(11) NOT NULL,
+ PRIMARY KEY (`id`),
+ KEY `f` (`f`),
+ CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f`) REFERENCES `t1` (`f`) ON DELETE CASCADE ON UPDATE CASCADE,
+ CONSTRAINT `t2_t1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE t2, t1;
+CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB;
+CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1);
+ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL;
+ALTER TABLE t2 MODIFY a INT NOT NULL;
+ERROR HY000: Error on rename of '#sql-temporary' to './test/t2' (errno: 150)
+DELETE FROM t1;
+DROP TABLE t2,t1;
+CREATE TABLE t1 (id int PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB
+AUTO_INCREMENT=42;
+INSERT INTO t1 VALUES (0),(347),(0);
+SELECT * FROM t1;
+id
+42
+347
+348
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1
+CREATE TABLE t2 (id int PRIMARY KEY) ENGINE=InnoDB;
+INSERT INTO t2 VALUES(42),(347),(348);
+ALTER TABLE t1 ADD CONSTRAINT t1_t2 FOREIGN KEY (id) REFERENCES t2(id);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ PRIMARY KEY (`id`),
+ CONSTRAINT `t1_t2` FOREIGN KEY (`id`) REFERENCES `t2` (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=349 DEFAULT CHARSET=latin1
+DROP TABLE t1,t2;
+set innodb_strict_mode=on;
+CREATE TABLE t1 (
+c01 CHAR(255), c02 CHAR(255), c03 CHAR(255), c04 CHAR(255),
+c05 CHAR(255), c06 CHAR(255), c07 CHAR(255), c08 CHAR(255),
+c09 CHAR(255), c10 CHAR(255), c11 CHAR(255), c12 CHAR(255),
+c13 CHAR(255), c14 CHAR(255), c15 CHAR(255), c16 CHAR(255),
+c17 CHAR(255), c18 CHAR(255), c19 CHAR(255), c20 CHAR(255),
+c21 CHAR(255), c22 CHAR(255), c23 CHAR(255), c24 CHAR(255),
+c25 CHAR(255), c26 CHAR(255), c27 CHAR(255), c28 CHAR(255),
+c29 CHAR(255), c30 CHAR(255), c31 CHAR(255), c32 CHAR(255)
+) ENGINE = InnoDB;
+ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
+DROP TABLE IF EXISTS t1;
+Warnings:
+Note 1051 Unknown table 't1'
+CREATE TABLE t1(
+id BIGINT(20) NOT NULL AUTO_INCREMENT PRIMARY KEY
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(-10);
+SELECT * FROM t1;
+id
+-10
+INSERT INTO t1 VALUES(NULL);
+SELECT * FROM t1;
+id
+-10
+1
+DROP TABLE t1;
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+DROP TABLE IF EXISTS t1, t2;
+Warnings:
+Note 1051 Unknown table 't1'
+Note 1051 Unknown table 't2'
+CREATE TABLE t1 ( a int ) ENGINE=InnoDB;
+CREATE TABLE t2 LIKE t1;
+SELECT * FROM t2;
+a
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (1);
+COMMIT;
+SELECT * FROM t1 WHERE a=1;
+a
+1
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+SELECT * FROM t2;
+a
+SET binlog_format='MIXED';
+SET TX_ISOLATION='read-committed';
+SET AUTOCOMMIT=0;
+INSERT INTO t1 VALUES (2);
+COMMIT;
+SELECT * FROM t1 WHERE a=2;
+a
+2
+SELECT * FROM t1 WHERE a=2;
+a
+2
+DROP TABLE t1;
+DROP TABLE t2;
+create table t1 (i int, j int) engine=innodb;
+insert into t1 (i, j) values (1, 1), (2, 2);
+update t1 set j = 2;
+affected rows: 1
+info: Rows matched: 2 Changed: 1 Warnings: 0
+drop table t1;
+create table t1 (id int) comment='this is a comment' engine=innodb;
+select table_comment, data_free > 0 as data_free_is_set
+from information_schema.tables
+where table_schema='test' and table_name = 't1';
+table_comment data_free_is_set
+this is a comment 1
+drop table t1;
+CREATE TABLE t1 (
+c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+c2 VARCHAR(128) NOT NULL,
+PRIMARY KEY(c1)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=100;
+CREATE TABLE t2 (
+c1 INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+c2 INT(10) UNSIGNED DEFAULT NULL,
+PRIMARY KEY(c1)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=200;
+SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
+AUTO_INCREMENT
+200
+ALTER TABLE t2 ADD CONSTRAINT t1_t2_1 FOREIGN KEY(c1) REFERENCES t1(c1);
+SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE table_name = 't2';
+AUTO_INCREMENT
+200
+DROP TABLE t2;
+DROP TABLE t1;
+CREATE TABLE t1 (c1 int default NULL,
+c2 int default NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+TRUNCATE TABLE t1;
+affected rows: 0
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+affected rows: 5
+info: Records: 5 Duplicates: 0 Warnings: 0
+TRUNCATE TABLE t1;
+affected rows: 0
+DROP TABLE t1;
+Variable_name Value
+Handler_update 0
+Variable_name Value
+Handler_delete 0
+Variable_name Value
+Handler_update 1
+Variable_name Value
+Handler_delete 1
+set optimizer_switch=@innodb_test_tmp;
+set @innodb_test_dont_touch_optimizer_switch=NULL;
+set optimizer_switch=@innodb_with_mrricp;
diff --git a/mysql-test/r/innodb_release_row_locks_early.result b/mysql-test/r/innodb_release_row_locks_early.result
deleted file mode 100644
index d544dc8df1f..00000000000
--- a/mysql-test/r/innodb_release_row_locks_early.result
+++ /dev/null
@@ -1,104 +0,0 @@
-DROP TABLE IF EXISTS t1;
-CREATE TABLE t1 (k INT NOT NULL, a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, PRIMARY KEY(k)) ENGINE=InnoDB;
-INSERT INTO t1 (k, a, b, c) VALUES (1, 0, 0, 0);
-INSERT INTO t1 (k, a, b, c) VALUES (2, 0, 0, 0);
-INSERT INTO t1 (k, a, b, c) VALUES (3, 0, 0, 0);
-INSERT INTO t1 (k, a, b, c) VALUES (4, 0, 0, 0);
-RESET MASTER;
-SET DEBUG_SYNC= 'RESET';
-# Connection c1
-SET binlog_format= mixed;
-BEGIN;
-UPDATE t1 SET a=10 WHERE k=1;
-SET DEBUG_SYNC="commit_after_release_LOCK_prepare_ordered SIGNAL c1_prepared WAIT_FOR c2_committing";
-COMMIT;
-# Connection c2
-SET binlog_format= mixed;
-SET DEBUG_SYNC="now WAIT_FOR c1_prepared";
-BEGIN;
-SELECT * FROM t1 WHERE k=1 FOR UPDATE;
-k a b c
-1 10 0 0
-UPDATE t1 SET a=20 WHERE k=1;
-SET DEBUG_SYNC="now SIGNAL c2_committing";
-COMMIT;
-# Connection c1
-BEGIN;
-UPDATE t1 SET a=10 WHERE k=2;
-SET DEBUG_SYNC="commit_after_release_LOCK_prepare_ordered SIGNAL c1_prepared WAIT_FOR c2_committed TIMEOUT 2";
-COMMIT;
-# Connection c2
-SET DEBUG_SYNC="now WAIT_FOR c1_prepared";
-BEGIN;
-SELECT * FROM t1 WHERE k=2 FOR UPDATE;
-k a b c
-2 10 0 0
-UPDATE t1 SET a=20 WHERE k=2;
-SET DEBUG_SYNC="binlog_after_log_and_order SIGNAL c2_committed";
-COMMIT;
-# Connection c1
-# This should warn about DEBUG_SYNC timeout
-Warnings:
-Warning 1639 debug sync point wait timed out
-# Connection c2
-SHOW BINLOG EVENTS LIMIT 2,12;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query 1 # use `test`; UPDATE t1 SET a=10 WHERE k=1
-master-bin.000001 # Xid 1 # COMMIT /* xid=XX */
-master-bin.000001 # Query 1 # BEGIN
-master-bin.000001 # Query 1 # use `test`; UPDATE t1 SET a=20 WHERE k=1
-master-bin.000001 # Xid 1 # COMMIT /* xid=XX */
-master-bin.000001 # Query 1 # BEGIN
-master-bin.000001 # Query 1 # use `test`; UPDATE t1 SET a=10 WHERE k=2
-master-bin.000001 # Xid 1 # COMMIT /* xid=XX */
-master-bin.000001 # Query 1 # BEGIN
-master-bin.000001 # Query 1 # use `test`; UPDATE t1 SET a=20 WHERE k=2
-master-bin.000001 # Xid 1 # COMMIT /* xid=XX */
-# Connection c1
-RESET MASTER;
-SET DEBUG_SYNC="commit_after_release_LOCK_prepare_ordered SIGNAL c1_prepared WAIT_FOR c2_committing";
-UPDATE t1 SET a=10 WHERE k=3;
-# Connection c2
-SET DEBUG_SYNC="now WAIT_FOR c1_prepared";
-SELECT * FROM t1 WHERE k=3 FOR UPDATE;
-k a b c
-3 10 0 0
-SET DEBUG_SYNC="commit_after_release_LOCK_prepare_ordered SIGNAL c2_committing";
-UPDATE t1 SET a=20 WHERE k=3;
-# Connection c1
-SET DEBUG_SYNC="commit_after_release_LOCK_prepare_ordered SIGNAL c1_prepared WAIT_FOR c2_committed TIMEOUT 2";
-UPDATE t1 SET a=10 WHERE k=4;
-# Connection c2
-SET DEBUG_SYNC="now WAIT_FOR c1_prepared";
-SELECT * FROM t1 WHERE k=4 FOR UPDATE;
-k a b c
-4 10 0 0
-SET DEBUG_SYNC="binlog_after_log_and_order SIGNAL c2_committed";
-UPDATE t1 SET a=20 WHERE k=4;
-# Connection c1
-# This should warn about DEBUG_SYNC timeout
-Warnings:
-Warning 1639 debug sync point wait timed out
-# Connection c2
-SHOW BINLOG EVENTS LIMIT 1,12;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query 1 # BEGIN
-master-bin.000001 # Query 1 # use `test`; UPDATE t1 SET a=10 WHERE k=3
-master-bin.000001 # Xid 1 # COMMIT /* xid=XX */
-master-bin.000001 # Query 1 # BEGIN
-master-bin.000001 # Query 1 # use `test`; UPDATE t1 SET a=20 WHERE k=3
-master-bin.000001 # Xid 1 # COMMIT /* xid=XX */
-master-bin.000001 # Query 1 # BEGIN
-master-bin.000001 # Query 1 # use `test`; UPDATE t1 SET a=10 WHERE k=4
-master-bin.000001 # Xid 1 # COMMIT /* xid=XX */
-master-bin.000001 # Query 1 # BEGIN
-master-bin.000001 # Query 1 # use `test`; UPDATE t1 SET a=20 WHERE k=4
-master-bin.000001 # Xid 1 # COMMIT /* xid=XX */
-SELECT * FROM t1 ORDER BY k;
-k a b c
-1 20 0 0
-2 20 0 0
-3 20 0 0
-4 20 0 0
-DROP TABLE t1;
-SET DEBUG_SYNC= 'RESET';
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index e3ef617503f..bd0df96c518 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -1,4 +1,5 @@
drop table if exists t1,t2,t3;
+drop view if exists v1,v2;
CREATE TABLE t1 (S1 INT);
CREATE TABLE t2 (S1 INT);
INSERT INTO t1 VALUES (1);
@@ -1221,6 +1222,24 @@ f1
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
#
+# Bug LP:798597: Incorrect "Duplicate entry" error with views and
+# GROUP BY
+#
+CREATE TABLE t1 ( f1 int NOT NULL , f2 int NOT NULL ) ;
+INSERT INTO t1 VALUES (214,0),(6,6);
+CREATE TABLE t2 ( f2 int) ;
+INSERT INTO t2 VALUES (88),(88);
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT t1.f1, t2.f2 FROM (t2 LEFT JOIN t1 ON (t2.f2 <> t1.f1)) WHERE (t1.f2 <= 0) ;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT t1.f1, t2.f2 FROM (t2 LEFT JOIN t1 ON (t2.f2 <> t1.f1)) WHERE (t1.f2 <= 0 or t1.f2 is null) ;
+SELECT f1 , MIN(f2) FROM v1 GROUP BY f1;
+f1 MIN(f2)
+214 88
+SELECT f1 , MIN(f2) FROM v2 GROUP BY f1;
+f1 MIN(f2)
+214 88
+drop table t1,t2;
+drop view v1,v2;
+#
# BUG#47217 Lost optimization caused slowdown & wrong result.
#
CREATE TABLE t1 (pk INT, v VARCHAR(2), PRIMARY KEY(pk));
@@ -1245,7 +1264,7 @@ SHOW STATUS LIKE 'Handler_read_%';
Variable_name Value
Handler_read_first 0
Handler_read_key 1
-Handler_read_next 0
+Handler_read_next 2
Handler_read_prev 0
Handler_read_rnd 0
Handler_read_rnd_next 1
@@ -1320,3 +1339,11 @@ WHERE t1.f1 IN (SELECT f1 FROM t1) AND t1.f1 = t2.f1 OR t1.f1 = 9;
f1 f2 f1 f2
9 4 10 9
DROP TABLE t1,t2;
+create table t1 (i time key);
+insert into t1 values ('1:1:1'), ('2:2:2');
+create table t2 (i time);
+insert into t2 values ('1:1:1');
+select t2.i from t1 left join t2 on t2.i = t1.i where t1.i = '1:1:1';
+i
+01:01:01
+drop table t1,t2;
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result
index bb28ed36f62..1f9ef1dfeda 100644
--- a/mysql-test/r/join_cache.result
+++ b/mysql-test/r/join_cache.result
@@ -1,8 +1,12 @@
DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11;
DROP DATABASE IF EXISTS world;
set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @local_join_cache_test_optimizer_switch_default=@@optimizer_switch;
set names utf8;
CREATE DATABASE world;
use world;
@@ -3032,13 +3036,13 @@ t6.formattypeid IN (2) AND (t3.formatid IN (31, 8, 76)) AND
t1.metaid = t2.metaid AND t1.affiliateid = '2';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t6 system PRIMARY NULL NULL NULL 1
-1 SIMPLE t1 ref t1_affiliateid,t1_metaid t1_affiliateid 4 const 1 Using index condition
-1 SIMPLE t4 ref PRIMARY,t4_formatclassid,t4_formats_idx t4_formats_idx 1 const 1 Using index condition; Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE t5 eq_ref PRIMARY,t5_formattypeid PRIMARY 4 test.t4.formatclassid 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t1 ref t1_affiliateid,t1_metaid t1_affiliateid 4 const 1
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t7 ref PRIMARY PRIMARY 4 test.t1.metaid 1 Using index
-1 SIMPLE t3 ref t3_metaid,t3_formatid,t3_metaidformatid t3_metaid 4 test.t1.metaid 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE t8 eq_ref PRIMARY PRIMARY 4 test.t7.artistid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t8 eq_ref PRIMARY PRIMARY 4 test.t7.artistid 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t3 ref t3_metaid,t3_formatid,t3_metaidformatid t3_metaidformatid 4 test.t1.metaid 1 Using index condition; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t4 eq_ref PRIMARY,t4_formatclassid,t4_formats_idx PRIMARY 4 test.t3.formatid 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t5 eq_ref PRIMARY,t5_formattypeid PRIMARY 4 test.t4.formatclassid 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t9 index PRIMARY,t9_subgenreid,t9_metaid PRIMARY 8 NULL 2 Using where; Using index; Using join buffer (incremental, BNL join)
1 SIMPLE t10 eq_ref PRIMARY,t10_genreid PRIMARY 4 test.t9.subgenreid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
1 SIMPLE t11 eq_ref PRIMARY PRIMARY 4 test.t10.genreid 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
@@ -3147,6 +3151,8 @@ CREATE TABLE t2 (a int, b int, INDEX idx(a));
INSERT INTO t1 VALUES (5,30), (3,20), (7,40), (2,10), (8,30), (1,10), (4,20);
INSERT INTO t2 VALUES (7,10), (1,20), (2,20), (8,20), (8,10), (1,20);
INSERT INTO t2 VALUES (1,10), (4,20), (3,20), (7,20), (7,10), (1,20);
+INSERT INTO t2 VALUES (17,10), (11,20), (12,20), (18,20), (18,10), (11,20);
+INSERT INTO t2 VALUES (11,10), (14,20), (13,20), (17,20), (17,10), (11,20);
set join_buffer_size=32;
Warnings:
Warning 1292 Truncated incorrect join_buffer_size value: '32'
@@ -3172,6 +3178,7 @@ CREATE TABLE t1 (a int NOT NULL);
INSERT INTO t1 VALUES (2), (4), (3), (5), (1);
CREATE TABLE t2 (a int NOT NULL, b int NOT NULL, INDEX i_a(a));
INSERT INTO t2 VALUES (4,10), (2,10), (2,30), (2,20), (4,20);
+INSERT INTO t2 VALUES (14,10), (12,10), (15,30), (12,20), (14,20);
EXPLAIN
SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL;
id select_type table type possible_keys key key_len ref rows Extra
@@ -3562,6 +3569,9 @@ create table t2 (id1 int, id2 int, index idx2 (id1));
insert into t2 values
(20, 100), (30, 400), (20, 400), (30, 200), (10, 300), (10, 200), (40, 100),
(40, 200), (30, 300), (10, 400), (20, 200), (20, 300);
+insert into t2 values
+(21, 10), (31, 400), (21, 400), (31, 200), (11, 300), (11, 200), (41, 100),
+(41, 200), (31, 300), (11, 400), (21, 200), (21, 300);
set join_cache_level=6;
explain
select t1.id1, sum(t2.id2) from t1 join t2 on t1.id1=t2.id1
@@ -3609,14 +3619,26 @@ insert into t2 values
(30, 'bbb'), (10, 'b'), (70, 'bbbbbbb'), (60, 'bbbbbb'),
(31, 'bbb'), (11, 'b'), (71, 'bbbbbbb'), (61, 'bbbbbb'),
(32, 'bbb'), (12, 'b'), (72, 'bbbbbbb'), (62, 'bbbbbb');
+insert into t2 values
+(130, 'bbb'), (110, 'b'), (170, 'bbbbbbb'), (160, 'bbbbbb'),
+(131, 'bbb'), (111, 'b'), (171, 'bbbbbbb'), (161, 'bbbbbb'),
+(132, 'bbb'), (112, 'b'), (172, 'bbbbbbb'), (162, 'bbbbbb');
insert into t3 values
(4000, 'dddd'), (3000, 'ddd'), (1000, 'd'), (8000, 'dddddddd'),
(4001, 'dddd'), (3001, 'ddd'), (1001, 'd'), (8001, 'dddddddd'),
(4002, 'dddd'), (3002, 'ddd'), (1002, 'd'), (8002, 'dddddddd');
+insert into t3 values
+(14000, 'dddd'), (13000, 'ddd'), (11000, 'd'), (18000, 'dddddddd'),
+(14001, 'dddd'), (13001, 'ddd'), (11001, 'd'), (18001, 'dddddddd'),
+(4002, 'dddd'), (3002, 'ddd'), (1002, 'd'), (8002, 'dddddddd');
insert into t4 values
(200, 'cc'), (600, 'cccccc'), (300, 'ccc'), (500, 'ccccc'),
(201, 'cc'), (601, 'cccccc'), (301, 'ccc'), (501, 'ccccc'),
(202, 'cc'), (602, 'cccccc'), (302, 'ccc'), (502, 'ccccc');
+insert into t4 values
+(1200, 'cc'), (1600, 'cccccc'), (1300, 'ccc'), (1500, 'ccccc'),
+(1201, 'cc'), (1601, 'cccccc'), (1301, 'ccc'), (1501, 'ccccc'),
+(1202, 'cc'), (1602, 'cccccc'), (1302, 'ccc'), (1502, 'ccccc');
analyze table t2,t3,t4;
set join_cache_level=1;
explain
@@ -3961,7 +3983,9 @@ DROP TABLE t1,t2,t3,t4;
CREATE TABLE t1 (b int);
INSERT INTO t1 VALUES (NULL),(3);
CREATE TABLE t2 (a int, b int, KEY (b));
-INSERT INTO t2 VALUES (100,NULL),(150,200);
+INSERT INTO t2 VALUES
+(100,NULL),(150,200),(50,150),(250,350),(180,210),(100,150),
+(101,NULL),(151,200),(51,150),(251,350),(181,210),(101,150);
set join_cache_level = 5;
explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
id select_type table type possible_keys key key_len ref rows Extra
@@ -3996,6 +4020,7 @@ CREATE TABLE t1 (b varchar(100));
INSERT INTO t1 VALUES (NULL),("some varchar");
CREATE TABLE t2 (a int, b varchar(100), KEY (b));
INSERT INTO t2 VALUES (100,NULL),(150,"varchar"),(200,NULL),(250,"long long varchar");
+INSERT INTO t2 VALUES (100,NULL),(150,"long varchar"),(200,"varchar"),(250,"long long long varchar");
set join_cache_level = 5;
explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
id select_type table type possible_keys key key_len ref rows Extra
@@ -4110,6 +4135,17 @@ INSERT INTO t3 VALUES
(1,0,'2002-07-13','06:34:26','v','v'), (9,3,'2003-01-03','18:07:38','m','m'),
(1,5,'2006-04-02','13:55:23','z','z'), (3,9,'2006-10-19','20:32:28','n','n'),
(8,1,'2005-06-08','11:57:44','d','d'), (231,107,'2006-12-26','03:10:35','a','a');
+INSERT INTO t3 VALUES
+(103,108,'2008-12-04','00:00:00','a','v'), (103,108,'2009-03-28','00:00:00','b','f'),
+(103,105,'1900-01-01','00:55:47','c','v'), (102,108,'2009-10-02','00:00:00','d','s'),
+(100,108,'1900-01-01','20:51:59','e','a'), (100,106,'2008-06-04','09:47:27','f','p'),
+(108,107,'2009-01-13','21:58:29','g','z'), (105,102,'1900-01-01','22:45:53','h','a'),
+(109,105,'2008-01-28','14:06:48','i','h'), (105,107,'2004-09-18','22:17:16','j','h'),
+(104,102,'2006-10-14','14:59:37','k','v'), (102,109,'1900-01-01','23:37:40','l','v'),
+(1033,1142,'2000-11-28','14:14:01','m','b'), (105,103,'2008-04-04','02:54:19','n','y'),
+(100,100,'2002-07-13','06:34:26','o','v'), (109,103,'2003-01-03','18:07:38','p','m'),
+(100,105,'2006-04-02','13:55:23','q','z'), (103,109,'2006-10-19','20:32:28','s','n'),
+(108,100,'2005-06-08','11:57:44','t','d'), (1231,1107,'2006-12-26','03:10:35','v','a');
CREATE TABLE t1 SELECT * FROM t3;
DELETE FROM t1 WHERE i > 8;
CREATE TABLE t2 SELECT * FROM t3;
@@ -4120,55 +4156,87 @@ WHERE t3.u <='a' AND t2.j < 5 AND t3.v = t2.u;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 16
1 SIMPLE t2 ALL NULL NULL NULL NULL 18 Using where; Using join buffer (flat, BNL join)
-1 SIMPLE t3 hash_ALL idx #hash#idx 3 test.t2.u 20 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t3 hash_ALL idx #hash#idx 3 test.t2.u 40 Using where; Using join buffer (flat, BNLH join)
SELECT t1.i, t1.d, t1.v, t2.i, t2.d, t2.t, t2.v FROM t1,t2,t3
WHERE t3.u <='a' AND t2.j < 5 AND t3.v = t2.u;
i d v i d t v
+0 2008-06-04 p 1 2002-07-13 06:34:26 v
+0 2008-06-04 p 4 2006-10-14 14:59:37 v
0 2008-06-04 p 5 1900-01-01 22:45:53 a
0 2008-06-04 p 5 1900-01-01 22:45:53 a
0 2008-06-04 p 5 1900-01-01 22:45:53 a
+1 1900-01-01 a 1 2002-07-13 06:34:26 v
+1 1900-01-01 a 4 2006-10-14 14:59:37 v
1 1900-01-01 a 5 1900-01-01 22:45:53 a
1 1900-01-01 a 5 1900-01-01 22:45:53 a
1 1900-01-01 a 5 1900-01-01 22:45:53 a
+1 2002-07-13 v 1 2002-07-13 06:34:26 v
+1 2002-07-13 v 4 2006-10-14 14:59:37 v
1 2002-07-13 v 5 1900-01-01 22:45:53 a
1 2002-07-13 v 5 1900-01-01 22:45:53 a
1 2002-07-13 v 5 1900-01-01 22:45:53 a
+1 2006-04-02 z 1 2002-07-13 06:34:26 v
+1 2006-04-02 z 4 2006-10-14 14:59:37 v
1 2006-04-02 z 5 1900-01-01 22:45:53 a
1 2006-04-02 z 5 1900-01-01 22:45:53 a
1 2006-04-02 z 5 1900-01-01 22:45:53 a
+2 1900-01-01 v 1 2002-07-13 06:34:26 v
+2 1900-01-01 v 4 2006-10-14 14:59:37 v
2 1900-01-01 v 5 1900-01-01 22:45:53 a
2 1900-01-01 v 5 1900-01-01 22:45:53 a
2 1900-01-01 v 5 1900-01-01 22:45:53 a
+2 2009-10-02 s 1 2002-07-13 06:34:26 v
+2 2009-10-02 s 4 2006-10-14 14:59:37 v
2 2009-10-02 s 5 1900-01-01 22:45:53 a
2 2009-10-02 s 5 1900-01-01 22:45:53 a
2 2009-10-02 s 5 1900-01-01 22:45:53 a
+3 1900-01-01 v 1 2002-07-13 06:34:26 v
+3 1900-01-01 v 4 2006-10-14 14:59:37 v
3 1900-01-01 v 5 1900-01-01 22:45:53 a
3 1900-01-01 v 5 1900-01-01 22:45:53 a
3 1900-01-01 v 5 1900-01-01 22:45:53 a
+3 2006-10-19 n 1 2002-07-13 06:34:26 v
+3 2006-10-19 n 4 2006-10-14 14:59:37 v
3 2006-10-19 n 5 1900-01-01 22:45:53 a
3 2006-10-19 n 5 1900-01-01 22:45:53 a
3 2006-10-19 n 5 1900-01-01 22:45:53 a
+3 2008-12-04 v 1 2002-07-13 06:34:26 v
+3 2008-12-04 v 4 2006-10-14 14:59:37 v
3 2008-12-04 v 5 1900-01-01 22:45:53 a
3 2008-12-04 v 5 1900-01-01 22:45:53 a
3 2008-12-04 v 5 1900-01-01 22:45:53 a
+3 2009-03-28 f 1 2002-07-13 06:34:26 v
+3 2009-03-28 f 4 2006-10-14 14:59:37 v
3 2009-03-28 f 5 1900-01-01 22:45:53 a
3 2009-03-28 f 5 1900-01-01 22:45:53 a
3 2009-03-28 f 5 1900-01-01 22:45:53 a
+4 2006-10-14 v 1 2002-07-13 06:34:26 v
+4 2006-10-14 v 4 2006-10-14 14:59:37 v
4 2006-10-14 v 5 1900-01-01 22:45:53 a
4 2006-10-14 v 5 1900-01-01 22:45:53 a
4 2006-10-14 v 5 1900-01-01 22:45:53 a
+5 1900-01-01 a 1 2002-07-13 06:34:26 v
+5 1900-01-01 a 4 2006-10-14 14:59:37 v
5 1900-01-01 a 5 1900-01-01 22:45:53 a
5 1900-01-01 a 5 1900-01-01 22:45:53 a
5 1900-01-01 a 5 1900-01-01 22:45:53 a
+5 2004-09-18 h 1 2002-07-13 06:34:26 v
+5 2004-09-18 h 4 2006-10-14 14:59:37 v
5 2004-09-18 h 5 1900-01-01 22:45:53 a
5 2004-09-18 h 5 1900-01-01 22:45:53 a
5 2004-09-18 h 5 1900-01-01 22:45:53 a
+5 2008-04-04 y 1 2002-07-13 06:34:26 v
+5 2008-04-04 y 4 2006-10-14 14:59:37 v
5 2008-04-04 y 5 1900-01-01 22:45:53 a
5 2008-04-04 y 5 1900-01-01 22:45:53 a
5 2008-04-04 y 5 1900-01-01 22:45:53 a
+8 2005-06-08 d 1 2002-07-13 06:34:26 v
+8 2005-06-08 d 4 2006-10-14 14:59:37 v
8 2005-06-08 d 5 1900-01-01 22:45:53 a
8 2005-06-08 d 5 1900-01-01 22:45:53 a
8 2005-06-08 d 5 1900-01-01 22:45:53 a
+8 2009-01-13 z 1 2002-07-13 06:34:26 v
+8 2009-01-13 z 4 2006-10-14 14:59:37 v
8 2009-01-13 z 5 1900-01-01 22:45:53 a
8 2009-01-13 z 5 1900-01-01 22:45:53 a
8 2009-01-13 z 5 1900-01-01 22:45:53 a
@@ -4186,7 +4254,15 @@ PRIMARY KEY (pk), INDEX idx1(i), INDEX idx2 (v,i)
INSERT INTO t1 VALUES
(10,8,'v'), (11,8,'f'), (12,5,'v'), (13,8,'s'), (14,8,'a'),
(15,6,'p'), (16,7,'z'), (17,2,'a'), (18,5,'h'), (19,7,'h'),
-(25,3,'m'), (26,5,'z'), (27,9,'n'), (28,1,'d'), (29,107,'a');
+(25,3,'m'), (26,5,'a'), (27,9,'n'), (28,1,'d'), (29,107,'a');
+INSERT INTO t1 VALUES
+(110,8,'x'), (111,8,'y'), (112,5,'v'), (113,8,'z'), (114,8,'i'),
+(115,6,'j'), (116,7,'t'), (117,2,'b'), (118,5,'j'), (119,7,'w'),
+(125,3,'q'), (126,5,'o'), (127,9,'n'), (128,1,'e'), (129,107,'c');
+INSERT INTO t1 VALUES
+(210,8,'b'), (211,8,'c'), (212,5,'d'), (213,8,'e'), (214,8,'g'),
+(215,6,'f'), (216,7,'h'), (217,2,'i'), (218,5,'j'), (219,7,'k'),
+(225,3,'l'), (226,5,'m'), (227,9,'n'), (228,1,'o'), (229,107,'p');
CREATE TABLE t2 (
pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
PRIMARY KEY (pk), INDEX idx1(i), INDEX idx2(v,i)
@@ -4195,7 +4271,7 @@ INSERT INTO t2 VALUES
(10,8,'v'), (11,8,'f'), (12,5,'v'), (13,8,'s'), (14,8,'a'),
(15,6,'p'), (16,7,'z'), (17,2,'a'), (18,5,'h'), (19,7,'h'),
(20,2,'v'), (21,9,'v'), (22,142,'b'), (23,3,'y'), (24,0,'v'),
-(25,3,'m'), (26,5,'z'), (27,9,'n'), (28,1,'d'), (29,107,'a');
+(25,3,'m'), (26,5,'b'), (27,9,'n'), (28,1,'d'), (29,107,'a');
CREATE TABLE t3 (
pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
PRIMARY KEY (pk), INDEX idx1(i), INDEX idx2(v,i)
@@ -4207,49 +4283,55 @@ INSERT INTO t3 VALUES
(16,6,'e'), (17,3,'t'), (18,8,'j'), (19,5,'h'), (20,7,'w');
SET SESSION join_cache_level=1;
EXPLAIN
-SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index idx1 idx2 7 NULL 20 Using index; Using temporary; Using filesort
1 SIMPLE t3 eq_ref PRIMARY,idx2 PRIMARY 4 test.t2.i 1 Using where
-1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 2
-SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 5 Using where
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
v
+b
h
-z
-p
n
v
+p
SET SESSION join_cache_level=6;
EXPLAIN
-SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL idx1 NULL NULL NULL 20 Using temporary; Using filesort
1 SIMPLE t3 eq_ref PRIMARY,idx2 PRIMARY 4 test.t2.i 1 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 2 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
-SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+1 SIMPLE t1 ref idx2 idx2 3 test.t3.v 5 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
v
+b
h
-z
n
v
p
SET SESSION join_cache_level=4;
EXPLAIN
-SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL idx1 NULL NULL NULL 20 Using temporary; Using filesort
1 SIMPLE t3 hash_ALL PRIMARY,idx2 #hash#PRIMARY 4 test.t2.i 20 Using where; Using join buffer (flat, BNLH join)
-1 SIMPLE t1 hash_ALL idx2 #hash#idx2 3 test.t3.v 15 Using join buffer (incremental, BNLH join)
-SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+1 SIMPLE t1 hash_ALL idx2 #hash#idx2 3 test.t3.v 45 Using where; Using join buffer (incremental, BNLH join)
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
v
+b
h
-z
n
v
p
@@ -4316,13 +4398,18 @@ INSERT INTO t2 VALUES
(1, 12, 102), (8, 81, 801), (7, 70, 700), (12, 120, 1200),
(8, 82, 802), (1, 13, 103), (1, 14, 104), (3, 31, 301),
(1, 15, 105), (8, 83, 803), (7, 71, 701);
+INSERT INTO t2 VALUES
+(108, 80, 800), (101, 10, 100), (101, 11, 101), (103, 30, 300),
+(101, 12, 102), (108, 81, 801), (107, 70, 700), (1012, 120, 1200),
+(108, 82, 802), (101, 13, 103), (101, 14, 104), (103, 31, 301),
+(101, 15, 105), (108, 83, 803), (107, 71, 701);
SET SESSION join_cache_level = 4;
SET SESSION join_buffer_size = 192;
EXPLAIN
SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 36 Using where
-1 SIMPLE t2 hash_ALL idx #hash#idx 10 test.t1.a,const 15 Using join buffer (flat, BNLH join)
+1 SIMPLE t2 hash_ALL idx #hash#idx 10 test.t1.a,const 30 Using join buffer (flat, BNLH join)
SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99;
a c
SET SESSION join_cache_level = DEFAULT;
@@ -4349,20 +4436,27 @@ INSERT INTO t2 VALUES
('abcdefjhjk',1015414784), ('or',4), ('now',0), ('abcdefjhjk',-32702464),
('abcdefjhjk',4), ('time',1078394880), ('f',4), ('m',-1845559296),
('ff', 5), ('abcdefjhjk',-1074397184);
+INSERT INTO t2 VALUES
+('dig',5), ('were',-1631322112), ('is',3), ('abcdefjhjl',3),
+('abcdefjh',4), ('told',-824573952), ('tt',0),('vv',-1711013888),
+('abcdefjhjj',1015414784), ('and',4), ('here',0), ('abcdefjhjm',-32702464),
+('abcdefjhji',4), ('space',1078394880), ('fs',4), ('mn',-1845559296),
+('fq', 5), ('abcdefjhjp',-1074397184);
EXPLAIN
SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where
-1 SIMPLE t2 ref idx idx 13 test.t1.v 2
+1 SIMPLE t2 ref idx idx 13 test.t1.v 3
SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
v i
+abcdefjh 4
f 4
f 4
EXPLAIN
SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 7
-1 SIMPLE t2 ref idx idx 13 func 2 Using index condition
+1 SIMPLE t2 ref idx idx 13 func 3 Using index condition
SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v);
v i
f 5
@@ -4372,16 +4466,17 @@ EXPLAIN
SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 7 Using where
-1 SIMPLE t2 hash_ALL idx #hash#idx 13 test.t1.v 18 Using join buffer (flat, BNLH join)
+1 SIMPLE t2 hash_ALL idx #hash#idx 13 test.t1.v 36 Using join buffer (flat, BNLH join)
SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
v i
f 4
f 4
+abcdefjh 4
EXPLAIN
SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 7
-1 SIMPLE t2 hash_ALL idx #hash#idx 13 func 18 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t2 hash_ALL idx #hash#idx 13 func 36 Using where; Using join buffer (flat, BNLH join)
SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = concat(t1.v, t1.v);
v i
f 5
@@ -4412,6 +4507,13 @@ INSERT INTO t2 VALUES
(11,6,'yes'), (12,NULL,'will'), (13,NULL,'o'), (14,NULL,'k'), (15,NULL,'she'),
(16,-1450835968,'abcdefjhjkl'), (17,-975831040,'abcdefjhjkl'), (18,NULL,'z'),
(19,-343932928,'t');
+INSERT INTO t2 VALUES
+(101,6,'yes'), (102,NULL,'will'), (103,NULL,'o'), (104,NULL,'k'), (105,NULL,'she'),
+(106,-1450835968,'abcdefjhjkl'), (107,-975831040,'abcdefjhjkl'), (108,NULL,'z'),
+(100,-343932928,'t'),
+(111,6,'yes'), (112,NULL,'will'), (113,NULL,'o'), (114,NULL,'k'), (115,NULL,'she'),
+(116,-1450835968,'abcdefjhjkl'), (117,-975831040,'abcdefjhjkl'), (118,NULL,'z'),
+(119,-343932928,'t');
CREATE TABLE t3 (
pk int NOT NULL PRIMARY KEY,
i int,
@@ -4427,6 +4529,15 @@ INSERT INTO t3 VALUES
(26,NULL,'all'), (27,1443168256,'c'), (28,1427046400,'right'),
(31,7,'abcdefjhjkl'), (32,6,'y'), (33,NULL,'to'), (34,7,'n'), (35,7,'look'),
(36,NULL,'all'), (37,1443168256,'c'), (38,1427046400,'right');
+INSERT INTO t3 VALUES
+(101,7,'abcdefjhjkl'),(102,6,'y'), (103,NULL,'to'),(104,7,'n'),(105,7,'look'),
+(106,NULL,'all'), (107,1443168256,'c'), (108,1427046400,'right'),
+(111,7,'abcdefjhjkl'), (112,6,'y'), (113,NULL,'to'), (114,7,'n'), (115,7,'look'),
+(116,NULL,'all'), (117,1443168256,'c'), (118,1427046400,'right'),
+(121,7,'abcdefjhjkl'), (122,6,'y'), (123,NULL,'to'), (124,7,'n'), (125,7,'look'),
+(126,NULL,'all'), (127,1443168256,'c'), (128,1427046400,'right'),
+(131,7,'abcdefjhjkl'), (132,6,'y'), (133,NULL,'to'), (134,7,'n'), (135,7,'look'),
+(136,NULL,'all'), (137,1443168256,'c'), (138,1427046400,'right');
SET SESSION join_buffer_size = 192;
SET SESSION join_cache_level = 4;
EXPLAIN
@@ -4434,8 +4545,8 @@ SELECT t3.i FROM t1,t2,t3
WHERE t1.v = t2.v AND t3.v = t1.v AND t2.i <> 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index idx idx 13 NULL 7 Using where; Using index
-1 SIMPLE t2 hash_ALL idx #hash#idx 1003 test.t1.v 18 Using where; Using join buffer (flat, BNLH join)
-1 SIMPLE t3 hash_ALL idx #hash#idx 1002 func 32 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t2 hash_ALL idx #hash#idx 1003 test.t1.v 36 Using where; Using join buffer (flat, BNLH join)
+1 SIMPLE t3 hash_ALL idx #hash#idx 1002 func 64 Using where; Using join buffer (incremental, BNLH join)
SELECT t3.i FROM t1,t2,t3
WHERE t1.v = t2.v AND t3.v = t1.v AND t2.i <> 0;
i
@@ -4460,19 +4571,28 @@ INSERT INTO t2 VALUES
(10, 'a'), (20, 'c'), (30, 'aa'), (4, 'bb'),
(11, 'a'), (21, 'c'), (31, 'aa'), (41, 'cc'),
(12, 'a'), (22, 'c'), (32, 'bb'), (42, 'aa');
+INSERT INTO t2 VALUES
+(110, 'a'), (120, 'c'), (130, 'aa'), (14, 'bb'),
+(111, 'a'), (121, 'c'), (131, 'aa'), (141, 'cc'),
+(112, 'a'), (122, 'c'), (132, 'bb'), (142, 'aa');
SELECT * FROM t1,t2 WHERE t2.a=t1.a;
pk a pk a
2 aa 30 aa
2 aa 31 aa
2 aa 42 aa
+2 aa 130 aa
+2 aa 131 aa
+2 aa 142 aa
3 bb 4 bb
3 bb 32 bb
+3 bb 14 bb
+3 bb 132 bb
SET SESSION join_cache_level = 4;
EXPLAIN
SELECT * FROM t1,t2 WHERE t2.a=t1.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL idx NULL NULL NULL 3 Using where
-1 SIMPLE t2 hash_ALL idx #hash#idx 515 test.t1.a 12 Using join buffer (flat, BNLH join)
+1 SIMPLE t2 hash_ALL idx #hash#idx 515 test.t1.a 24 Using join buffer (flat, BNLH join)
SELECT * FROM t1,t2 WHERE t2.a=t1.a;
pk a pk a
2 aa 30 aa
@@ -4480,6 +4600,11 @@ pk a pk a
2 aa 31 aa
3 bb 32 bb
2 aa 42 aa
+2 aa 130 aa
+3 bb 14 bb
+2 aa 131 aa
+3 bb 132 bb
+2 aa 142 aa
SET SESSION join_cache_level = DEFAULT;
DROP TABLE t1,t2;
#
@@ -4562,6 +4687,9 @@ CREATE TABLE t3 (pk int, a3 int, c3 int, d3 int) ;
INSERT IGNORE INTO t3 VALUES (9,0,0,2), (1,0,0,7);
CREATE TABLE t4 (pk int, a4 int, INDEX idx(a4)) ;
INSERT IGNORE INTO t4 VALUES (2,NULL), (8,0);
+INSERT IGNORE INTO t4 VALUES (12,10), (18,20);
+INSERT IGNORE INTO t4 VALUES (22,11), (28,21);
+INSERT IGNORE INTO t4 VALUES (32,12), (38,22);
CREATE TABLE t5 (pk int, a5 int) ;
INSERT IGNORE INTO t5 VALUES (2,0), (8,0);
SET SESSION optimizer_switch = 'outer_join_with_cache=on';
@@ -4779,13 +4907,16 @@ INSERT INTO t1 VALUES
INSERT INTO t2 VALUES
(1,'Bbbb'), (2,'BBB'), (3,'bbbb'), (4,'AaA'), (5,'CC'),
(6,'cC'), (7,'CCC'), (8,'AAA'), (9,'bBbB'), (10,'aaaa'),
-(11,'a'), (12,'dd'), (13,'EE'), (14,'ee'), (15,'D');
+(11,'a'), (12,'dd'), (13,'EE'), (14,'ee'), (15,'D'),
+(101,'Bbbb'), (102,'BBB'), (103,'bbbb'), (104,'AaA'), (105,'CC'),
+(106,'cC'), (107,'CCC'), (108,'AAA'), (109,'bBbB'), (110,'aaaa'),
+(111,'a'), (112,'dd'), (113,'EE'), (114,'ee'), (115,'D');
SET SESSION join_cache_level = 4;
EXPLAIN
SELECT * FROM t1,t2 WHERE t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where
-1 SIMPLE t2 hash_ALL idx #hash#idx 35 test.t1.a 15 Using join buffer (flat, BNLH join)
+1 SIMPLE t2 hash_ALL idx #hash#idx 35 test.t1.a 30 Using join buffer (flat, BNLH join)
SELECT * FROM t1,t2 WHERE t1.a=t2.a;
pk a pk a
20 BBBB 1 Bbbb
@@ -4798,6 +4929,16 @@ pk a pk a
40 DD 12 dd
50 ee 13 EE
50 ee 14 ee
+20 BBBB 101 Bbbb
+20 BBBB 103 bbbb
+10 AAA 104 AaA
+30 Cc 105 CC
+30 Cc 106 cC
+10 AAA 108 AAA
+20 BBBB 109 bBbB
+40 DD 112 dd
+50 ee 113 EE
+50 ee 114 ee
SET SESSION join_cache_level = DEFAULT;
DROP TABLE t1,t2;
#
@@ -4827,13 +4968,13 @@ EXPLAIN
SELECT * FROM t1,t2
WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan
1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNL join)
SELECT * FROM t1,t2
WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6);
f1 f3 f3 f2 f4
SET SESSION join_cache_level = DEFAULT;
-SET SESSION optimizer_switch = DEFAULT;
+SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default;
DROP TABLE t1,t2;
CREATE TABLE t1 (f1 int, f2 varchar(10), KEY (f1), KEY (f2)) ;
INSERT INTO t1 VALUES
@@ -4855,7 +4996,7 @@ id select_type table type possible_keys key key_len ref rows Extra
SELECT * FROM t1,t2
WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1;
f1 f2 f3
-SET SESSION optimizer_switch = DEFAULT;
+SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default;
SET SESSION optimizer_switch = 'index_condition_pushdown=on';
EXPLAIN SELECT * FROM t1,t2
WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1;
@@ -4865,7 +5006,7 @@ id select_type table type possible_keys key key_len ref rows Extra
SELECT * FROM t1,t2
WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1;
f1 f2 f3
-SET SESSION optimizer_switch = DEFAULT;
+SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default;
DROP TABLE t1,t2;
#
# Bug #694443: hash join using IS NULL the an equi-join condition
@@ -4922,13 +5063,15 @@ CREATE TABLE t2 ( f1 varchar(10) , f2 int(11) , KEY (f1));
INSERT INTO t2 VALUES
('hgtofubn',1), ('GDOXZ',91), ('n',2), ('fggxgalh',88),
('hgtofu',1), ('GDO',101), ('n',3), ('fggxga',55),
-('hgtofu',3), ('GDO',33), ('nn',3), ('fggxgarrr',77);
+('hgtofu',3), ('GDO',33), ('nn',3), ('fggxgarrr',77),
+('jgtofu',3), ('JDO',33), ('mn',3), ('jggxgarrr',77),
+('igtofu',3), ('IDO',33), ('ln',3), ('iggxgarrr',77);
SET SESSION join_cache_level=3;
EXPLAIN
SELECT * FROM t1,t2 WHERE t2.f1 = t1.f1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL f1 NULL NULL NULL 2 Using where
-1 SIMPLE t2 hash_ALL f1 #hash#f1 13 test.t1.f1 12 Using join buffer (flat, BNLH join)
+1 SIMPLE t2 hash_ALL f1 #hash#f1 13 test.t1.f1 20 Using join buffer (flat, BNLH join)
SELECT * FROM t1,t2 WHERE t2.f1 = t1.f1;
f1 f2 f1 f2
SET SESSION join_cache_level = DEFAULT;
@@ -4941,17 +5084,20 @@ INSERT INTO t1 VALUES ('o'), ('u');
CREATE TABLE t2 (a int, v varchar(1), INDEX idx (v)) ;
INSERT INTO t2 VALUES
(8,NULL), (10,'b'), (5,'k'), (4,NULL),
-(1,NULL), (11,'u'), (7,NULL), (2,'d');
+(1,NULL), (11,'u'), (7,NULL), (2,'d'),
+(18,'u'), (11,'b'), (15,'k'), (12,'d'),
+(18,'x'), (11,'y'), (15,'l'), (12,'e');
SET SESSION join_buffer_size = 255;
SET SESSION join_cache_level = 4;
EXPLAIN
SELECT a FROM t1,t2 WHERE t2.v = t1.v ;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
-1 SIMPLE t2 hash_ALL idx #hash#idx 4 test.t1.v 8 Using join buffer (flat, BNLH join)
+1 SIMPLE t2 hash_ALL idx #hash#idx 4 test.t1.v 16 Using join buffer (flat, BNLH join)
SELECT a FROM t1,t2 WHERE t2.v = t1.v ;
a
11
+18
SET SESSION join_cache_level = 1;
EXPLAIN
SELECT a FROM t1,t2 WHERE t2.v = t1.v ;
@@ -4961,7 +5107,43 @@ id select_type table type possible_keys key key_len ref rows Extra
SELECT a FROM t1,t2 WHERE t2.v = t1.v ;
a
11
+18
SET SESSION join_cache_level = DEFAULT;
SET SESSION join_buffer_size = DEFAULT;
DROP TABLE t1,t2;
+#
+# Bug #802860: crash on join cache + derived + duplicate_weedout
+#
+SET SESSION optimizer_switch=
+'semijoin=on,materialization=off,firstmatch=off,loosescan=off,derived_with_keys=on';
+CREATE TABLE t1 (a int) ;
+INSERT IGNORE INTO t1 VALUES (0), (1), (0);
+CREATE TABLE t2 (a int) ;
+INSERT IGNORE INTO t2 VALUES (0), (3), (0), (2);
+SET SESSION join_cache_level = 0;
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+WHERE t.a IN (SELECT t2.a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY <derived2> ref key0 key0 5 test.t2.a 2 End temporary
+2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+WHERE t.a IN (SELECT t2.a FROM t2);
+a
+0
+SET SESSION join_cache_level = 1;
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+WHERE t.a IN (SELECT t2.a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL key0 NULL NULL NULL 3 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 3 Using temporary
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+WHERE t.a IN (SELECT t2.a FROM t2);
+a
+0
+SET SESSION join_cache_level = DEFAULT;
+DROP TABLE t1, t2;
set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result
index 3dc6a6338cb..234ac4a88d9 100644
--- a/mysql-test/r/join_nested.result
+++ b/mysql-test/r/join_nested.result
@@ -841,25 +841,26 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
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`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(((`test`.`t3`.`a` = 1) and (`test`.`t4`.`b` = `test`.`t2`.`b`))) where (`test`.`t1`.`a` <= 2)
+INSERT INTO t2 VALUES (-1,9,0), (-3,10,0), (-2,8,0), (-4,11,0), (-5,15,0);
CREATE INDEX idx_b ON t2(b);
EXPLAIN EXTENDED
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
(t1,t2)
-ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
+ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0;
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
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
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`.`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`.`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
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
(t1,t2)
-ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
+ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0;
a b a b a b
4 2 1 2 3 2
4 2 1 2 3 2
@@ -878,7 +879,7 @@ LEFT JOIN
t2
LEFT JOIN
(t3, t4)
-ON t3.a=1 AND t2.b=t4.b,
+ON t3.a=1 AND t2.b=t4.b AND t2.a>0,
t5
LEFT JOIN
(
@@ -907,16 +908,18 @@ t0.b=t1.b AND
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
-1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
-1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
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
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where
+1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where
+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`.`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`.`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`)))
+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);
CREATE INDEX idx_b ON t5(b);
EXPLAIN EXTENDED
@@ -928,7 +931,7 @@ LEFT JOIN
t2
LEFT JOIN
(t3, t4)
-ON t3.a=1 AND t2.b=t4.b,
+ON t3.a=1 AND t2.b=t4.b AND t2.a>0 AND t4.a>0,
t5
LEFT JOIN
(
@@ -937,7 +940,7 @@ LEFT JOIN
t8
ON t7.b=t8.b AND t6.b < 10
)
-ON t6.b >= 2 AND t5.b=t7.b
+ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
@@ -957,16 +960,17 @@ t0.b=t1.b AND
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where
-1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
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
-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`) 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`.`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`.`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`)))
+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
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
@@ -977,16 +981,16 @@ LEFT JOIN
t2
LEFT JOIN
(t3, t4)
-ON t3.a=1 AND t2.b=t4.b,
+ON t3.a=1 AND t2.b=t4.b AND t2.a>0 AND t4.a>0,
t5
LEFT JOIN
(
(t6, t7)
LEFT JOIN
t8
-ON t7.b=t8.b AND t6.b < 10
+ON t7.b=t8.b AND t6.b < 10 AND t8.a>=0
)
-ON t6.b >= 2 AND t5.b=t7.b
+ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
@@ -1006,16 +1010,17 @@ t0.b=t1.b AND
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where
-1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
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
-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`) 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))) 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`.`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`)))
+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);
EXPLAIN EXTENDED
@@ -1040,7 +1045,7 @@ ON t6.b >= 2 AND t5.b=t7.b
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
-(t1.a != 2),
+(t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -1056,16 +1061,16 @@ t0.b=t1.b AND
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t0 ref idx_a idx_a 5 const 1 100.00 Using where
1 SIMPLE t1 ref idx_b idx_b 5 test.t0.b 2 100.00
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where
-1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where
+1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where
1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where
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
-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`) 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))) 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`.`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`)))
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
@@ -1087,7 +1092,7 @@ ON t6.b >= 2 AND t5.b=t7.b
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
-(t1.a != 2),
+(t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -1124,6 +1129,11 @@ a b
3 3
4 2
5 3
+-1 9
+-3 10
+-2 8
+-4 11
+-5 15
SELECT t3.a,t3.b
FROM t3;
a b
@@ -1447,12 +1457,12 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
1 SIMPLE t3 ref a a 5 test.t2.b X Using where
1 SIMPLE t5 ref a a 5 test.t3.b X
-1 SIMPLE t4 ref a a 5 test.t3.b X Using index condition
+1 SIMPLE t4 ref a a 5 test.t3.b X Using where
explain select * from (t4 join t6 on t6.a=t4.b) right join t3 on t4.a=t3.b
join t2 left join (t5 join t7 on t7.a=t5.b) on t5.a=t2.b where t3.a<=>t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL X
-1 SIMPLE t3 ref a a 5 test.t2.b X Using index condition
+1 SIMPLE t3 ref a a 5 test.t2.b X Using where
1 SIMPLE t4 ref a a 5 test.t3.b X Using where
1 SIMPLE t6 ref a a 5 test.t4.b X
1 SIMPLE t5 ref a a 5 test.t2.b X Using where
@@ -1801,4 +1811,35 @@ pk a pk a pk a
7 NULL NULL NULL NULL NULL
8 9 NULL NULL NULL NULL
DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (a int NOT NULL );
+INSERT INTO t1 VALUES (9), (9);
+CREATE TABLE t2 (a int NOT NULL );
+INSERT INTO t2 VALUES (9);
+CREATE TABLE t3 (a int NOT NULL, b int);
+INSERT INTO t3 VALUES (19,9);
+CREATE TABLE t4 (b int) ;
+SELECT * FROM t1 LEFT JOIN
+((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ON t1.a=t2.a;
+a a a b b
+9 9 19 9 NULL
+9 9 19 9 NULL
+SELECT * FROM t1 LEFT JOIN
+((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ON t1.a=t2.a
+WHERE t3.a IS NULL;
+a a a b b
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN
+((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ON t1.a=t2.a
+WHERE t3.a IS NULL;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 1 100.00 Using where
+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`)
+DROP TABLE t1,t2,t3,t4;
End of 5.0 tests
diff --git a/mysql-test/r/join_nested_jcl6.result b/mysql-test/r/join_nested_jcl6.result
index 26c0a9cadfe..ff5a31b599b 100644
--- a/mysql-test/r/join_nested_jcl6.result
+++ b/mysql-test/r/join_nested_jcl6.result
@@ -1,6 +1,8 @@
set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
+set @@optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set join_cache_level=6;
show variables like 'join_cache_level';
Variable_name Value
@@ -848,25 +850,26 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
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`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` 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))) where (`test`.`t1`.`a` <= 2)
+INSERT INTO t2 VALUES (-1,9,0), (-3,10,0), (-2,8,0), (-4,11,0), (-5,15,0);
CREATE INDEX idx_b ON t2(b);
EXPLAIN EXTENDED
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
(t1,t2)
-ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
+ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0;
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
1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
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`.`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`.`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
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
(t1,t2)
-ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
+ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0;
a b a b a b
4 2 1 2 3 2
4 2 1 2 4 2
@@ -885,7 +888,7 @@ LEFT JOIN
t2
LEFT JOIN
(t3, t4)
-ON t3.a=1 AND t2.b=t4.b,
+ON t3.a=1 AND t2.b=t4.b AND t2.a>0,
t5
LEFT JOIN
(
@@ -914,16 +917,18 @@ t0.b=t1.b AND
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 hash_ALL NULL #hash#$hj 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
-1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
-1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
1 SIMPLE t5 ALL NULL NULL NULL NULL 3 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 hash_ALL NULL #hash#$hj 5 test.t5.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t4 hash_ALL NULL #hash#$hj 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BNLH join)
+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`.`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`.`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`)))
+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);
CREATE INDEX idx_b ON t5(b);
EXPLAIN EXTENDED
@@ -935,7 +940,7 @@ LEFT JOIN
t2
LEFT JOIN
(t3, t4)
-ON t3.a=1 AND t2.b=t4.b,
+ON t3.a=1 AND t2.b=t4.b AND t2.a>0 AND t4.a>0,
t5
LEFT JOIN
(
@@ -944,7 +949,7 @@ LEFT JOIN
t8
ON t7.b=t8.b AND t6.b < 10
)
-ON t6.b >= 2 AND t5.b=t7.b
+ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
@@ -964,16 +969,17 @@ t0.b=t1.b AND
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 hash_ALL NULL #hash#$hj 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 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)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+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 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`.`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`)))
+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
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
@@ -984,16 +990,16 @@ LEFT JOIN
t2
LEFT JOIN
(t3, t4)
-ON t3.a=1 AND t2.b=t4.b,
+ON t3.a=1 AND t2.b=t4.b AND t2.a>0 AND t4.a>0,
t5
LEFT JOIN
(
(t6, t7)
LEFT JOIN
t8
-ON t7.b=t8.b AND t6.b < 10
+ON t7.b=t8.b AND t6.b < 10 AND t8.a>=0
)
-ON t6.b >= 2 AND t5.b=t7.b
+ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
@@ -1013,16 +1019,17 @@ t0.b=t1.b AND
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t1 hash_ALL NULL #hash#$hj 5 test.t0.b 3 100.00 Using where; Using join buffer (flat, BNLH join)
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 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)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 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 t5 ALL idx_b NULL NULL NULL 7 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t6 ALL NULL NULL NULL NULL 3 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 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
-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`.`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`)))
+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);
EXPLAIN EXTENDED
@@ -1047,7 +1054,7 @@ ON t6.b >= 2 AND t5.b=t7.b
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
-(t1.a != 2),
+(t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -1063,16 +1070,16 @@ t0.b=t1.b AND
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t0 ref idx_a idx_a 5 const 1 100.00 Using where
1 SIMPLE t1 ref idx_b idx_b 5 test.t0.b 2 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3 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)
+1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 2 100.00 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE t5 ALL idx_b NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join)
+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 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`.`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))) 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`.`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`)))
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
@@ -1094,7 +1101,7 @@ ON t6.b >= 2 AND t5.b=t7.b
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
-(t1.a != 2),
+(t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -1108,15 +1115,15 @@ t0.b=t1.b AND
(t8.b=t9.b OR t8.c IS NULL) AND
(t9.a=1);
a b a b a b a b a b a b a b a b a b a b
-1 2 3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2 1 2
1 2 3 2 4 2 1 2 4 2 2 2 6 2 2 2 0 2 1 2
+1 2 3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2 1 2
1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 1
-1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 1
1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 2
+1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 1
1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 2
1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 1
-1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 1
1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 2
+1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 1
1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 2
1 2 3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 1 2
1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 1
@@ -1131,6 +1138,11 @@ a b
3 3
4 2
5 3
+-1 9
+-3 10
+-2 8
+-4 11
+-5 15
SELECT t3.a,t3.b
FROM t3;
a b
@@ -1808,6 +1820,37 @@ pk a pk a pk a
7 NULL NULL NULL NULL NULL
8 9 NULL NULL NULL NULL
DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (a int NOT NULL );
+INSERT INTO t1 VALUES (9), (9);
+CREATE TABLE t2 (a int NOT NULL );
+INSERT INTO t2 VALUES (9);
+CREATE TABLE t3 (a int NOT NULL, b int);
+INSERT INTO t3 VALUES (19,9);
+CREATE TABLE t4 (b int) ;
+SELECT * FROM t1 LEFT JOIN
+((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ON t1.a=t2.a;
+a a a b b
+9 9 19 9 NULL
+9 9 19 9 NULL
+SELECT * FROM t1 LEFT JOIN
+((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ON t1.a=t2.a
+WHERE t3.a IS NULL;
+a a a b b
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN
+((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ON t1.a=t2.a
+WHERE t3.a IS NULL;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 hash_ALL NULL #hash#$hj 4 test.t1.a 1 100.00 Using where; Using join buffer (flat, BNLH join)
+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`)
+DROP TABLE t1,t2,t3,t4;
End of 5.0 tests
CREATE TABLE t5 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
CREATE TABLE t6 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b));
@@ -1817,6 +1860,9 @@ INSERT INTO t5 VALUES (1,1,0), (2,2,0), (3,3,0);
INSERT INTO t6 VALUES (1,2,0), (3,2,0), (6,1,0);
INSERT INTO t7 VALUES (1,1,0), (2,2,0);
INSERT INTO t8 VALUES (0,2,0), (1,2,0);
+INSERT INTO t6 VALUES (-1,12,0), (-3,13,0), (-6,11,0), (-4,14,0);
+INSERT INTO t7 VALUES (-1,11,0), (-2,12,0), (-3,13,0), (-4,14,0), (-5,15,0);
+INSERT INTO t8 VALUES (-3,13,0), (-1,12,0), (-2,14,0), (-5,15,0), (-4,16,0);
EXPLAIN
SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
FROM t5
@@ -1825,14 +1871,14 @@ LEFT JOIN
(t6, t7)
LEFT JOIN
t8
-ON t7.b=t8.b AND t6.b < 10
+ON t7.b=t8.b AND t6.b < 10
)
ON t6.b >= 2 AND t5.b=t7.b AND
-(t8.a > 0 OR t8.c IS NULL);
+(t8.a > 0 OR t8.c IS NULL) AND t6.a>0 AND t7.a>0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t5 ALL NULL NULL NULL NULL 3
-1 SIMPLE t7 ref b_i b_i 5 test.t5.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
-1 SIMPLE t6 ALL b_i NULL NULL NULL 3 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE t7 ref PRIMARY,b_i b_i 5 test.t5.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t6 ALL PRIMARY,b_i NULL NULL NULL 7 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE t8 ref b_i b_i 5 test.t5.b 2 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
FROM t5
@@ -1844,7 +1890,7 @@ t8
ON t7.b=t8.b AND t6.b < 10
)
ON t6.b >= 2 AND t5.b=t7.b AND
-(t8.a > 0 OR t8.c IS NULL);
+(t8.a > 0 OR t8.c IS NULL) AND t6.a>0 AND t7.a>0;
a b a b a b a b
2 2 1 2 2 2 1 2
2 2 3 2 2 2 1 2
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index c8e174f5a58..ae8ae88dc8d 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -1378,7 +1378,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE jt5 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index
1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index
Warnings:
-Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt1` left join (`test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1))) on(1) where 1
+Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt1` left join (`test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on(((`test`.`jt6`.`f1` <> 0) and 1))) on(1) where 1
EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1
RIGHT JOIN t1 AS jt2
RIGHT JOIN t1 AS jt3
@@ -1395,7 +1395,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index
1 SIMPLE jt1 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index
Warnings:
-Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1)) left join `test`.`t1` `jt1` on(1) where 1
+Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on(((`test`.`jt6`.`f1` <> 0) and 1)) left join `test`.`t1` `jt1` on(1) where 1
DROP TABLE t1;
#
# Bug#49600: outer join of two single-row tables with joining attributes
@@ -1478,6 +1478,8 @@ create table t2 like t1;
insert into t2 select if(t1.a is null, 10, t1.a) from t1;
create table t3 (a int, b int, index idx(a));
insert into t3 values (1, 100), (3, 301), (4, 402), (1, 102), (1, 101);
+insert into t3 values (11, 100), (33, 301), (44, 402), (11, 102), (11, 101);
+insert into t3 values (22, 100), (53, 301), (64, 402), (22, 102), (22, 101);
analyze table t1,t2,t3;
Table Op Msg_type Msg_text
test.t1 analyze status OK
@@ -1539,3 +1541,112 @@ GROUP BY t2.f1, t2.f2;
f1 f1 f2
DROP TABLE t1,t2;
End of 5.1 tests
+#
+# LP bug #813447: LEFT JOIN with single-row inner table and
+# a subquery in ON expression
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (0);
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (0), (0);
+SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3);
+a
+NULL
+EXPLAIN EXTENDED
+SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 100.00 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on(<in_optimizer>(6,<exists>(select `test`.`t3`.`a` from `test`.`t3` where (6 = `test`.`t3`.`a`)))) where 1
+DROP TABLE t1,t2,t3;
+#
+# LP bug #817384 Wrong result with outer join + subquery in ON
+# clause +unique key
+#
+CREATE TABLE t1 ( c int NOT NULL , b char(1) NOT NULL ) ;
+INSERT INTO t1 VALUES (1,'b');
+CREATE TABLE t2 ( a int NOT NULL , b char(1) NOT NULL , PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (1,'a');
+create table t3 (c1 char(1), c2 char(2));
+insert into t3 values ('c','d');
+insert into t3 values ('c','d');
+EXPLAIN SELECT t2.b
+FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b
+FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3);
+b
+NULL
+EXPLAIN SELECT t2.b
+FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 const PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b
+FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1;
+b
+NULL
+DROP TABLE t1,t2,t3;
+#
+# LP bug #825035: second execution of PS with outer join
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+CREATE TABLE t2 (a int);
+PREPARE stmt FROM
+"SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a";
+EXECUTE stmt;
+a a
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+EXECUTE stmt;
+a a
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1,t2;
+#
+# LP bug #838633: second execution of PS with outer join
+# converted to inner join
+#
+CREATE TABLE t1 ( b int NOT NULL ) ;
+INSERT INTO t1 VALUES (9),(10);
+CREATE TABLE t2 ( b int NOT NULL, PRIMARY KEY (b)) ;
+INSERT INTO t2 VALUES
+(75),(76),(77),(78),(79),(80),(81),(82),(83),(84),(85),(86),(87),(88),(89),
+(10), (90),(91),(92),(93),(94),(95),(96),(97),(98),(99),(100);
+CREATE TABLE t3 ( a int, b int NOT NULL , PRIMARY KEY (b)) ;
+INSERT INTO t3 VALUES
+(0,6),(0,7),(0,8),(2,9),(0,10),(2,21),(0,22),(2,23),(2,24),(2,25);
+SET SESSION join_cache_level=4;
+EXPLAIN EXTENDED
+SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t3 hash_ALL PRIMARY #hash#PRIMARY 4 test.t1.b 10 10.00 Using join buffer (flat, BNLH join)
+1 SIMPLE t2 hash_index PRIMARY #hash#PRIMARY:PRIMARY 4:4 test.t1.b 27 3.70 Using join buffer (incremental, BNLH join)
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t2` join `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t1`.`b`))
+PREPARE stmt FROM
+'SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b';
+EXECUTE stmt;
+b b a b
+10 10 0 10
+EXECUTE stmt;
+b b a b
+10 10 0 10
+DEALLOCATE PREPARE stmt;
+SET SESSION join_cache_level=default;
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result
index eb04e7170a7..11b5edf5a13 100644
--- a/mysql-test/r/join_outer_jcl6.result
+++ b/mysql-test/r/join_outer_jcl6.result
@@ -1,6 +1,8 @@
set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set join_cache_level=6;
show variables like 'join_cache_level';
Variable_name Value
@@ -1385,7 +1387,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE jt5 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (incremental, BNL join)
1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (incremental, BNL join)
Warnings:
-Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt1` left join (`test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1))) on(1) where 1
+Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt1` left join (`test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on(((`test`.`jt6`.`f1` <> 0) and 1))) on(1) where 1
EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1
RIGHT JOIN t1 AS jt2
RIGHT JOIN t1 AS jt3
@@ -1402,7 +1404,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (incremental, BNL join)
1 SIMPLE jt1 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index; Using join buffer (incremental, BNL join)
Warnings:
-Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on((`test`.`jt6`.`f1` and 1)) left join `test`.`t1` `jt1` on(1) where 1
+Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on(((`test`.`jt6`.`f1` <> 0) and 1)) left join `test`.`t1` `jt1` on(1) where 1
DROP TABLE t1;
#
# Bug#49600: outer join of two single-row tables with joining attributes
@@ -1485,6 +1487,8 @@ create table t2 like t1;
insert into t2 select if(t1.a is null, 10, t1.a) from t1;
create table t3 (a int, b int, index idx(a));
insert into t3 values (1, 100), (3, 301), (4, 402), (1, 102), (1, 101);
+insert into t3 values (11, 100), (33, 301), (44, 402), (11, 102), (11, 101);
+insert into t3 values (22, 100), (53, 301), (64, 402), (22, 102), (22, 101);
analyze table t1,t2,t3;
Table Op Msg_type Msg_text
test.t1 analyze status OK
@@ -1546,6 +1550,115 @@ GROUP BY t2.f1, t2.f2;
f1 f1 f2
DROP TABLE t1,t2;
End of 5.1 tests
+#
+# LP bug #813447: LEFT JOIN with single-row inner table and
+# a subquery in ON expression
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (0);
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (0), (0);
+SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3);
+a
+NULL
+EXPLAIN EXTENDED
+SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 100.00 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on(<in_optimizer>(6,<exists>(select `test`.`t3`.`a` from `test`.`t3` where (6 = `test`.`t3`.`a`)))) where 1
+DROP TABLE t1,t2,t3;
+#
+# LP bug #817384 Wrong result with outer join + subquery in ON
+# clause +unique key
+#
+CREATE TABLE t1 ( c int NOT NULL , b char(1) NOT NULL ) ;
+INSERT INTO t1 VALUES (1,'b');
+CREATE TABLE t2 ( a int NOT NULL , b char(1) NOT NULL , PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (1,'a');
+create table t3 (c1 char(1), c2 char(2));
+insert into t3 values ('c','d');
+insert into t3 values ('c','d');
+EXPLAIN SELECT t2.b
+FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b
+FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3);
+b
+NULL
+EXPLAIN SELECT t2.b
+FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 const PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b
+FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1;
+b
+NULL
+DROP TABLE t1,t2,t3;
+#
+# LP bug #825035: second execution of PS with outer join
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+CREATE TABLE t2 (a int);
+PREPARE stmt FROM
+"SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a";
+EXECUTE stmt;
+a a
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+EXECUTE stmt;
+a a
+1 NULL
+2 NULL
+3 NULL
+4 NULL
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1,t2;
+#
+# LP bug #838633: second execution of PS with outer join
+# converted to inner join
+#
+CREATE TABLE t1 ( b int NOT NULL ) ;
+INSERT INTO t1 VALUES (9),(10);
+CREATE TABLE t2 ( b int NOT NULL, PRIMARY KEY (b)) ;
+INSERT INTO t2 VALUES
+(75),(76),(77),(78),(79),(80),(81),(82),(83),(84),(85),(86),(87),(88),(89),
+(10), (90),(91),(92),(93),(94),(95),(96),(97),(98),(99),(100);
+CREATE TABLE t3 ( a int, b int NOT NULL , PRIMARY KEY (b)) ;
+INSERT INTO t3 VALUES
+(0,6),(0,7),(0,8),(2,9),(0,10),(2,21),(0,22),(2,23),(2,24),(2,25);
+SET SESSION join_cache_level=4;
+EXPLAIN EXTENDED
+SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t3 hash_ALL PRIMARY #hash#PRIMARY 4 test.t1.b 10 10.00 Using join buffer (flat, BNLH join)
+1 SIMPLE t2 hash_index PRIMARY #hash#PRIMARY:PRIMARY 4:4 test.t1.b 27 3.70 Using join buffer (incremental, BNLH join)
+Warnings:
+Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t2` join `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`b` = `test`.`t1`.`b`))
+PREPARE stmt FROM
+'SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b';
+EXECUTE stmt;
+b b a b
+10 10 0 10
+EXECUTE stmt;
+b b a b
+10 10 0 10
+DEALLOCATE PREPARE stmt;
+SET SESSION join_cache_level=default;
+DROP TABLE t1,t2,t3;
set join_cache_level=default;
show variables like 'join_cache_level';
Variable_name Value
diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result
index 162a0d47c27..97bb066a32e 100644
--- a/mysql-test/r/key_cache.result
+++ b/mysql-test/r/key_cache.result
@@ -628,7 +628,7 @@ select p from t1 where p between 1010 and 1020;
p
explain select i from t2 where p between 1010 and 1020;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 28 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 28 Using where
select i from t2 where p between 1010 and 1020;
i
1
diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result
index 8b6830d4798..fa6b90ea891 100644
--- a/mysql-test/r/kill.result
+++ b/mysql-test/r/kill.result
@@ -125,6 +125,7 @@ release_lock("lock27563")
drop table t1, t2;
drop function bug27563;
drop procedure proc27563;
+set session optimizer_search_depth=0;
PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40 WHERE a1=a2 AND a2=a3 AND a3=a4 AND a4=a5 AND a5=a6 AND a6=a7 AND a7=a8 AND a8=a9 AND a9=a10 AND a10=a11 AND a11=a12 AND a12=a13 AND a13=a14 AND a14=a15 AND a15=a16 AND a16=a17 AND a17=a18 AND a18=a19 AND a19=a20 AND a20=a21 AND a21=a22 AND a22=a23 AND a23=a24 AND a24=a25 AND a25=a26 AND a26=a27 AND a27=a28 AND a28=a29 AND a29=a30 AND a30=a31 AND a31=a32 AND a32=a33 AND a33=a34 AND a34=a35 AND a35=a36 AND a36=a37 AND a37=a38 AND a38=a39 AND a39=a40 ';
EXECUTE stmt;
#
@@ -138,4 +139,27 @@ KILL CONNECTION_ID();
# of close of the connection socket
SELECT 1;
Got one of the listed errors
+#
+# Test kill USER
+#
+grant ALL on test.* to test@localhost;
+grant ALL on test.* to test2@localhost;
+kill hard query user test2@nohost;
+affected rows: 0
+kill soft query user test@localhost;
+affected rows: 1
+kill hard query user test@localhost;
+affected rows: 1
+kill soft connection user test2;
+affected rows: 1
+kill hard connection user test@localhost;
+affected rows: 1
+revoke all privileges on test.* from test@localhost;
+revoke all privileges on test.* from test2@localhost;
+drop user test@localhost;
+drop user test2@localhost;
+select 1;
+Got one of the listed errors
+select 1;
+Got one of the listed errors
set @@global.concurrent_insert= @old_concurrent_insert;
diff --git a/mysql-test/r/maria_icp.result b/mysql-test/r/maria_icp.result
index 7db44c0028f..2d755daf0d6 100644
--- a/mysql-test/r/maria_icp.result
+++ b/mysql-test/r/maria_icp.result
@@ -1,5 +1,7 @@
set @save_storage_engine= @@storage_engine;
set storage_engine=Maria;
+set @maria_icp_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
#
# Bug#36981 - "innodb crash when selecting for update"
#
@@ -81,6 +83,150 @@ c1 c2 c3 c4
DROP TABLE t1;
#
+# Bug#43617 - Innodb returns wrong results with timestamp's range value
+# in IN clause
+# (Note: Fixed by patch for BUG#42580)
+#
+CREATE TABLE t1(
+c1 TIMESTAMP NOT NULL,
+c2 TIMESTAMP NULL,
+c3 DATE,
+c4 DATETIME,
+PRIMARY KEY(c1),
+UNIQUE INDEX(c2)
+);
+INSERT INTO t1 VALUES
+('0000-00-00 00:00:00','0000-00-00 00:00:00','2008-01-04','2008-01-05 00:00:00'),
+('1971-01-01 00:00:01','1980-01-01 00:00:01','2009-01-01','2009-01-02 00:00:00'),
+('1999-01-01 00:00:00','1999-01-01 00:00:00', NULL, NULL),
+('2007-05-23 09:15:28','2007-05-23 09:15:28','2007-05-24','2007-05-24 09:15:28'),
+('2007-05-27 00:00:00','2007-05-25 00:00:00','2007-05-26','2007-05-26 00:00:00'),
+('2008-01-01 00:00:00', NULL, '2008-01-02','2008-01-03 00:00:00'),
+('2009-01-29 11:11:27','2009-01-29 11:11:27','2009-01-29','2009-01-29 11:11:27'),
+('2038-01-09 03:14:07','2038-01-09 03:14:07','2009-01-05','2009-01-06 00:00:00');
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 LIMIT 2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC LIMIT 2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+DROP TABLE t1;
+#
+# BUG#43618: MyISAM&Maria returns wrong results with 'between'
+# on timestamp
+#
+CREATE TABLE t1(
+ts TIMESTAMP NOT NULL,
+c char NULL,
+PRIMARY KEY(ts)
+);
+INSERT INTO t1 VALUES
+('1971-01-01','a'),
+('2007-05-25','b'),
+('2008-01-01','c'),
+('2038-01-09','d');
+
+# Execute select with invalid timestamp, desc ordering
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+ts c
+2008-01-01 00:00:00 c
+2007-05-25 00:00:00 b
+
+# Should use index condition
+EXPLAIN
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using index condition
+
+DROP TABLE t1;
+#
+# BUG#49906: Assertion failed - Field_varstring::val_str in field.cc
+# (Note: Fixed by patch for LP BUG#625841)
+#
+CREATE TABLE t1 (
+f1 VARCHAR(1024),
+f2 VARCHAR(10),
+INDEX test_idx USING BTREE (f2,f1(5))
+);
+INSERT INTO t1 VALUES ('a','c'), ('b','d');
+SELECT f1
+FROM t1
+WHERE f2 LIKE 'd'
+ORDER BY f1;
+f1
+b
+DROP TABLE t1;
+#
+# Bug#52660 - "Perf. regr. using ICP for MyISAM on range queries on
+# an index containing TEXT"
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 SELECT A.a + 10*(B.a) FROM t1 A, t1 B;
+CREATE TABLE t3 (
+c1 TINYTEXT NOT NULL,
+i1 INT NOT NULL,
+KEY (c1(6),i1)
+);
+INSERT INTO t3 SELECT CONCAT('c-',1000+t2.a,'=w'), 1 FROM t2;
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range c1 c1 8 NULL 3 Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+c1
+c-1004=w
+c-1005=w
+c-1006=w
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range c1 c1 12 NULL 2 Using index condition; Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+c1
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 ALL c1 NULL NULL NULL 100 Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+c1
+c-1004=w
+c-1005=w
+c-1006=w
+DROP TABLE t1, t2, t3;
+#
# Bug#40992 - InnoDB: Crash when engine_condition_pushdown is on
#
CREATE TABLE t (
@@ -200,4 +346,366 @@ COUNT(*)
12
DROP PROCEDURE insert_data;
DROP TABLE t1, t2, t3;
+#
+# Bug#57372 "Multi-table updates and deletes fail when running with ICP
+# against InnoDB"
+#
+CREATE TABLE t1 (
+a INT KEY,
+b INT
+);
+CREATE TABLE t2 (
+a INT KEY,
+b INT
+);
+INSERT INTO t1 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105);
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+UPDATE t1, t2
+SET t1.a = t1.a + 100, t2.b = t1.a + 10
+WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b - 100;
+SELECT * FROM t1;
+a b
+1 101
+102 102
+103 103
+104 104
+5 105
+SELECT * FROM t2;
+a b
+1 1
+2 12
+3 13
+4 14
+5 5
+DROP TABLE t1, t2;
+#
+# Bug#52605 - "Adding LIMIT 1 clause to query with complex range
+# predicate causes wrong results"
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT,
+PRIMARY KEY (pk),
+KEY k1 (c1)
+);
+INSERT INTO t1 VALUES (1,NULL);
+INSERT INTO t1 VALUES (2,6);
+INSERT INTO t1 VALUES (3,NULL);
+INSERT INTO t1 VALUES (4,6);
+INSERT INTO t1 VALUES (5,NULL);
+INSERT INTO t1 VALUES (6,NULL);
+INSERT INTO t1 VALUES (7,9);
+INSERT INTO t1 VALUES (8,0);
+SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+pk c1
+4 6
+EXPLAIN SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,k1 k1 5 NULL 4 Using where
+DROP TABLE t1;
+#
+# Bug#59259 "Incorrect rows returned for a correlated subquery
+# when ICP is on"
+#
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+Warnings:
+Warning 1286 Unknown table engine 'InnoDB'
+Warning 1266 Using storage engine Aria for table 't1'
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+Warnings:
+Warning 1286 Unknown table engine 'InnoDB'
+Warning 1266 Using storage engine Aria for table 't2'
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using index
+2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index condition
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+pk i
+12 5
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1, t2;
+#
+# Bug #58816 "Extra temporary duplicate rows in result set when
+# switching ICP off"
+#
+set @save_optimizer_switch= @@optimizer_switch;
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1);
+EXPLAIN SELECT pk, c1 FROM t1 WHERE pk <> 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 5 Using where
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT pk, c1 FROM t1 WHERE pk <> 3;
+pk c1
+1 9
+2 7
+4 3
+5 1
+DROP TABLE t1;
+set optimizer_switch= @save_optimizer_switch;
+#
+# Bug#58837: ICP crash or valgrind error due to uninitialized
+# value in innobase_index_cond
+#
+CREATE TABLE t1 (
+t1_int INT,
+t1_time TIME
+);
+CREATE TABLE t2 (
+t2_int int PRIMARY KEY,
+t2_int2 INT
+);
+INSERT INTO t2 VALUES ();
+INSERT INTO t1 VALUES ();
+SELECT * FROM t1 AS t1a
+WHERE NOT EXISTS (SELECT * FROM t1 AS t1b
+WHERE t1b.t1_int NOT IN
+(SELECT t2.t2_int FROM t2
+WHERE t1b.t1_time LIKE t1b.t1_int
+OR t1b.t1_time <> t2.t2_int2
+AND 6=7));
+t1_int t1_time
+DROP TABLE t1,t2;
+#
+# Bug#59186: Wrong results of join when ICP is enabled
+# (fixed by the patch for LP bug #694092)
+#
+CREATE TABLE t1 (
+pk INTEGER NOT NULL,
+c1 VARCHAR(3) NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'y'),(0,'or');
+CREATE TABLE t2 (
+pk INTEGER NOT NULL,
+c1 VARCHAR(3) NOT NULL,
+c2 VARCHAR(6) NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (6,'y','RPOYT'),(10,'m','JINQE');
+EXPLAIN
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+(t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNL join)
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+(t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+c2
+DROP TABLE t1, t2;
+#
+# Bug#58838: "Wrong results with HAVING + LIMIT without GROUP BY when
+# ICP is enabled".
+# (Fixed by the patches for LP bugs #668644, #702322)
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT,
+PRIMARY KEY (pk),
+KEY col_int_key (c1)
+);
+INSERT INTO t1 VALUES (1,37),(2,8),(3,-25),(4,NULL),(5,55);
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 0;
+pk
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 1;
+pk
+3
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 2;
+pk
+3
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 5;
+pk
+3
+DROP TABLE t1;
+#
+# Bug#59483 "Crash on INSERT/REPLACE in
+# rec_convert_dtuple_to_rec_comp with ICP on"
+#
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT PRIMARY KEY,
+i1 INTEGER,
+c1 CHAR(6),
+i2 INTEGER NOT NULL,
+KEY (i2)
+);
+INSERT INTO t1 VALUES
+(NULL, 4, 'that', 8),
+(NULL, 1, 'she', 6),
+(NULL, 6, 'tell', 2);
+SELECT * FROM t1 WHERE i2 IN (3, 6) LIMIT 2 FOR UPDATE;
+pk i1 c1 i2
+2 1 she 6
+INSERT INTO t1 (i2) VALUES (1);
+DROP TABLE t1;
+#
+# Bug #11766678 - 59843:
+# USING UNINITIALISED VALUE IN USES_INDEX_FIELDS_ONLY
+#
+CREATE TABLE t1 (
+col999 FLOAT NOT NULL,
+COL1000 VARBINARY(179) NOT NULL,
+col1003 DATE DEFAULT NULL,
+KEY idx4267 (col1000, col1003)
+);
+INSERT INTO t1 VALUES (),();
+Warnings:
+Warning 1364 Field 'col999' doesn't have a default value
+Warning 1364 Field 'COL1000' doesn't have a default value
+SELECT col999 FROM t1 WHERE col1000 = "3" AND col1003 <=> sysdate();
+col999
+DROP TABLE t1;
+#
+# BUG#12822678 - ICP WITH STRAIGHT_JOIN
+#
+CREATE TABLE t1 (
+i1 INTEGER NOT NULL,
+d1 DOUBLE,
+KEY k1 (d1)
+);
+INSERT INTO t1 VALUES (10,1), (17,NULL), (22,NULL);
+CREATE TABLE t2 (
+pk INTEGER NOT NULL,
+i1 INTEGER NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (4,1);
+EXPLAIN
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL k1 9 NULL 3 Using index
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using where
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+d1 pk i1
+1 4 1
+DROP TABLE t1, t2;
+#
+# BUG#778434 Wrong result with in_to_exists=on in maria-5.3-mwl89
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0);
+CREATE TABLE t2 ( f10 int) ;
+INSERT IGNORE INTO t2 VALUES (0);
+CREATE TABLE t3 ( f1 int NOT NULL , f10 int, PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES (6,0),(10,0);
+CREATE TABLE t4 ( f11 int) ;
+INSERT IGNORE INTO t4 VALUES
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(NULL),
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+set @tmp_778434=@@optimizer_switch;
+SET optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off,semijoin=off';
+SELECT * FROM t1 INNER JOIN t2 ON t2.f10 = t1.f11
+WHERE (6, 234) IN (
+SELECT t3.f1, t3.f1
+FROM t3 JOIN t4 ON t4.f11 = t3.f10
+);
+f11 f10
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch= @tmp_778434;
+#
+# Bug#885168: ICP for one index + potential ORDER BY for another
+#
+CREATE TABLE t1 (a varchar(64), b varchar(10), INDEX(a), INDEX(b)) ;
+INSERT INTO t1 VALUES
+('Ohio','Iowa'), ('k','d'), ('bdkpj','mbdkpjdanp'), ('d','xdmbdkpjda'),
+('fkxdmbdkpjdanpje','o'), ('f','Pennsylvan'), ('Virginia','ei');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range b b 13 NULL 2 Using where; Rowid-ordered scan; Using filesort
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+a b
+d xdmbdkpjda
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range b b 13 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using filesort
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+a b
+d xdmbdkpjda
+DROP TABLE t1;
+#
+# Bug#886145: join with ICP + ORDER BY
+#
+CREATE TABLE t1 (b int NOT NULL, c int, a varchar(1024), PRIMARY KEY (b));
+INSERT INTO t1 VALUES (1,4,'Ill');
+CREATE TABLE t2 (a varchar(1024), KEY (a(512)));
+INSERT INTO t2 VALUES
+('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t2 ref a a 515 const 1 Using where
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+b c
+1 4
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t2 ref a a 515 const 1 Using where
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+b c
+1 4
+DROP TABLE t1,t2;
+#
+# Bug#879871: InnoDB: possible ICP + GROUP BY primary index
+#
+CREATE TABLE t1 (
+a int NOT NULL, b int, c varchar(1), d varchar(1),
+PRIMARY KEY (a), KEY c (c,b)
+);
+INSERT INTO t1 VALUES (10,8,'g','g');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+a
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+a
+DROP TABLE t1;
set storage_engine= @save_storage_engine;
+set optimizer_switch=@maria_icp_tmp;
diff --git a/mysql-test/r/maria_mrr.result b/mysql-test/r/maria_mrr.result
index 667f49177c3..652bea93e7a 100644
--- a/mysql-test/r/maria_mrr.result
+++ b/mysql-test/r/maria_mrr.result
@@ -1,4 +1,6 @@
drop table if exists t1,t2,t3,t4;
+set @maria_mrr_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set @mrr_buffer_size_save= @@mrr_buffer_size;
set @save_storage_engine= @@storage_engine;
set storage_engine=aria;
@@ -185,7 +187,7 @@ explain
select * from t4 where a IS NULL and b IS NULL and (c IS NULL or c='no-such-row1'
or c='no-such-row2');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 range idx1 idx1 29 NULL 16 Using index condition; Rowid-ordered scan
+1 SIMPLE t4 range idx1 idx1 29 NULL 16 Using index condition; Using where; Rowid-ordered scan
select * from t4 where a IS NULL and b IS NULL and (c IS NULL or c='no-such-row1'
or c='no-such-row2');
a b c filler
@@ -207,7 +209,7 @@ NULL NULL NULL NULL-1
explain
select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 range idx1 idx1 29 NULL 32 Using index condition; Rowid-ordered scan
+1 SIMPLE t4 range idx1 idx1 29 NULL 32 Using index condition; Using where; Rowid-ordered scan
select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
a b c filler
b-1 NULL c-1 NULL-15
@@ -342,7 +344,9 @@ pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
PRIMARY KEY (pk), INDEX idx (v, i)
) ENGINE=ARIA;
INSERT INTO t3 SELECT * FROM t1;
-INSERT INTO t3 VALUES (88, 442, 'y'), (99, 445, 'w') ;
+INSERT INTO t3 VALUES
+(88, 442, 'y'), (99, 445, 'w'), (87, 442, 'z'), (98, 445, 'v'), (86, 442, 'x'),
+(97, 445, 't'), (85, 442, 'b'), (96, 445, 'l'), (84, 442, 'a'), (95, 445, 'k');
SELECT COUNT(t1.v) FROM t1, t2 IGNORE INDEX (idx), t3 IGNORE INDEX (idx)
WHERE t3.v = t2.v AND t3.i < t2.i AND t3.pk > 0 AND t2.pk > 0;
COUNT(t1.v)
@@ -353,7 +357,7 @@ WHERE t3.v = t2.v AND t3.i < t2.i AND t3.pk > 0 AND t2.pk > 0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL idx 7 NULL 15 Using index
1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 16 Using where; Using join buffer (flat, BNL join)
-1 SIMPLE t3 ALL PRIMARY NULL NULL NULL 17 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL PRIMARY NULL NULL NULL 25 Using where; Using join buffer (flat, BNL join)
SELECT COUNT(t1.v) FROM t1, t2, t3
WHERE t3.v = t2.v AND t3.i < t2.i AND t3.pk > 0 AND t2.pk > 0;
COUNT(t1.v)
@@ -379,11 +383,8 @@ PRIMARY KEY (pk),
KEY col_varchar_1024_latin1_key (col_varchar_1024_latin1_key)
) ENGINE=Aria;
INSERT INTO t1 VALUES
-(1,'z'),
-(2,'abcdefjhjkl'),
-(3,'in'),
-(4,'abcdefjhjkl'),
-(6,'abcdefjhjkl');
+(1,'z'), (2,'abcdefjhjkl'), (3,'in'), (4,'abcdefjhjkl'), (6,'abcdefjhjkl'),
+(11,'zx'), (12,'abcdefjhjm'), (13,'jn'), (14,'abcdefjhjp'), (16,'abcdefjhjr');
CREATE TABLE t2 (
col_varchar_10_latin1 varchar(10) DEFAULT NULL
) ENGINE=Aria;
@@ -426,4 +427,5 @@ alias2.f3 < 0;
f2 f3 f4 f5 f2
set join_cache_level=@_save_join_cache_level;
set join_buffer_size=@_save_join_buffer_size;
+set optimizer_switch=@maria_mrr_tmp;
drop table t1;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index a575242db2f..289be98c1b5 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -673,7 +673,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT * FROM t1 WHERE fileset_id = 2
AND file_code BETWEEN '0000000115' AND '0000000120' LIMIT 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,files PRIMARY 35 NULL 5 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY,files PRIMARY 35 NULL 5 Using where
EXPLAIN SELECT * FROM t2 WHERE fileset_id = 2
AND file_code = '0000000115' LIMIT 1;
id select_type table type possible_keys key key_len ref rows Extra
diff --git a/mysql-test/r/mix2_myisam.result b/mysql-test/r/mix2_myisam.result
index 4172226b986..e0a3d1af089 100644
--- a/mysql-test/r/mix2_myisam.result
+++ b/mysql-test/r/mix2_myisam.result
@@ -1114,11 +1114,11 @@ count(*)
29267
explain select * from t1 where c between 1 and 2500;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 5 NULL # Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c c 5 NULL # Using where
update t1 set c=a;
explain select * from t1 where c between 1 and 2500;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 5 NULL # Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c c 5 NULL # Using where
drop table t1,t2;
create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) engine=MyISAM;
insert into t1 (id) values (null),(null),(null),(null),(null);
@@ -1559,7 +1559,7 @@ qq
*a *a*a *
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v,v_2 # 13 const # Using index condition
+1 SIMPLE t1 ref v,v_2 # 13 const # Using where
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
@@ -1735,7 +1735,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v v 303 const # Using index condition
+1 SIMPLE t1 ref v v 303 const # Using where
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
diff --git a/mysql-test/r/mrr_icp_extra.result b/mysql-test/r/mrr_icp_extra.result
new file mode 100644
index 00000000000..bf45702fcc0
--- /dev/null
+++ b/mysql-test/r/mrr_icp_extra.result
@@ -0,0 +1,892 @@
+set @mrr_icp_extra_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+SET NAMES latin1;
+CREATE TABLE t1
+(s1 char(10) COLLATE latin1_german1_ci,
+s2 char(10) COLLATE latin1_swedish_ci,
+KEY(s1),
+KEY(s2));
+INSERT INTO t1 VALUES ('a','a');
+INSERT INTO t1 VALUES ('b','b');
+INSERT INTO t1 VALUES ('c','c');
+INSERT INTO t1 VALUES ('d','d');
+INSERT INTO t1 VALUES ('e','e');
+INSERT INTO t1 VALUES ('f','f');
+INSERT INTO t1 VALUES ('g','g');
+INSERT INTO t1 VALUES ('h','h');
+INSERT INTO t1 VALUES ('i','i');
+INSERT INTO t1 VALUES ('j','j');
+EXPLAIN SELECT * FROM t1 WHERE s1='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref s1 s1 11 const 1 Using index condition
+EXPLAIN SELECT * FROM t1 WHERE s2='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref s2 s2 11 const 1 Using index condition
+EXPLAIN SELECT * FROM t1 WHERE s1='a' COLLATE latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref s1 s1 11 const 1 Using index condition
+EXPLAIN SELECT * FROM t1 WHERE s2='a' COLLATE latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
+EXPLAIN SELECT * FROM t1 WHERE s1 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range s1 s1 11 NULL 2 Using index condition; Rowid-ordered scan
+EXPLAIN SELECT * FROM t1 WHERE s2 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
+EXPLAIN SELECT * FROM t1 WHERE s1 IN ('a','b' COLLATE latin1_german1_ci);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range s1 s1 11 NULL 2 Using index condition; Rowid-ordered scan
+EXPLAIN SELECT * FROM t1 WHERE s2 IN ('a','b' COLLATE latin1_german1_ci);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
+EXPLAIN SELECT * FROM t1 WHERE s1 LIKE 'a' COLLATE latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range s1 s1 11 NULL 1 Using index condition; Rowid-ordered scan
+EXPLAIN SELECT * FROM t1 WHERE s2 LIKE 'a' COLLATE latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL s2 NULL NULL NULL 10 Using where
+DROP TABLE t1;
+#
+#
+CREATE TABLE t2 (a varchar(32), b int(11), c float, d double,
+UNIQUE KEY a (a,b,c), KEY b (b), KEY c (c));
+CREATE TABLE t1 (a varchar(32), b char(3), UNIQUE KEY a (a,b), KEY b (b));
+CREATE TABLE t3 (a varchar(32), b char(3), UNIQUE KEY a (a,b));
+INSERT INTO t3 SELECT * FROM t1;
+EXPLAIN
+SELECT d FROM t1, t2
+WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
+ORDER BY t2.c LIMIT 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT d FROM t1, t2
+WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
+ORDER BY t2.c LIMIT 1;
+d
+DROP TABLE t1,t2,t3;
+#
+#
+create table t1(a int, b int, index(b));
+insert into t1 values (2, 1), (1, 1), (4, NULL), (3, NULL), (6, 2), (5, 2);
+insert into t1 values (2, 11), (1, 11), (4, 14), (3, 14), (6, 12), (5, 12);
+explain select * from t1 where b=1 or b is null order by a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref_or_null b b 5 const 4 Using index condition; Using where; Using filesort
+select * from t1 where b=1 or b is null order by a;
+a b
+1 1
+2 1
+3 NULL
+4 NULL
+explain select * from t1 where b=2 or b is null order by a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref_or_null b b 5 const 3 Using index condition; Using where; Using filesort
+select * from t1 where b=2 or b is null order by a;
+a b
+3 NULL
+4 NULL
+5 2
+6 2
+drop table t1;
+#
+#
+CREATE TABLE t1 (
+FieldKey varchar(36) NOT NULL default '',
+LongVal bigint(20) default NULL,
+StringVal mediumtext,
+KEY FieldKey (FieldKey),
+KEY LongField (FieldKey,LongVal),
+KEY StringField (FieldKey,StringVal(32))
+);
+INSERT INTO t1 VALUES ('0',3,'0'),('0',2,'1'),('0',1,'2'),('1',2,'1'),('1',1,'3'), ('1',0,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('3',2,'1'),('3',1,'2'),('3','3','3');
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (LongField, StringField) WHERE FieldKey > '2' ORDER BY LongVal;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range FieldKey FieldKey 38 NULL 4 Using index condition; Rowid-ordered scan; Using filesort
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range StringField StringField 38 NULL 4 Using index condition; Using filesort
+SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
+FieldKey LongVal StringVal
+3 1 2
+3 2 1
+3 3 3
+DROP TABLE t1;
+#
+#
+CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
+INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
+INSERT into t2 values (1,1,1), (2,2,2);
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+explain select * from t1 force index (a) where a=0 or a=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 4 NULL 4 Using index condition; Using where; Rowid-ordered scan
+select * from t1 force index (a) where a=0 or a=2;
+a b c
+0 NULL 0
+0 NULL 1
+0 NULL 2
+0 NULL 3
+drop table t1;
+#
+#
+create table t1
+(
+pk1 int not null,
+pk2 int not null,
+key1 int not null,
+key2 int not null,
+pktail1ok int not null,
+pktail2ok int not null,
+pktail3bad int not null,
+pktail4bad int not null,
+pktail5bad int not null,
+pk2copy int not null,
+badkey int not null,
+filler1 char (200),
+filler2 char (200),
+key (key1),
+key (key2),
+/* keys with tails from CPK members */
+key (pktail1ok, pk1),
+key (pktail2ok, pk1, pk2),
+key (pktail3bad, pk2, pk1),
+key (pktail4bad, pk1, pk2copy),
+key (pktail5bad, pk1, pk2, pk2copy),
+primary key (pk1, pk2)
+);
+explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 7 Using index condition; Using where; Rowid-ordered scan
+select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
+pk1 pk2 key1 key2 pktail1ok pktail2ok pktail3bad pktail4bad pktail5bad pk2copy badkey filler1 filler2
+1 19 0 0 0 0 0 0 0 19 0 filler-data-19 filler2
+1 18 0 0 0 0 0 0 0 18 0 filler-data-18 filler2
+1 17 0 0 0 0 0 0 0 17 0 filler-data-17 filler2
+1 16 0 0 0 0 0 0 0 16 0 filler-data-16 filler2
+1 15 0 0 0 0 0 0 0 15 0 filler-data-15 filler2
+1 14 0 0 0 0 0 0 0 14 0 filler-data-14 filler2
+1 13 0 0 0 0 0 0 0 13 0 filler-data-13 filler2
+1 12 0 0 0 0 0 0 0 12 0 filler-data-12 filler2
+1 11 0 0 0 0 0 0 0 11 0 filler-data-11 filler2
+1 10 0 0 0 0 0 0 0 10 0 filler-data-10 filler2
+drop table t1;
+#
+#
+CREATE TABLE t1 (
+f1 int,
+f4 varchar(32),
+f5 int,
+PRIMARY KEY (f1),
+KEY (f4)
+);
+INSERT INTO t1 VALUES
+(5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6),
+(530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1),
+(535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2),
+(540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0),
+(956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0),
+(961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL),
+(966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0),
+(971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0),
+(976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7),
+(981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1),
+(986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7),
+(991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4),
+(996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2);
+EXPLAIN
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,f4 f4 35 NULL 5 Using index condition; Using where; Rowid-ordered scan
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+f1 f4 f5
+994 r 2
+996 A 2
+998 a 0
+drop table t1;
+#
+#
+drop table if exists t1,t2,t3;
+--- Testing varchar ---
+--- Testing varchar ---
+create table t1 (v varchar(10), c char(10), t text);
+insert into t1 values('+ ', '+ ', '+ ');
+set @a=repeat(' ',20);
+insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
+Warnings:
+Note 1265 Data truncated for column 'v' at row 1
+select concat('*',v,'*',c,'*',t,'*') from t1;
+concat('*',v,'*',c,'*',t,'*')
+*+ *+*+ *
+*+ *+*+ *
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+create table t2 like t1;
+show create table t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+create table t3 select * from t1;
+show create table t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t1 modify c varchar(10);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` varchar(10) DEFAULT NULL,
+ `t` text
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t1 modify v char(10);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` char(10) DEFAULT NULL,
+ `c` varchar(10) DEFAULT NULL,
+ `t` text
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+alter table t1 modify t varchar(10);
+Warnings:
+Note 1265 Data truncated for column 't' at row 2
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` char(10) DEFAULT NULL,
+ `c` varchar(10) DEFAULT NULL,
+ `t` varchar(10) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select concat('*',v,'*',c,'*',t,'*') from t1;
+concat('*',v,'*',c,'*',t,'*')
+*+*+*+ *
+*+*+*+ *
+drop table t1,t2,t3;
+create table t1 (v varchar(10), c char(10), t text, key(v), key(c), key(t(10)));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `v` (`v`),
+ KEY `c` (`c`),
+ KEY `t` (`t`(10))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select count(*) from t1;
+count(*)
+270
+insert into t1 values(concat('a',char(1)),concat('a',char(1)),concat('a',char(1)));
+select count(*) from t1 where v='a';
+count(*)
+10
+select count(*) from t1 where c='a';
+count(*)
+10
+select count(*) from t1 where t='a';
+count(*)
+10
+select count(*) from t1 where v='a ';
+count(*)
+10
+select count(*) from t1 where c='a ';
+count(*)
+10
+select count(*) from t1 where t='a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+count(*)
+10
+select count(*) from t1 where v like 'a%';
+count(*)
+11
+select count(*) from t1 where c like 'a%';
+count(*)
+11
+select count(*) from t1 where t like 'a%';
+count(*)
+11
+select count(*) from t1 where v like 'a %';
+count(*)
+9
+explain select count(*) from t1 where v='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
+explain select count(*) from t1 where c='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref c c 11 const # Using where; Using index
+explain select count(*) from t1 where t='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref t t 13 const # Using where
+explain select count(*) from t1 where v like 'a%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range v v 13 NULL # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 13 const # Using where; Using index
+alter table t1 add unique(v);
+ERROR 23000: Duplicate entry '{ ' for key 'v_2'
+alter table t1 add key(v);
+select concat('*',v,'*',c,'*',t,'*') as qq from t1 where v='a';
+qq
+*a*a*a*
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+*a *a*a *
+explain select * from t1 where v='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v,v_2 # 13 const # Using index condition
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(c) from t1 group by v limit 10;
+v count(c)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(c) from t1 group by v limit 10;
+v count(c)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select c,count(*) from t1 group by c limit 10;
+c count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select c,count(t) from t1 group by c limit 10;
+c count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result c,count(t) from t1 group by c limit 10;
+c count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select t,count(*) from t1 group by t limit 10;
+t count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select t,count(t) from t1 group by t limit 10;
+t count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result t,count(t) from t1 group by t limit 10;
+t count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+alter table t1 modify v varchar(300), drop key v, drop key v_2, add key v (v);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(300) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `c` (`c`),
+ KEY `t` (`t`(10)),
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select count(*) from t1 where v='a';
+count(*)
+10
+select count(*) from t1 where v='a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+count(*)
+10
+select count(*) from t1 where v like 'a%';
+count(*)
+11
+select count(*) from t1 where v like 'a %';
+count(*)
+9
+explain select count(*) from t1 where v='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
+explain select count(*) from t1 where v like 'a%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range v v 303 NULL # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
+explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using where; Using index
+explain select * from t1 where v='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 303 const # Using index condition
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+alter table t1 drop key v, add key v (v(30));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(300) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `c` (`c`),
+ KEY `t` (`t`(10)),
+ KEY `v` (`v`(30))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select count(*) from t1 where v='a';
+count(*)
+10
+select count(*) from t1 where v='a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ';
+count(*)
+10
+select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+count(*)
+10
+select count(*) from t1 where v like 'a%';
+count(*)
+11
+select count(*) from t1 where v like 'a %';
+count(*)
+9
+explain select count(*) from t1 where v='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+explain select count(*) from t1 where v like 'a%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range v v 33 NULL # Using where
+explain select count(*) from t1 where v between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+explain select count(*) from t1 where v between 'a' and 'a ' and v between 'a ' and 'b\n';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+explain select * from t1 where v='a';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref v v 33 const # Using where
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+alter table t1 modify v varchar(600), drop key v, add key v (v);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(600) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `c` (`c`),
+ KEY `t` (`t`(10)),
+ KEY `v` (`v`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select v,count(*) from t1 group by v limit 10;
+v count(*)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+select sql_big_result v,count(t) from t1 group by v limit 10;
+v count(t)
+a 1
+a 10
+b 10
+c 10
+d 10
+e 10
+f 10
+g 10
+h 10
+i 10
+drop table t1;
+create table t1 (a char(10), unique (a));
+insert into t1 values ('a ');
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a' for key 'a'
+alter table t1 modify a varchar(10);
+insert into t1 values ('a '),('a '),('a '),('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+insert into t1 values ('a ');
+ERROR 23000: Duplicate entry 'a ' for key 'a'
+update t1 set a='a ' where a like 'a%';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+update t1 set a='abc ' where a like 'a ';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+update t1 set a='a ' where a like 'a %';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+update t1 set a='a ' where a like 'a ';
+select concat(a,'.') from t1;
+concat(a,'.')
+a .
+drop table t1;
+create table t1 (v varchar(10), c char(10), t text, key(v(5)), key(c(5)), key(t(5)));
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL,
+ `t` text,
+ KEY `v` (`v`(5)),
+ KEY `c` (`c`(5)),
+ KEY `t` (`t`(5))
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (v char(10) character set utf8);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` char(10) CHARACTER SET utf8 DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (v varchar(10), c char(10)) row_format=fixed;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `v` varchar(10) DEFAULT NULL,
+ `c` char(10) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 ROW_FORMAT=FIXED
+insert into t1 values('a','a'),('a ','a ');
+select concat('*',v,'*',c,'*') from t1;
+concat('*',v,'*',c,'*')
+*a*a*
+*a *a*
+drop table t1;
+create table t1 (v varchar(65530), key(v(10)));
+insert into t1 values(repeat('a',65530));
+select length(v) from t1 where v=repeat('a',65530);
+length(v)
+65530
+drop table t1;
+create table t1(a int, b varchar(12), key ba(b, a));
+insert into t1 values (1, 'A'), (20, NULL);
+explain select * from t1 where a=20 and b is null;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref ba ba 20 const,const 1 Using where; Using index
+select * from t1 where a=20 and b is null;
+a b
+20 NULL
+drop table t1;
+#
+#
+drop database if exists world;
+CREATE DATABASE world;
+use world;
+CREATE TABLE Country (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name)
+);
+CREATE TABLE City (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE CountryLanguage (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+ID Name Country Population
+637 Mit Ghamr EGY 101801
+707 Marbella ESP 101144
+3792 Tartu EST 101246
+4032 Cambridge USA 101355
+explain
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country Population 4 NULL # Using index condition; Using where; Rowid-ordered scan
+explain
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City index_merge Population,Country Country,Population 3,4 NULL # Using sort_union(Country,Population); Using where
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+ID Name Country Population
+65 Abu Dhabi ARE 398695
+168 Pabna BGD 103277
+189 Parakou BEN 103577
+750 Paarl ZAF 105768
+2865 Pak Pattan PAK 107800
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 7000000;
+ID Name Country Population
+1024 Mumbai (Bombay) IND 10500000
+3580 Moscow RUS 8389200
+explain
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 7000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population Population 4 NULL # Using index condition; Using where; Rowid-ordered scan
+explain
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country # # NULL # Using index condition; Using where; Rowid-ordered scan
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+ID Name Country Population
+1895 Harbin CHN 4289800
+1904 Jinan CHN 2278100
+1905 Hangzhou CHN 2190500
+1914 Guiyang CHN 1465200
+1916 Hefei CHN 1369100
+1923 Jilin CHN 1040000
+1927 Hohhot CHN 916700
+1928 Handan CHN 840000
+1937 Huainan CHN 700000
+1938 Jixi CHN 683885
+1944 Jinzhou CHN 570000
+1950 Hegang CHN 520000
+explain
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE City range Population,Country # # NULL # Using index condition; Using where; Rowid-ordered scan
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+ID Name Country Population
+1895 Harbin CHN 4289800
+1905 Hangzhou CHN 2190500
+1914 Guiyang CHN 1465200
+1916 Hefei CHN 1369100
+1927 Hohhot CHN 916700
+1928 Handan CHN 840000
+1937 Huainan CHN 700000
+1950 Hegang CHN 520000
+drop database world;
+use test;
+set @mrr_icp_extra_tmp=@@optimizer_switch;
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 49d8e2d576f..e02c57ee8b9 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -329,7 +329,7 @@ ALTER TABLE t1 ADD INDEX t1 (a, b, c, d, e);
ERROR 42000: Specified key was too long; max key length is 1000 bytes
DROP TABLE t1;
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
-INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+INSERT into t1 values (0,null,0), (0,null,1), (0,null,2), (0,null,3), (1,1,4);
create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
INSERT into t2 values (1,1,1), (2,2,2);
optimize table t1;
@@ -355,10 +355,34 @@ explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL a NULL NULL NULL 2
1 SIMPLE t1 ref a a 4 test.t2.a 3
+INSERT into t1 values (2,4,5), (7,8,4), (8,3,1), (9,7,2), (5,5,9);
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 b 1 b A 10 NULL NULL YES BTREE
+t1 1 c 1 c A 10 NULL NULL YES BTREE
+t1 1 a 1 a A 10 NULL NULL BTREE
+t1 1 a 2 b A 10 NULL NULL YES BTREE
+t1 1 c_2 1 c A 10 NULL NULL YES BTREE
+t1 1 c_2 2 a A 10 NULL NULL BTREE
explain select * from t1,t2 where t1.b=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL b NULL NULL NULL 2 Using where
1 SIMPLE t1 ref b b 5 test.t2.b 1
+delete from t1 where t1.a>1;
+optimize table t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+show index from t1;
+Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
+t1 1 b 1 b A 5 NULL NULL YES BTREE
+t1 1 c 1 c A 5 NULL NULL YES BTREE
+t1 1 a 1 a A 1 NULL NULL BTREE
+t1 1 a 2 b A 5 NULL NULL YES BTREE
+t1 1 c_2 1 c A 5 NULL NULL YES BTREE
+t1 1 c_2 2 a A 5 NULL NULL BTREE
explain select * from t1,t2 force index(c) where t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 2
@@ -368,7 +392,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where
explain select * from t1 force index (a) where a=0 or a=2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 4 NULL 4 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range a a 4 NULL 4 Using where
explain select * from t1 where c=1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref c,c_2 c 5 const 1
@@ -1230,7 +1254,7 @@ qq
*a *a*a *
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v,v_2 # 13 const # Using index condition
+1 SIMPLE t1 ref v,v_2 # 13 const # Using where
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
@@ -1406,7 +1430,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v v 303 const # Using index condition
+1 SIMPLE t1 ref v v 303 const # Using where
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
diff --git a/mysql-test/r/myisam_icp.result b/mysql-test/r/myisam_icp.result
index 45d45bd3452..b73e98e2aea 100644
--- a/mysql-test/r/myisam_icp.result
+++ b/mysql-test/r/myisam_icp.result
@@ -1,3 +1,5 @@
+set @myisam_icp_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
#
# Bug#36981 - "innodb crash when selecting for update"
#
@@ -79,6 +81,150 @@ c1 c2 c3 c4
DROP TABLE t1;
#
+# Bug#43617 - Innodb returns wrong results with timestamp's range value
+# in IN clause
+# (Note: Fixed by patch for BUG#42580)
+#
+CREATE TABLE t1(
+c1 TIMESTAMP NOT NULL,
+c2 TIMESTAMP NULL,
+c3 DATE,
+c4 DATETIME,
+PRIMARY KEY(c1),
+UNIQUE INDEX(c2)
+);
+INSERT INTO t1 VALUES
+('0000-00-00 00:00:00','0000-00-00 00:00:00','2008-01-04','2008-01-05 00:00:00'),
+('1971-01-01 00:00:01','1980-01-01 00:00:01','2009-01-01','2009-01-02 00:00:00'),
+('1999-01-01 00:00:00','1999-01-01 00:00:00', NULL, NULL),
+('2007-05-23 09:15:28','2007-05-23 09:15:28','2007-05-24','2007-05-24 09:15:28'),
+('2007-05-27 00:00:00','2007-05-25 00:00:00','2007-05-26','2007-05-26 00:00:00'),
+('2008-01-01 00:00:00', NULL, '2008-01-02','2008-01-03 00:00:00'),
+('2009-01-29 11:11:27','2009-01-29 11:11:27','2009-01-29','2009-01-29 11:11:27'),
+('2038-01-09 03:14:07','2038-01-09 03:14:07','2009-01-05','2009-01-06 00:00:00');
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 LIMIT 2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+SELECT *
+FROM t1
+WHERE c2 IN ('1971-01-01 00:00:01','2038-01-09 03:14:07')
+ORDER BY c2 DESC LIMIT 2;
+c1 c2 c3 c4
+2038-01-09 03:14:07 2038-01-09 03:14:07 2009-01-05 2009-01-06 00:00:00
+
+DROP TABLE t1;
+#
+# BUG#43618: MyISAM&Maria returns wrong results with 'between'
+# on timestamp
+#
+CREATE TABLE t1(
+ts TIMESTAMP NOT NULL,
+c char NULL,
+PRIMARY KEY(ts)
+);
+INSERT INTO t1 VALUES
+('1971-01-01','a'),
+('2007-05-25','b'),
+('2008-01-01','c'),
+('2038-01-09','d');
+
+# Execute select with invalid timestamp, desc ordering
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+ts c
+2008-01-01 00:00:00 c
+2007-05-25 00:00:00 b
+
+# Should use index condition
+EXPLAIN
+SELECT *
+FROM t1
+WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00'
+ORDER BY ts DESC
+LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using index condition
+
+DROP TABLE t1;
+#
+# BUG#49906: Assertion failed - Field_varstring::val_str in field.cc
+# (Note: Fixed by patch for LP BUG#625841)
+#
+CREATE TABLE t1 (
+f1 VARCHAR(1024),
+f2 VARCHAR(10),
+INDEX test_idx USING BTREE (f2,f1(5))
+);
+INSERT INTO t1 VALUES ('a','c'), ('b','d');
+SELECT f1
+FROM t1
+WHERE f2 LIKE 'd'
+ORDER BY f1;
+f1
+b
+DROP TABLE t1;
+#
+# Bug#52660 - "Perf. regr. using ICP for MyISAM on range queries on
+# an index containing TEXT"
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 SELECT A.a + 10*(B.a) FROM t1 A, t1 B;
+CREATE TABLE t3 (
+c1 TINYTEXT NOT NULL,
+i1 INT NOT NULL,
+KEY (c1(6),i1)
+);
+INSERT INTO t3 SELECT CONCAT('c-',1000+t2.a,'=w'), 1 FROM t2;
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range c1 c1 8 NULL 3 Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w';
+c1
+c-1004=w
+c-1005=w
+c-1006=w
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range c1 c1 12 NULL 2 Using index condition; Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' and i1 > 2;
+c1
+EXPLAIN
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 ALL c1 NULL NULL NULL 100 Using where
+SELECT c1 FROM t3 WHERE c1 >= 'c-1004=w' and c1 <= 'c-1006=w' or i1 > 2;
+c1
+c-1004=w
+c-1005=w
+c-1006=w
+DROP TABLE t1, t2, t3;
+#
# Bug#40992 - InnoDB: Crash when engine_condition_pushdown is on
#
CREATE TABLE t (
@@ -198,4 +344,432 @@ COUNT(*)
12
DROP PROCEDURE insert_data;
DROP TABLE t1, t2, t3;
+#
+# Bug#57372 "Multi-table updates and deletes fail when running with ICP
+# against InnoDB"
+#
+CREATE TABLE t1 (
+a INT KEY,
+b INT
+);
+CREATE TABLE t2 (
+a INT KEY,
+b INT
+);
+INSERT INTO t1 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105);
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
+UPDATE t1, t2
+SET t1.a = t1.a + 100, t2.b = t1.a + 10
+WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b - 100;
+SELECT * FROM t1;
+a b
+1 101
+102 102
+103 103
+104 104
+5 105
+SELECT * FROM t2;
+a b
+1 1
+2 12
+3 13
+4 14
+5 5
+DROP TABLE t1, t2;
+#
+# Bug#52605 - "Adding LIMIT 1 clause to query with complex range
+# predicate causes wrong results"
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT,
+PRIMARY KEY (pk),
+KEY k1 (c1)
+);
+INSERT INTO t1 VALUES (1,NULL);
+INSERT INTO t1 VALUES (2,6);
+INSERT INTO t1 VALUES (3,NULL);
+INSERT INTO t1 VALUES (4,6);
+INSERT INTO t1 VALUES (5,NULL);
+INSERT INTO t1 VALUES (6,NULL);
+INSERT INTO t1 VALUES (7,9);
+INSERT INTO t1 VALUES (8,0);
+SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+pk c1
+4 6
+EXPLAIN SELECT pk, c1
+FROM t1
+WHERE (pk BETWEEN 4 AND 5 OR pk < 2) AND c1 < 240
+ORDER BY c1
+LIMIT 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,k1 k1 5 NULL 4 Using where
+DROP TABLE t1;
+#
+# Bug#59259 "Incorrect rows returned for a correlated subquery
+# when ICP is on"
+#
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+Warnings:
+Warning 1286 Unknown table engine 'InnoDB'
+Warning 1266 Using storage engine MyISAM for table 't1'
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL) ENGINE=InnoDB;
+Warnings:
+Warning 1286 Unknown table engine 'InnoDB'
+Warning 1266 Using storage engine MyISAM for table 't2'
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+set @save_optimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using index
+2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index condition
+SELECT * FROM t1
+WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
+pk i
+12 5
+set optimizer_switch=@save_optimizer_switch;
+DROP TABLE t1, t2;
+#
+# Bug #58816 "Extra temporary duplicate rows in result set when
+# switching ICP off"
+#
+set @save_optimizer_switch= @@optimizer_switch;
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1);
+EXPLAIN SELECT pk, c1 FROM t1 WHERE pk <> 3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 5 Using where
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT pk, c1 FROM t1 WHERE pk <> 3;
+pk c1
+1 9
+2 7
+4 3
+5 1
+DROP TABLE t1;
+set optimizer_switch= @save_optimizer_switch;
+#
+# Bug#58837: ICP crash or valgrind error due to uninitialized
+# value in innobase_index_cond
+#
+CREATE TABLE t1 (
+t1_int INT,
+t1_time TIME
+);
+CREATE TABLE t2 (
+t2_int int PRIMARY KEY,
+t2_int2 INT
+);
+INSERT INTO t2 VALUES ();
+INSERT INTO t1 VALUES ();
+SELECT * FROM t1 AS t1a
+WHERE NOT EXISTS (SELECT * FROM t1 AS t1b
+WHERE t1b.t1_int NOT IN
+(SELECT t2.t2_int FROM t2
+WHERE t1b.t1_time LIKE t1b.t1_int
+OR t1b.t1_time <> t2.t2_int2
+AND 6=7));
+t1_int t1_time
+DROP TABLE t1,t2;
+#
+# Bug#59186: Wrong results of join when ICP is enabled
+# (fixed by the patch for LP bug #694092)
+#
+CREATE TABLE t1 (
+pk INTEGER NOT NULL,
+c1 VARCHAR(3) NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t1 VALUES (1,'y'),(0,'or');
+CREATE TABLE t2 (
+pk INTEGER NOT NULL,
+c1 VARCHAR(3) NOT NULL,
+c2 VARCHAR(6) NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (6,'y','RPOYT'),(10,'m','JINQE');
+EXPLAIN
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+(t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNL join)
+SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1
+WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR
+(t1.pk > 1 AND t2.pk BETWEEN 6 AND 6);
+c2
+DROP TABLE t1, t2;
+#
+# Bug#58838: "Wrong results with HAVING + LIMIT without GROUP BY when
+# ICP is enabled".
+# (Fixed by the patches for LP bugs #668644, #702322)
+#
+CREATE TABLE t1 (
+pk INT NOT NULL,
+c1 INT,
+PRIMARY KEY (pk),
+KEY col_int_key (c1)
+);
+INSERT INTO t1 VALUES (1,37),(2,8),(3,-25),(4,NULL),(5,55);
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 0;
+pk
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 1;
+pk
+3
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 2;
+pk
+3
+SELECT pk FROM t1 WHERE c1 <> 1 HAVING pk = 3 ORDER BY pk LIMIT 5;
+pk
+3
+DROP TABLE t1;
+#
+# Bug#59483 "Crash on INSERT/REPLACE in
+# rec_convert_dtuple_to_rec_comp with ICP on"
+#
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT PRIMARY KEY,
+i1 INTEGER,
+c1 CHAR(6),
+i2 INTEGER NOT NULL,
+KEY (i2)
+);
+INSERT INTO t1 VALUES
+(NULL, 4, 'that', 8),
+(NULL, 1, 'she', 6),
+(NULL, 6, 'tell', 2);
+SELECT * FROM t1 WHERE i2 IN (3, 6) LIMIT 2 FOR UPDATE;
+pk i1 c1 i2
+2 1 she 6
+INSERT INTO t1 (i2) VALUES (1);
+DROP TABLE t1;
+#
+# Bug #11766678 - 59843:
+# USING UNINITIALISED VALUE IN USES_INDEX_FIELDS_ONLY
+#
+CREATE TABLE t1 (
+col999 FLOAT NOT NULL,
+COL1000 VARBINARY(179) NOT NULL,
+col1003 DATE DEFAULT NULL,
+KEY idx4267 (col1000, col1003)
+);
+INSERT INTO t1 VALUES (),();
+Warnings:
+Warning 1364 Field 'col999' doesn't have a default value
+Warning 1364 Field 'COL1000' doesn't have a default value
+SELECT col999 FROM t1 WHERE col1000 = "3" AND col1003 <=> sysdate();
+col999
+DROP TABLE t1;
+#
+# BUG#12822678 - ICP WITH STRAIGHT_JOIN
+#
+CREATE TABLE t1 (
+i1 INTEGER NOT NULL,
+d1 DOUBLE,
+KEY k1 (d1)
+);
+INSERT INTO t1 VALUES (10,1), (17,NULL), (22,NULL);
+CREATE TABLE t2 (
+pk INTEGER NOT NULL,
+i1 INTEGER NOT NULL,
+PRIMARY KEY (pk)
+);
+INSERT INTO t2 VALUES (4,1);
+EXPLAIN
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL k1 9 NULL 3 Using index
+1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 Using where
+SELECT t1.d1, t2.pk, t2.i1 FROM t1 STRAIGHT_JOIN t2 ON t2.i1
+WHERE t2.pk <> t1.d1 AND t2.pk = 4;
+d1 pk i1
+1 4 1
+DROP TABLE t1, t2;
+#
+# BUG#778434 Wrong result with in_to_exists=on in maria-5.3-mwl89
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0);
+CREATE TABLE t2 ( f10 int) ;
+INSERT IGNORE INTO t2 VALUES (0);
+CREATE TABLE t3 ( f1 int NOT NULL , f10 int, PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES (6,0),(10,0);
+CREATE TABLE t4 ( f11 int) ;
+INSERT IGNORE INTO t4 VALUES
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(NULL),
+(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+set @tmp_778434=@@optimizer_switch;
+SET optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off,semijoin=off';
+SELECT * FROM t1 INNER JOIN t2 ON t2.f10 = t1.f11
+WHERE (6, 234) IN (
+SELECT t3.f1, t3.f1
+FROM t3 JOIN t4 ON t4.f11 = t3.f10
+);
+f11 f10
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch= @tmp_778434;
+#
+# Bug#885168: ICP for one index + potential ORDER BY for another
+#
+CREATE TABLE t1 (a varchar(64), b varchar(10), INDEX(a), INDEX(b)) ;
+INSERT INTO t1 VALUES
+('Ohio','Iowa'), ('k','d'), ('bdkpj','mbdkpjdanp'), ('d','xdmbdkpjda'),
+('fkxdmbdkpjdanpje','o'), ('f','Pennsylvan'), ('Virginia','ei');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range b b 13 NULL 2 Using where; Rowid-ordered scan; Using filesort
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+a b
+d xdmbdkpjda
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range b b 13 NULL 2 Using index condition; Using where; Rowid-ordered scan; Using filesort
+SELECT * FROM t1
+WHERE NOT(b = 'Texas') AND b BETWEEN 'wy' AND 'y' OR b = 'Pennsylvania'
+ ORDER BY a;
+a b
+d xdmbdkpjda
+DROP TABLE t1;
+#
+# Bug#886145: join with ICP + ORDER BY
+#
+CREATE TABLE t1 (b int NOT NULL, c int, a varchar(1024), PRIMARY KEY (b));
+INSERT INTO t1 VALUES (1,4,'Ill');
+CREATE TABLE t2 (a varchar(1024), KEY (a(512)));
+INSERT INTO t2 VALUES
+('Ill'), ('eckqzsflbzaffti'), ('w'), ('she'), ('gxbwypqtjzwywwer'), ('w');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t2 ref a a 515 const 1 Using where
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+b c
+1 4
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system PRIMARY NULL NULL NULL 1
+1 SIMPLE t2 ref a a 515 const 1 Using where
+SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0
+HAVING t1.c != 5 ORDER BY t1.c;
+b c
+1 4
+DROP TABLE t1,t2;
+#
+# Bug#879871: InnoDB: possible ICP + GROUP BY primary index
+#
+CREATE TABLE t1 (
+a int NOT NULL, b int, c varchar(1), d varchar(1),
+PRIMARY KEY (a), KEY c (c,b)
+);
+INSERT INTO t1 VALUES (10,8,'g','g');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+a
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+SELECT a FROM t1 WHERE c IS NULL AND d IS NOT NULL GROUP BY 1;
+a
+DROP TABLE t1;
drop table if exists t0, t1, t1i, t1m;
+#
+# BUG#826935 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed
+#
+CREATE TABLE t1 ( a int, b varchar(1024), c int, KEY (c), KEY (c,a)) ;
+INSERT INTO t1 VALUES
+(NULL,'x','-678428672'),
+(NULL,'ok',NULL),
+(796262400,'byluovkgwoukfxedyeffsedajyqkyhpaqqpozn', NULL),
+(7,'STQUF',146014208),
+(955711488,'WWVOR','-1515388928');
+SELECT b FROM t1 WHERE a != 1 AND c IS NULL ORDER BY 1;
+b
+byluovkgwoukfxedyeffsedajyqkyhpaqqpozn
+DROP TABLE t1;
+#
+# Bug#870046: ICP for a GROUP BY query
+#
+CREATE TABLE t1 (a int, b varchar(1), c varchar(1), INDEX idx(b));
+INSERT INTO t1 VALUES (2,'x','x'), (5,'x','y');
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx idx 4 const 1 Using where; Using temporary; Using filesort
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+a MIN(c)
+5 y
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref idx idx 4 const 1 Using index condition; Using where; Using temporary; Using filesort
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+a MIN(c)
+5 y
+DROP TABLE t1;
+#
+# BUG#887026: Wrong result with ICP, outer join, subquery in maria-5.3-icp
+#
+CREATE TABLE t1 (c varchar(1));
+INSERT INTO t1 VALUES ('c'), ('c');
+CREATE TABLE t2 (c varchar(1), b int);
+INSERT INTO t2 VALUES ('d', NULL),('d', NULL);
+CREATE TABLE t3 (c varchar(1));
+INSERT INTO t3 VALUES ('c');
+INSERT INTO t3 VALUES ('c');
+CREATE TABLE t4 ( b int, c varchar(1), KEY (b));
+INSERT INTO t4 VALUES (7,'c');
+INSERT INTO t4 VALUES (7,'c');
+# Must be t1,t2,t3,t4, with t4 having Full-scan-on-NULL but not Using index condition
+explain
+SELECT * FROM t1 LEFT JOIN t2 ON t1.c=t2.b
+WHERE
+t2.b NOT IN (SELECT t4.b FROM t3 STRAIGHT_JOIN t4 WHERE t4.b <= 2 AND t4.c = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY t4 ref_or_null b b 5 func 2 Using where; Full scan on NULL key
+SELECT * FROM t1 LEFT JOIN t2 ON t1.c=t2.b
+WHERE
+t2.b NOT IN (SELECT t4.b FROM t3 STRAIGHT_JOIN t4 WHERE t4.b <= 2 AND t4.c = t3.c);
+c c b
+c NULL NULL
+c NULL NULL
+DROP TABLE t1,t2,t3,t4;
+set optimizer_switch=@myisam_icp_tmp;
diff --git a/mysql-test/r/myisam_mrr.result b/mysql-test/r/myisam_mrr.result
index 38e1841dd41..5bb6b9db49e 100644
--- a/mysql-test/r/myisam_mrr.result
+++ b/mysql-test/r/myisam_mrr.result
@@ -1,4 +1,6 @@
drop table if exists t0, t1, t2, t3;
+set @myisam_mrr_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set @mrr_buffer_size_save= @@mrr_buffer_size;
set mrr_buffer_size=79;
Warnings:
@@ -186,7 +188,7 @@ explain
select * from t4 where a IS NULL and b IS NULL and (c IS NULL or c='no-such-row1'
or c='no-such-row2');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 range idx1 idx1 29 NULL 10 Using index condition; Rowid-ordered scan
+1 SIMPLE t4 range idx1 idx1 29 NULL 10 Using index condition; Using where; Rowid-ordered scan
select * from t4 where a IS NULL and b IS NULL and (c IS NULL or c='no-such-row1'
or c='no-such-row2');
a b c filler
@@ -208,7 +210,7 @@ NULL NULL NULL NULL-1
explain
select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t4 range idx1 idx1 29 NULL 21 Using index condition; Rowid-ordered scan
+1 SIMPLE t4 range idx1 idx1 29 NULL 21 Using index condition; Using where; Rowid-ordered scan
select * from t4 where (a ='b-1' or a='bb-1') and b IS NULL and (c='c-1' or c='cc-2');
a b c filler
b-1 NULL c-1 NULL-15
@@ -347,10 +349,10 @@ WHERE t2.int_key IS NULL
GROUP BY t2.pk
);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
2 SUBQUERY t2 ref int_key int_key 5 const 1 100.00 Using index condition; Using where; Using filesort
Warnings:
-Note 1003 select min(`test`.`t1`.`pk`) AS `MIN(t1.pk)` from `test`.`t1` where exists(select `test`.`t2`.`pk` from `test`.`t2` where isnull(`test`.`t2`.`int_key`) group by `test`.`t2`.`pk`)
+Note 1003 select min(1) AS `MIN(t1.pk)` from `test`.`t1` where exists(select `test`.`t2`.`pk` from `test`.`t2` where isnull(`test`.`t2`.`int_key`) group by `test`.`t2`.`pk`)
DROP TABLE t1, t2;
#
# BUG#42048 Discrepancy between MyISAM and Maria's ICP implementation
@@ -363,7 +365,7 @@ update t1 set b=repeat(char(65+a), 20) where a < 25;
This must show range + using index condition:
explain select * from t1 where a < 10 and b = repeat(char(65+a), 20);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 19 Using where
+1 SIMPLE t1 range a a 5 NULL 19 Using index condition; Using where
select * from t1 where a < 10 and b = repeat(char(65+a), 20);
a b filler
0 AAAAAAAAAAAAAAAAAAAA filler
@@ -486,6 +488,14 @@ INSERT INTO t1 VALUES
(22,142,'b','b'),(23,3,'y','y'),(24,0,'v','v'),
(25,3,'m','m'),(26,5,'z','z'),(27,9,'n','n'),
(28,1,'d','d'),(29,107,'a','a');
+INSERT INTO t1 VALUES
+(110,8,'v','v'),(111,8,'f','f'), (112,5,'v','v'),
+(113,8,'s','s'),(114,8,'a','a'),(115,6,'p','p'),
+(116,7,'z','z'),(117,2,'a','a'),(118,5,'h','h'),
+(119,7,'h','h'),(120,2,'v','v'),(121,9,'v','v'),
+(122,142,'b','b'),(123,3,'y','y'),(124,0,'v','v'),
+(125,3,'m','m'),(126,5,'z','z'),(127,9,'n','n'),
+(128,1,'d','d'),(129,107,'a','a');
SELECT COUNT(*)
FROM
t1 AS table2, t1 AS table3
@@ -494,7 +504,7 @@ table3.col_varchar_key = table2.col_varchar_key AND
table3.col_varchar_key = table2.col_varchar_nokey AND
table3.pk<>0;
COUNT(*)
-50
+200
EXPLAIN SELECT COUNT(*)
FROM
t1 AS table2, t1 AS table3
@@ -503,8 +513,48 @@ table3.col_varchar_key = table2.col_varchar_key AND
table3.col_varchar_key = table2.col_varchar_nokey AND
table3.pk<>0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE table2 ALL col_varchar_key NULL NULL NULL 20 Using where
-1 SIMPLE table3 ref PRIMARY,col_varchar_key col_varchar_key 3 test.table2.col_varchar_key 3 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE table2 ALL col_varchar_key NULL NULL NULL 40 Using where
+1 SIMPLE table3 ref PRIMARY,col_varchar_key col_varchar_key 3 test.table2.col_varchar_key 5 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
set join_cache_level= @save_join_cache_level;
set join_buffer_size= @save_join_buffer_size;
drop table t1;
+#
+# BUG#730133: Wrong result with jkl = 7, BKA, ICP in maria-5.3 + compound index
+#
+set @tmp_730133_jcl= @@join_cache_level;
+set join_cache_level = 7;
+set @tmp_730133_os= @@optimizer_switch;
+set optimizer_switch= 'join_cache_hashed=off,join_cache_bka=on,index_condition_pushdown=on,optimize_join_buffer_size=on';
+CREATE TABLE t1 (f1 int, f2 int, f3 int, f4 int, f5 int, KEY (f4,f3));
+INSERT IGNORE INTO t1 VALUES ('2','9','5','0','0'),('4','7','0','0','0'),
+('6','97','190','0','0'),('7','3','6','0','0'),('11','101','186','0','0'),
+('14','194','226','0','0'),('15','148','133','0','0'),
+('16','9','6','0','0'),('17','9','3','0','0'),('18','1','8','0','0'),
+('19','1','5','0','0'),('20','5','7','0','0');
+explain
+SELECT COUNT(alias2.f2)
+FROM
+t1 STRAIGHT_JOIN
+t1 AS alias3 STRAIGHT_JOIN
+t1 AS alias2 FORCE KEY (f4)
+WHERE
+alias2.f4=alias3.f5 AND
+alias2.f3 > alias3.f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL f4 10 NULL 12 Using index
+1 SIMPLE alias3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE alias2 ref f4 f4 5 test.alias3.f5 2 Using index condition(BKA); Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+SELECT COUNT(alias2.f2)
+FROM
+t1 STRAIGHT_JOIN
+t1 AS alias3 STRAIGHT_JOIN
+t1 AS alias2 FORCE KEY (f4)
+WHERE
+alias2.f4=alias3.f5 AND
+alias2.f3 > alias3.f1;
+COUNT(alias2.f2)
+768
+set @@join_cache_level= @tmp_730133_jcl;
+set @@optimizer_switch= @tmp_730133_os;
+drop table t1;
+set optimizer_switch= @myisam_mrr_tmp;
diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result
index f4298cc7a4c..895fb5f3761 100644
--- a/mysql-test/r/mysql.result
+++ b/mysql-test/r/mysql.result
@@ -1,4 +1,4 @@
-drop table if exists t1;
+drop table if exists t1,t2,t3;
create table t1(a int);
insert into t1 values(1);
ERROR at line 9: DELIMITER must be followed by a 'delimiter' character or string
@@ -137,6 +137,14 @@ drop table t1;
1
ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
ERROR at line 1: USE must be followed by a database name
+1 +1
+2
+1 +1
+2
+1 +1
+2
+1 +1
+2
\
\\
';
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 9723c40721c..86754f1b458 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -1722,6 +1722,90 @@ insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thir
</table_data>
</database>
</mysqldump>
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+LOCK TABLES `t1` WRITE;
+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+INSERT INTO `t1` VALUES (NULL),(10),(20);
+/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
+UNLOCK TABLES;
+
+LOCK TABLES `t2` WRITE;
+/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
+INSERT INTO `t2` VALUES (1,NULL,NULL,NULL,NULL,NULL),(2,10,NULL,NULL,NULL,NULL),(3,NULL,'twenty',NULL,NULL,NULL),(4,30,'thirty',NULL,NULL,NULL);
+/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+DROP TABLE IF EXISTS `t1`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t1` (
+ `a` int(10) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+LOCK TABLES `t1` WRITE;
+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+INSERT INTO `t1` VALUES (NULL),(10),(20);
+/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
+UNLOCK TABLES;
+DROP TABLE IF EXISTS `t2`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `t2` (
+ `pk` int(11) NOT NULL AUTO_INCREMENT,
+ `a` int(10) DEFAULT NULL,
+ `b` varchar(30) DEFAULT NULL,
+ `c` datetime DEFAULT NULL,
+ `d` blob,
+ `e` text,
+ PRIMARY KEY (`pk`)
+) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+LOCK TABLES `t2` WRITE;
+/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
+INSERT INTO `t2` VALUES (1,NULL,NULL,NULL,NULL,NULL),(2,10,NULL,NULL,NULL,NULL),(3,NULL,'twenty',NULL,NULL,NULL),(4,30,'thirty',NULL,NULL,NULL);
+/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
+UNLOCK TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
drop table t1, t2;
#
# Bug#12123 mysqldump --tab results in text file which can't be imported
diff --git a/mysql-test/r/negation_elimination.result b/mysql-test/r/negation_elimination.result
index dea0d865d87..5b09b0fc511 100644
--- a/mysql-test/r/negation_elimination.result
+++ b/mysql-test/r/negation_elimination.result
@@ -4,7 +4,7 @@ insert into t1 values (NULL), (0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(10), (11), (12), (13), (14), (15), (16), (17), (18), (19);
explain select * from t1 where not(not(a));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index NULL a 5 NULL 21 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 20 Using where; Using index
select * from t1 where not(not(a));
a
1
@@ -375,6 +375,121 @@ a
13
14
15
+# XOR (Note: XOR is negated by negating one of the operands)
+# Should return 6,7
+SELECT * FROM t1 WHERE ((a > 5) XOR (a > 7));
+a
+6
+7
+# Should return 0..5,8..19
+SELECT * FROM t1 WHERE ((NOT (a > 5)) XOR (a > 7));
+a
+0
+1
+2
+3
+4
+5
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+SELECT * FROM t1 WHERE ((a > 5) XOR (NOT (a > 7)));
+a
+0
+1
+2
+3
+4
+5
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+SELECT * FROM t1 WHERE NOT ((a > 5) XOR (a > 7));
+a
+0
+1
+2
+3
+4
+5
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+# Should return 6,7
+SELECT * FROM t1 WHERE NOT ((NOT (a > 5)) XOR (a > 7));
+a
+6
+7
+SELECT * FROM t1 WHERE NOT ((a > 5) XOR (NOT (a > 7)));
+a
+6
+7
+# Should return 0..5,8..19
+SELECT * FROM t1 WHERE NOT ((NOT (a > 5)) XOR (NOT (a > 7)));
+a
+0
+1
+2
+3
+4
+5
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+# Should have empty result
+SELECT * FROM t1 WHERE (NULL XOR (a > 7));
+a
+SELECT * FROM t1 WHERE NOT (NULL XOR (a > 7));
+a
+# Should be simplified to "...WHERE (a XOR a)
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT ((NOT a) XOR (a));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index NULL a 5 NULL 21 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` xor `test`.`t1`.`a`)
+# Should be simplified to "...WHERE (a XOR a)
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT (a XOR (NOT a));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index NULL a 5 NULL 21 100.00 Using where; Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` xor `test`.`t1`.`a`)
+# End XOR
delete from t1 where a > 3;
select a, not(not(a)) from t1;
a not(not(a))
@@ -385,7 +500,7 @@ NULL NULL
3 1
explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "1"), not (a not in (1,2)), not(a != 2) from t1 where not(not(a)) having not(not(a));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 index NULL a 5 NULL 5 100.00 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 4 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or `test`.`t1`.`a`) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like '1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where `test`.`t1`.`a` having `test`.`t1`.`a`
+Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or `test`.`t1`.`a`) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like '1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where (`test`.`t1`.`a` <> 0) having (`test`.`t1`.`a` <> 0)
drop table t1;
diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result
index 54729bd6937..1cdc48e6552 100644
--- a/mysql-test/r/null.result
+++ b/mysql-test/r/null.result
@@ -148,10 +148,10 @@ insert into t1 values
(7,7), (8,8), (9,9), (10,10), (11,11), (12,12);
explain select * from t1 where a between 2 and 3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx idx 4 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range idx idx 4 NULL 2 Using where
explain select * from t1 where a between 2 and 3 or b is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx idx 4 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range idx idx 4 NULL 2 Using where
drop table t1;
select cast(NULL as signed);
cast(NULL as signed)
diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result
index db2f662eeac..78e28c75ab1 100644
--- a/mysql-test/r/null_key.result
+++ b/mysql-test/r/null_key.result
@@ -258,7 +258,7 @@ INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4
INSERT INTO t2 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL);
explain select id from t1 where uniq_id is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref idx1 idx1 5 const 5 Using index condition
+1 SIMPLE t1 ref idx1 idx1 5 const 5 Using where
explain select id from t1 where uniq_id =1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const idx1 idx1 5 const 1
diff --git a/mysql-test/r/old-mode.result b/mysql-test/r/old-mode.result
index a9815d7dab2..6e6f9965e73 100644
--- a/mysql-test/r/old-mode.result
+++ b/mysql-test/r/old-mode.result
@@ -16,3 +16,6 @@ Table Checksum
test.t1 2948697075
test.t2 2948697075
drop table t1,t2;
+SHOW PROCESSLIST;
+Id User Host db Command Time State Info
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
diff --git a/mysql-test/r/optimizer_switch.result b/mysql-test/r/optimizer_switch.result
index 937b4dfeffa..9286e8687db 100644
--- a/mysql-test/r/optimizer_switch.result
+++ b/mysql-test/r/optimizer_switch.result
@@ -4,19 +4,19 @@
#
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch='index_merge=off,index_merge_union=off';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch='index_merge_union=on';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch='default,index_merge_sort_union=off';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch=4;
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of '4'
set optimizer_switch=NULL;
@@ -43,60 +43,60 @@ set optimizer_switch=default;
set optimizer_switch='index_merge=off,index_merge_union=off,default';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch=default;
select @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set @@global.optimizer_switch=default;
select @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
#
# Check index_merge's @@optimizer_switch flags
#
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
BUG#37120 optimizer_switch allowable values not according to specification
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch='default,materialization=off';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch='default,semijoin=off';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch='default,loosescan=off';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=off,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=off,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch='default,semijoin=off,materialization=off';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch='default,materialization=off,semijoin=off';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch='default,semijoin=off,materialization=off,loosescan=off';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch='default,semijoin=off,loosescan=off';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch='default,materialization=off,loosescan=off';
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=off,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=off,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
set optimizer_switch=default;
select @@optimizer_switch;
@@optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=on,derived_merge=on,derived_with_keys=on,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=on,mrr_cost_based=off,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=on,loosescan=on,materialization=off,in_to_exists=on,semijoin=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on,mrr=off,mrr_cost_based=off,mrr_sort_keys=off,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index 9a39cb4f16c..5d6b2a18003 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -515,7 +515,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.skr = t3.uid order by t1.gid,t3.skr;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 2 test.t1.skr 1 Using index condition
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 2 test.t1.skr 1 Using where
drop table t1,t2,t3;
CREATE TABLE t1 (
`titre` char(80) NOT NULL default '',
@@ -612,7 +612,7 @@ DS-MRR: use two IGNORE INDEX queries, otherwise we get cost races, because
DS-MRR: records_in_range/read_time return the same numbers for all three indexes
EXPLAIN SELECT * FROM t1 IGNORE INDEX (LongField, StringField) WHERE FieldKey > '2' ORDER BY LongVal;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range FieldKey FieldKey 38 NULL 4 Using index condition; Rowid-ordered scan; Using filesort
+1 SIMPLE t1 range FieldKey FieldKey 38 NULL 4 Using where; Using filesort
EXPLAIN SELECT * FROM t1 IGNORE INDEX (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range StringField StringField 38 NULL 4 Using where; Using filesort
@@ -642,9 +642,10 @@ id
drop table t1;
create table t1(a int, b int, index(b));
insert into t1 values (2, 1), (1, 1), (4, NULL), (3, NULL), (6, 2), (5, 2);
+insert into t1 values (12, 11), (11, 11), (14, 3), (13, 5), (16, 12), (15, 12);
explain select * from t1 where b=1 or b is null order by a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null b b 5 const 3 Using index condition; Using filesort
+1 SIMPLE t1 ref_or_null b b 5 const 4 Using where; Using filesort
select * from t1 where b=1 or b is null order by a;
a b
1 1
@@ -653,7 +654,7 @@ a b
4 NULL
explain select * from t1 where b=2 or b is null order by a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null b b 5 const 4 Using index condition; Using filesort
+1 SIMPLE t1 ref_or_null b b 5 const 3 Using where; Using filesort
select * from t1 where b=2 or b is null order by a;
a b
3 NULL
@@ -1113,7 +1114,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index k2 k3 5 NULL 73 Using where
EXPLAIN SELECT id,c3 FROM t2 WHERE c2 BETWEEN 20 AND 30 ORDER BY c3 LIMIT 4000;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range k2 k2 5 NULL 386 Using index condition; Rowid-ordered scan; Using filesort
+1 SIMPLE t2 range k2 k2 5 NULL 386 Using where; Using filesort
SELECT id,c3 FROM t2 WHERE c2=11 ORDER BY c3 LIMIT 20;
id c3
6 14
@@ -1464,7 +1465,7 @@ INSERT INTO t1 VALUES (1, 10), (2, NULL);
EXPLAIN
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref_or_null a_c,a a_c 10 const,const 1 Using where
+1 SIMPLE t1 ref_or_null a_c,a a_c 10 const,const 2 Using where; Using index; Using filesort
# Must return 1 row
SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c;
col
@@ -1490,8 +1491,8 @@ SELECT d FROM t1, t2
WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
ORDER BY t2.c LIMIT 1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a,b b 4 const 4 Using index condition; Using where; Using temporary; Using filesort
-1 SIMPLE t2 ref a,b,c a 40 test.t1.a,const 11 Using index condition
+1 SIMPLE t1 ref a,b b 4 const 4 Using where; Using temporary; Using filesort
+1 SIMPLE t2 ref a,b,c a 40 test.t1.a,const 11 Using where
SELECT d FROM t1, t2
WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
ORDER BY t2.c LIMIT 1;
@@ -1626,19 +1627,19 @@ INSERT INTO t2 SELECT a+4, b FROM t2;
EXPLAIN
SELECT * FROM t1 FORCE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 2 Using index condition; Rowid-ordered scan; Using temporary; Using filesort
+1 SIMPLE t1 range a a 5 NULL 2 Using where; Using temporary; Using filesort
1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
# should have "using filesort"
EXPLAIN
SELECT * FROM t1 USE INDEX FOR ORDER BY (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 2 Using index condition; Rowid-ordered scan; Using temporary; Using filesort
+1 SIMPLE t1 range a a 5 NULL 2 Using where; Using temporary; Using filesort
1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
# should have "using filesort"
EXPLAIN
SELECT * FROM t1 FORCE INDEX FOR JOIN (a), t2 WHERE t1.a < 2 ORDER BY t1.a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 2 Using index condition; Rowid-ordered scan; Using temporary; Using filesort
+1 SIMPLE t1 range a a 5 NULL 2 Using where; Using temporary; Using filesort
1 SIMPLE t2 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
DROP TABLE t1, t2;
#
diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result
index 0791b979da1..4df5f1702c7 100644
--- a/mysql-test/r/partition_error.result
+++ b/mysql-test/r/partition_error.result
@@ -657,15 +657,16 @@ CREATE TABLE t1 (a INT) PARTITION BY HASH (a);
FLUSH TABLES;
CHECK TABLE t1;
Table Op Msg_type Msg_text
+test.t1 check Error File './test/t1.par' not found (Errcode: 2)
test.t1 check Error Failed to read from the .par file
test.t1 check Error Incorrect information in file: './test/t1.frm'
test.t1 check error Corrupt
SELECT * FROM t1;
-ERROR HY000: Failed to read from the .par file
+ERROR HY000: File './test/t1.par' not found (Errcode: 2)
# Note that it is currently impossible to drop a partitioned table
# without the .par file
DROP TABLE t1;
-ERROR 42S02: Unknown table 't1'
+ERROR HY000: File './test/t1.par' not found (Errcode: 2)
#
# Bug#49477: Assertion `0' failed in ha_partition.cc:5530
# with temporary table and partitions
diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result
index 75097b8d411..6d6371e263f 100644
--- a/mysql-test/r/partition_pruning.result
+++ b/mysql-test/r/partition_pruning.result
@@ -2340,16 +2340,17 @@ drop table t1;
create table t1 (a int not null, b int not null, key(a), key(b))
partition by hash(a) partitions 4;
insert into t1 values (1,1),(2,2),(3,3),(4,4);
+insert into t1 values (5,5),(6,6),(7,7),(8,8);
explain partitions
select * from t1 X, t1 Y
where X.b = Y.b and (X.a=1 or X.a=2) and (Y.a=2 or Y.a=3);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE X p1,p2 ALL a,b NULL NULL NULL 2 Using where
+1 SIMPLE X p1,p2 range a,b a 4 NULL 4 Using where
1 SIMPLE Y p2,p3 ref a,b b 4 test.X.b 2 Using where
explain partitions
select * from t1 X, t1 Y where X.a = Y.a and (X.a=1 or X.a=2);
id select_type table partitions type possible_keys key key_len ref rows Extra
-1 SIMPLE X p1,p2 ALL a NULL NULL NULL 2 Using where
+1 SIMPLE X p1,p2 range a a 4 NULL 4 Using where
1 SIMPLE Y p1,p2 ref a a 4 test.X.a 2
drop table t1;
create table t1 (a int) partition by hash(a) partitions 20;
diff --git a/mysql-test/r/plugin_innodb.result b/mysql-test/r/plugin_innodb.result
new file mode 100644
index 00000000000..48510ad8745
--- /dev/null
+++ b/mysql-test/r/plugin_innodb.result
@@ -0,0 +1,11 @@
+install plugin example soname 'ha_example.so';
+create table t1(a int) engine=example;
+drop table t1;
+alter table mysql.plugin engine=innodb;
+restart
+create table t1(a int) engine=example;
+select * from t1;
+a
+drop table t1;
+alter table mysql.plugin engine=myisam;
+uninstall plugin example;
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 5197aea9e87..ca847188ce9 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -156,6 +156,7 @@ prepare stmt1 from @stmt ;
execute stmt1 ;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -163,6 +164,7 @@ id select_type table type possible_keys key key_len ref rows Extra
execute stmt1 ;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
@@ -170,6 +172,7 @@ id select_type table type possible_keys key key_len ref rows Extra
explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+6 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
5 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
4 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result
index f280bd93ffc..8d578794d6d 100644
--- a/mysql-test/r/ps_1general.result
+++ b/mysql-test/r/ps_1general.result
@@ -465,9 +465,9 @@ def key 253 64 7 Y 0 31 8
def key_len 253 4096 1 Y 0 31 8
def ref 253 2048 0 Y 0 31 8
def rows 8 10 1 Y 32928 0 63
-def Extra 253 255 57 N 1 31 8
+def Extra 253 255 27 N 1 31 8
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using index condition; Rowid-ordered scan; Using filesort
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using filesort
drop table if exists t2;
create table t2 (id smallint, name varchar(20)) ;
prepare stmt1 from ' insert into t2 values(?, ?) ' ;
diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result
index e99c5b9942b..2a9d08a70f4 100644
--- a/mysql-test/r/ps_2myisam.result
+++ b/mysql-test/r/ps_2myisam.result
@@ -1509,8 +1509,8 @@ prepare stmt1 from 'insert into t1 values(?,?),(?,?)';
execute stmt1 using @arg00, @arg01, @arg02, @arg03 ;
select a,b from t1 where a in (@arg00,@arg02) ;
a b
-82 8-2
81 8-1
+82 8-2
set @arg00=9 ;
set @arg01='nine' ;
prepare stmt1 from 'insert into t1 set a=?, b=? ';
diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result
index 7431ac6899e..a5e71e114ca 100644
--- a/mysql-test/r/ps_ddl.result
+++ b/mysql-test/r/ps_ddl.result
@@ -1508,12 +1508,12 @@ create view v_27690_1 as select A.a, A.b from t_27690_1 A, t_27690_1 B;
execute stmt;
a b a b
1 1 1 1
-1 1 2 2
2 2 1 1
-2 2 2 2
1 1 1 1
-1 1 2 2
2 2 1 1
+1 1 2 2
+2 2 2 2
+1 1 2 2
2 2 2 2
call p_verify_reprepare_count(1);
SUCCESS
@@ -1521,12 +1521,12 @@ SUCCESS
execute stmt;
a b a b
1 1 1 1
-1 1 2 2
2 2 1 1
-2 2 2 2
1 1 1 1
-1 1 2 2
2 2 1 1
+1 1 2 2
+2 2 2 2
+1 1 2 2
2 2 2 2
call p_verify_reprepare_count(0);
SUCCESS
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 8f9e8dd48c3..6155a0ee433 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1,4 +1,4 @@
-drop table if exists t1, t2, t3;
+drop table if exists t1, t2, t3, t10, t100;
CREATE TABLE t1 (
event_date date DEFAULT '0000-00-00' NOT NULL,
type int(11) DEFAULT '0' NOT NULL,
@@ -221,27 +221,27 @@ update t1 set y=x;
explain select * from t1, t1 t2 where t1.y = 8 and t2.x between 7 and t1.y+0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1
-1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+1 SIMPLE t2 range x x 5 NULL 2 Using where; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 8 and t2.x >= 7 and t2.x <= t1.y+0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1
-1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+1 SIMPLE t2 range x x 5 NULL 2 Using where; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1
-1 SIMPLE t2 range x x 5 NULL 3 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+1 SIMPLE t2 range x x 5 NULL 3 Using where; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1
-1 SIMPLE t2 range x x 5 NULL 3 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+1 SIMPLE t2 range x x 5 NULL 3 Using where; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1
-1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+1 SIMPLE t2 range x x 5 NULL 2 Using where; Using join buffer (flat, BNL join)
explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref y y 5 const 1
-1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+1 SIMPLE t2 range x x 5 NULL 2 Using where; Using join buffer (flat, BNL join)
explain select count(*) from t1 where x in (1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref x x 5 const 1 Using index
@@ -276,7 +276,7 @@ INSERT INTO t1 VALUES
(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a,b a 5 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range a,b a 5 NULL 2 Using where
SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
a b
DROP TABLE t1;
@@ -421,19 +421,19 @@ test.t1 analyze status OK
test.t2 analyze status Table is already up to date
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using where
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using where
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using where
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using where
1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
id name uid id name uid
@@ -615,13 +615,13 @@ INSERT INTO t1 (a) VALUES
('111'),('222'),('222'),('222'),('222'),('444'),('aaa'),('AAA'),('bbb');
explain select * from t1 where a='aaa';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref a a 11 const 2 Using index condition
+1 SIMPLE t1 ref a a 11 const 2 Using where
explain select * from t1 where a=binary 'aaa';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 11 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range a a 11 NULL 2 Using where
explain select * from t1 where a='aaa' collate latin1_bin;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 11 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range a a 11 NULL 2 Using where
explain select * from t1 where a='aaa' collate latin1_german1_ci;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL a NULL NULL NULL 9 Using where
@@ -698,14 +698,26 @@ INSERT INTO t1 VALUES
'd8c4177d09f8b11f5.52725521'),
('d8c4177d24ccef970.14957924','d8c4177d09f8b11f5.52725521',10,11,
'd8c4177d09f8b11f5.52725521');
+INSERT INTO t1 VALUES
+('d8c4177d09f8b11f5.52725522','oxrootid',1,40,'d8c4177d09f8b11f5.52725522'),
+('d8c4177d151affab2.81582771','d8c4177d09f8b11f5.52725521',2,3,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d206a333d2.74422678','d8c4177d09f8b11f5.52725521',4,5,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d225791924.30714721','d8c4177d09f8b11f5.52725521',6,7,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d2380fc201.39666694','d8c4177d09f8b11f5.52725521',8,9,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d24ccef970.14957925','d8c4177d09f8b11f5.52725521',10,11,
+'d8c4177d09f8b11f5.52725522');
EXPLAIN
SELECT s.oxid FROM t1 v, t1 s
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
s.oxleft > v.oxleft AND s.oxleft < v.oxright;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 5 Using index condition
-1 SIMPLE s ALL OXLEFT NULL NULL NULL 6 Range checked for each record (index map: 0x4)
+1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 5 Using where
+1 SIMPLE s ALL OXLEFT NULL NULL NULL 12 Range checked for each record (index map: 0x4)
SELECT s.oxid FROM t1 v, t1 s
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
@@ -878,10 +890,10 @@ INSERT INTO t1 VALUES
(55,'C'), (56,'C'), (57,'C'), (58,'C'), (59,'C'), (60,'C');
EXPLAIN SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range status status 23 NULL 11 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range status status 23 NULL 11 Using where
EXPLAIN SELECT * FROM t1 WHERE status NOT IN ('A','B');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range status status 23 NULL 11 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range status status 23 NULL 11 Using where
SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B';
id status
53 C
@@ -910,10 +922,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range status status 23 NULL 11 Using where; Using index
EXPLAIN SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range status status 23 NULL 10 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range status status 23 NULL 10 Using where
EXPLAIN SELECT * FROM t1 WHERE status < 'A' OR status > 'B';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range status status 23 NULL 10 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range status status 23 NULL 10 Using where
SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B';
id status
53 C
@@ -1014,20 +1026,20 @@ create table t2 (a varchar(10), filler char(200), key(a));
insert into t2 select * from t1;
explain select * from t1 where a between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 13 NULL # Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range a a 13 NULL # Using where
explain select * from t1 where a = 'a' or a='a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 13 NULL # Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range a a 13 NULL # Using where
explain select * from t2 where a between 'a' and 'a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref a a 13 const # Using index condition
+1 SIMPLE t2 ref a a 13 const # Using where
explain select * from t2 where a = 'a' or a='a ';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref a a 13 const # Using index condition
+1 SIMPLE t2 ref a a 13 const # Using where
update t1 set a='b' where a<>'a';
explain select * from t1 where a not between 'b' and 'b';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 13 NULL # Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range a a 13 NULL # Using where
select a, hex(filler) from t1 where a not between 'b' and 'b';
a hex(filler)
a 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
@@ -1071,10 +1083,10 @@ id b c
0 3 4
EXPLAIN SELECT * FROM t1 WHERE b<=3 AND 3<=c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using where
EXPLAIN SELECT * FROM t1 WHERE 3 BETWEEN b AND c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using where; Rowid-ordered scan
+1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using where
SELECT * FROM t1 WHERE 0 < b OR 0 > c;
id b c
0 3 4
@@ -1103,7 +1115,7 @@ INSERT INTO t1 VALUES
('A2','2005-12-01 08:00:00',1000);
EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using index condition
+1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using where
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
item started price
Warnings:
@@ -1141,7 +1153,7 @@ INSERT INTO t1 VALUES
This must use range access:
explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range dateval dateval 4 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range dateval dateval 4 NULL 2 Using where
drop table t1;
CREATE TABLE t1 (
a varchar(32), index (a)
@@ -1207,7 +1219,7 @@ Z
In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)
explain select * from t2 where a=1000 and b<11;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref a a 5 const 502 Using index condition
+1 SIMPLE t2 ref a a 5 const 502 Using where
drop table t1, t2;
CREATE TABLE t1( a INT, b INT, KEY( a, b ) );
CREATE TABLE t2( a INT, b INT, KEY( a, b ) );
@@ -1678,7 +1690,7 @@ pk i4
EXPLAIN
SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range i4_uq i4_uq 5 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 3 Using where
SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4;
pk i4
1 10
@@ -1687,7 +1699,7 @@ pk i4
EXPLAIN
SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using where
SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10;
pk i4
1 10
@@ -1721,7 +1733,7 @@ pk i4
EXPLAIN
SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using where
SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999;
pk i4
1 10
@@ -1736,7 +1748,7 @@ pk i4
EXPLAIN
SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using where
SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20';
pk i4
1 10
@@ -1745,14 +1757,14 @@ EXPLAIN
SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using index condition
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using where
SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4;
pk i4 pk i4
EXPLAIN
SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3
-1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using index condition
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using where
SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk;
pk i4 pk i4
DROP TABLE t1;
@@ -1763,3 +1775,49 @@ select min(f1) from t1 where f1 >= '2006-05-25 07:00:20' and f1 between '2003-
min(f1)
NULL
drop table t1;
+#
+# BUG#11765831: 'RANGE ACCESS' MAY INCORRECTLY FILTER
+# AWAY QUALIFYING ROWS
+#
+CREATE TABLE t10(
+K INT NOT NULL AUTO_INCREMENT,
+I INT, J INT,
+PRIMARY KEY(K),
+KEY(I,J)
+);
+INSERT INTO t10(I,J) VALUES (6,1),(6,2),(6,3),(6,4),(6,5),
+(6,6),(6,7),(6,8),(6,9),(6,0);
+CREATE TABLE t100 LIKE t10;
+INSERT INTO t100(I,J) SELECT X.I, X.K+(10*Y.K) FROM t10 AS X,t10 AS Y;
+INSERT INTO t100(I,J) VALUES(8,26);
+
+EXPLAIN SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t100 range I I 10 NULL 4 Using where
+
+SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5);
+K I J
+101 8 26
+DROP TABLE t10,t100;
+#
+# lp:817363: Wrong result with sort_union and multipart key in maria-5.3
+#
+CREATE TABLE t1 (a int NOT NULL , b int, c int, d varchar(32), KEY (d,b), PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (7,7,NULL,'e'),(8,1,0,'p'),(9,7,1,'s'),(10,1,1,'j'),(12,2,0,'c'),(13,0,0,'a'),(14,1,1,'q');
+SELECT c FROM t1 WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
+c
+1
+1
+SELECT c FROM t1 ignore index (d) WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
+c
+1
+1
+SELECT * FROM t1 ignore index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
+a b c d
+9 7 1 s
+14 1 1 q
+SELECT * FROM t1 force index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
+a b c d
+14 1 1 q
+9 7 1 s
+DROP TABLE t1;
diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result
new file mode 100644
index 00000000000..cb9ea051ae0
--- /dev/null
+++ b/mysql-test/r/range_mrr_icp.result
@@ -0,0 +1,1826 @@
+set @mrr_icp_extra_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+drop table if exists t1, t2, t3, t10, t100;
+CREATE TABLE t1 (
+event_date date DEFAULT '0000-00-00' NOT NULL,
+type int(11) DEFAULT '0' NOT NULL,
+event_id int(11) DEFAULT '0' NOT NULL,
+PRIMARY KEY (event_date,type,event_id)
+);
+INSERT INTO t1 VALUES ('1999-07-10',100100,24), ('1999-07-11',100100,25),
+('1999-07-13',100600,0), ('1999-07-13',100600,4), ('1999-07-13',100600,26),
+('1999-07-14',100600,10), ('1999-07-15',100600,16), ('1999-07-15',100800,45),
+('1999-07-15',101000,47), ('1999-07-16',100800,46), ('1999-07-20',100600,5),
+('1999-07-20',100600,27), ('1999-07-21',100600,11), ('1999-07-22',100600,17),
+('1999-07-23',100100,39), ('1999-07-24',100100,39), ('1999-07-24',100500,40),
+('1999-07-25',100100,39), ('1999-07-27',100600,1), ('1999-07-27',100600,6),
+('1999-07-27',100600,28), ('1999-07-28',100600,12), ('1999-07-29',100500,41),
+('1999-07-29',100600,18), ('1999-07-30',100500,41), ('1999-07-31',100500,41),
+('1999-08-01',100700,34), ('1999-08-03',100600,7), ('1999-08-03',100600,29),
+('1999-08-04',100600,13), ('1999-08-05',100500,42), ('1999-08-05',100600,19),
+('1999-08-06',100500,42), ('1999-08-07',100500,42), ('1999-08-08',100500,42),
+('1999-08-10',100600,2), ('1999-08-10',100600,9), ('1999-08-10',100600,30),
+('1999-08-11',100600,14), ('1999-08-12',100600,20), ('1999-08-17',100500,8),
+('1999-08-17',100600,31), ('1999-08-18',100600,15), ('1999-08-19',100600,22),
+('1999-08-24',100600,3), ('1999-08-24',100600,32), ('1999-08-27',100500,43),
+('1999-08-31',100600,33), ('1999-09-17',100100,37), ('1999-09-18',100100,37),
+('1999-09-19',100100,37), ('2000-12-18',100700,38);
+select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date;
+event_date type event_id
+1999-07-10 100100 24
+1999-07-11 100100 25
+1999-07-13 100600 0
+1999-07-13 100600 4
+1999-07-13 100600 26
+1999-07-14 100600 10
+explain select event_date,type,event_id from t1 WHERE type = 100601 and event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date <= "1999-07-15" AND (type=100600 OR type=100100) or event_date >= "1999-07-01" AND event_date <= "1999-07-15" AND type=100099;
+event_date type event_id
+1999-07-10 100100 24
+1999-07-11 100100 25
+1999-07-13 100600 0
+1999-07-13 100600 4
+1999-07-13 100600 26
+1999-07-14 100600 10
+1999-07-15 100600 16
+drop table t1;
+CREATE TABLE t1 (
+PAPER_ID smallint(6) DEFAULT '0' NOT NULL,
+YEAR smallint(6) DEFAULT '0' NOT NULL,
+ISSUE smallint(6) DEFAULT '0' NOT NULL,
+CLOSED tinyint(4) DEFAULT '0' NOT NULL,
+ISS_DATE date DEFAULT '0000-00-00' NOT NULL,
+PRIMARY KEY (PAPER_ID,YEAR,ISSUE)
+);
+INSERT INTO t1 VALUES (3,1999,34,0,'1999-07-12'), (1,1999,111,0,'1999-03-23'),
+(1,1999,222,0,'1999-03-23'), (3,1999,33,0,'1999-07-12'),
+(3,1999,32,0,'1999-07-12'), (3,1999,31,0,'1999-07-12'),
+(3,1999,30,0,'1999-07-12'), (3,1999,29,0,'1999-07-12'),
+(3,1999,28,0,'1999-07-12'), (1,1999,40,1,'1999-05-01'),
+(1,1999,41,1,'1999-05-01'), (1,1999,42,1,'1999-05-01'),
+(1,1999,46,1,'1999-05-01'), (1,1999,47,1,'1999-05-01'),
+(1,1999,48,1,'1999-05-01'), (1,1999,49,1,'1999-05-01'),
+(1,1999,50,0,'1999-05-01'), (1,1999,51,0,'1999-05-01'),
+(1,1999,200,0,'1999-06-28'), (1,1999,52,0,'1999-06-28'),
+(1,1999,53,0,'1999-06-28'), (1,1999,54,0,'1999-06-28'),
+(1,1999,55,0,'1999-06-28'), (1,1999,56,0,'1999-07-01'),
+(1,1999,57,0,'1999-07-01'), (1,1999,58,0,'1999-07-01'),
+(1,1999,59,0,'1999-07-01'), (1,1999,60,0,'1999-07-01'),
+(3,1999,35,0,'1999-07-12');
+select YEAR,ISSUE from t1 where PAPER_ID=3 and (YEAR>1999 or (YEAR=1999 and ISSUE>28)) order by YEAR,ISSUE;
+YEAR ISSUE
+1999 29
+1999 30
+1999 31
+1999 32
+1999 33
+1999 34
+1999 35
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+repair table t1;
+Table Op Msg_type Msg_text
+test.t1 repair status OK
+drop table t1;
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+parent_id int(11) DEFAULT '0' NOT NULL,
+level tinyint(4) DEFAULT '0' NOT NULL,
+PRIMARY KEY (id),
+KEY parent_id (parent_id),
+KEY level (level)
+);
+INSERT INTO t1 VALUES (1,0,0), (3,1,1), (4,1,1), (8,2,2), (9,2,2), (17,3,2),
+(22,4,2), (24,4,2), (28,5,2), (29,5,2), (30,5,2), (31,6,2), (32,6,2), (33,6,2),
+(203,7,2), (202,7,2), (20,3,2), (157,0,0), (193,5,2), (40,7,2), (2,1,1),
+(15,2,2), (6,1,1), (34,6,2), (35,6,2), (16,3,2), (7,1,1), (36,7,2), (18,3,2),
+(26,5,2), (27,5,2), (183,4,2), (38,7,2), (25,5,2), (37,7,2), (21,4,2),
+(19,3,2), (5,1,1), (179,5,2);
+SELECT * FROM t1 WHERE level = 1 AND parent_id = 1;
+id parent_id level
+3 1 1
+4 1 1
+2 1 1
+6 1 1
+7 1 1
+5 1 1
+SELECT * FROM t1 WHERE level = 1 AND parent_id = 1 order by id;
+id parent_id level
+2 1 1
+3 1 1
+4 1 1
+5 1 1
+6 1 1
+7 1 1
+drop table t1;
+create table t1(
+Satellite varchar(25) not null,
+SensorMode varchar(25) not null,
+FullImageCornersUpperLeftLongitude double not null,
+FullImageCornersUpperRightLongitude double not null,
+FullImageCornersUpperRightLatitude double not null,
+FullImageCornersLowerRightLatitude double not null,
+index two (Satellite, SensorMode, FullImageCornersUpperLeftLongitude, FullImageCornersUpperRightLongitude, FullImageCornersUpperRightLatitude, FullImageCornersLowerRightLatitude));
+insert into t1 values("OV-3","PAN1",91,-92,40,50);
+insert into t1 values("OV-4","PAN1",91,-92,40,50);
+select * from t1 where t1.Satellite = "OV-3" and t1.SensorMode = "PAN1" and t1.FullImageCornersUpperLeftLongitude > -90.000000 and t1.FullImageCornersUpperRightLongitude < -82.000000;
+Satellite SensorMode FullImageCornersUpperLeftLongitude FullImageCornersUpperRightLongitude FullImageCornersUpperRightLatitude FullImageCornersLowerRightLatitude
+OV-3 PAN1 91 -92 40 50
+drop table t1;
+create table t1 ( aString char(100) not null default "", key aString (aString(10)) );
+insert t1 (aString) values ( "believe in myself" ), ( "believe" ), ("baaa" ), ( "believe in love");
+select * from t1 where aString < "believe in myself" order by aString;
+aString
+baaa
+believe
+believe in love
+select * from t1 where aString > "believe in love" order by aString;
+aString
+believe in myself
+alter table t1 drop key aString;
+select * from t1 where aString < "believe in myself" order by aString;
+aString
+baaa
+believe
+believe in love
+select * from t1 where aString > "believe in love" order by aString;
+aString
+believe in myself
+drop table t1;
+CREATE TABLE t1 (
+t1ID int(10) unsigned NOT NULL auto_increment,
+art binary(1) NOT NULL default '',
+KNR char(5) NOT NULL default '',
+RECHNR char(6) NOT NULL default '',
+POSNR char(2) NOT NULL default '',
+ARTNR char(10) NOT NULL default '',
+TEX char(70) NOT NULL default '',
+PRIMARY KEY (t1ID),
+KEY IdxArt (art),
+KEY IdxKnr (KNR),
+KEY IdxArtnr (ARTNR)
+) ENGINE=MyISAM;
+INSERT INTO t1 (art) VALUES ('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),('j'),('J'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),
+('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j'),('j');
+select count(*) from t1 where upper(art) = 'J';
+count(*)
+213
+select count(*) from t1 where art = 'J' or art = 'j';
+count(*)
+602
+select count(*) from t1 where art = 'j' or art = 'J';
+count(*)
+602
+select count(*) from t1 where art = 'j';
+count(*)
+389
+select count(*) from t1 where art = 'J';
+count(*)
+213
+drop table t1;
+create table t1 (x int, y int, index(x), index(y));
+insert into t1 (x) values (1),(2),(3),(4),(5),(6),(7),(8),(9);
+update t1 set y=x;
+explain select * from t1, t1 t2 where t1.y = 8 and t2.x between 7 and t1.y+0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+explain select * from t1, t1 t2 where t1.y = 8 and t2.x >= 7 and t2.x <= t1.y+0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x between t1.y-1 and t1.y+1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 3 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= t1.y-1 and t2.x <= t1.y+1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 3 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x between 0 and t1.y;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+explain select * from t1, t1 t2 where t1.y = 2 and t2.x >= 0 and t2.x <= t1.y;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref y y 5 const 1
+1 SIMPLE t2 range x x 5 NULL 2 Using index condition; Rowid-ordered scan; Using join buffer (flat, BNL join)
+explain select count(*) from t1 where x in (1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref x x 5 const 1 Using index
+explain select count(*) from t1 where x in (1,2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index x x 5 NULL 9 Using where; Using index
+drop table t1;
+CREATE TABLE t1 (key1 int(11) NOT NULL default '0', KEY i1 (key1));
+INSERT INTO t1 VALUES (0),(0),(0),(0),(0),(1),(1);
+CREATE TABLE t2 (keya int(11) NOT NULL default '0', KEY j1 (keya));
+INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2);
+explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref j1 j1 4 const 1 Using index
+1 SIMPLE t1 index i1 i1 4 NULL 7 Using where; Using index; Using join buffer (flat, BNL join)
+explain select * from t1 force index(i1), t2 force index(j1) where
+(t1.key1 <t2.keya + 1) and t2.keya=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref j1 j1 4 const 1 Using index
+1 SIMPLE t1 index i1 i1 4 NULL 7 Using where; Using index; Using join buffer (flat, BNL join)
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+a int(11) default NULL,
+b int(11) default NULL,
+KEY a (a),
+KEY b (b)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+(1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,2),(10,2),
+(13,2),(14,2),(15,2),(16,2),(17,3),(17,3),(16,3),(17,3),(19,3),(20,3),
+(21,4),(22,5),(23,5),(24,5),(25,5),(26,5),(30,5),(31,5),(32,5),(33,5),
+(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
+EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a,b a 5 NULL 2 Using index condition; Using where; Rowid-ordered scan
+SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
+a b
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int, c int, INDEX (c,a,b));
+INSERT INTO t1 VALUES (1,0,0),(1,0,0),(1,0,0);
+INSERT INTO t1 VALUES (0,1,0),(0,1,0),(0,1,0);
+SELECT COUNT(*) FROM t1 WHERE (c=0 and a=1) or (c=0 and b=1);
+COUNT(*)
+6
+SELECT COUNT(*) FROM t1 WHERE (c=0 and b=1) or (c=0 and a=1);
+COUNT(*)
+6
+DROP TABLE t1;
+CREATE TABLE t1 ( a int not null, b int not null, INDEX ab(a,b) );
+INSERT INTO t1 VALUES (47,1), (70,1), (15,1), (15, 4);
+SELECT * FROM t1
+WHERE
+(
+( b =1 AND a BETWEEN 14 AND 21 ) OR
+( b =2 AND a BETWEEN 16 AND 18 ) OR
+( b =3 AND a BETWEEN 15 AND 19 ) OR
+(a BETWEEN 19 AND 47)
+);
+a b
+15 1
+47 1
+DROP TABLE t1;
+CREATE TABLE t1 (
+id int( 11 ) unsigned NOT NULL AUTO_INCREMENT ,
+line int( 5 ) unsigned NOT NULL default '0',
+columnid int( 3 ) unsigned NOT NULL default '0',
+owner int( 3 ) unsigned NOT NULL default '0',
+ordinal int( 3 ) unsigned NOT NULL default '0',
+showid smallint( 6 ) unsigned NOT NULL default '1',
+tableid int( 1 ) unsigned NOT NULL default '1',
+content int( 5 ) unsigned NOT NULL default '188',
+PRIMARY KEY ( owner, id ) ,
+KEY menu( owner, showid, columnid ) ,
+KEY `COLUMN` ( owner, columnid, line ) ,
+KEY `LINES` ( owner, tableid, content, id ) ,
+KEY recount( owner, line )
+) ENGINE = MYISAM;
+INSERT into t1 (owner,id,columnid,line) values (11,15,15,1),(11,13,13,5);
+SELECT id, columnid, tableid, content, showid, line, ordinal FROM t1 WHERE owner=11 AND ((columnid IN ( 15, 13, 14 ) AND line IN ( 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 31 )) OR (columnid IN ( 13, 14 ) AND line IN ( 15 ))) LIMIT 0 , 30;
+id columnid tableid content showid line ordinal
+13 13 1 188 1 5 0
+15 15 1 188 1 1 0
+drop table t1;
+create table t1 (id int(10) primary key);
+insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
+select id from t1 where id in (2,5,9) ;
+id
+2
+5
+9
+select id from t1 where id=2 or id=5 or id=9 ;
+id
+2
+5
+9
+drop table t1;
+create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2));
+insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"),
+(3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"),
+(6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"),
+(9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"),
+(12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"),
+(15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"),
+(18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa");
+select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1;
+id1 idnull
+drop table t1;
+create table t1 (
+id int not null auto_increment,
+name char(1) not null,
+uid int not null,
+primary key (id),
+index uid_index (uid));
+create table t2 (
+id int not null auto_increment,
+name char(1) not null,
+uid int not null,
+primary key (id),
+index uid_index (uid));
+insert into t1(id, uid, name) values(1, 0, ' ');
+insert into t1(uid, name) values(0, ' ');
+insert into t2(uid, name) select uid, name from t1;
+insert into t1(uid, name) select uid, name from t2;
+insert into t2(uid, name) select uid, name from t1;
+insert into t1(uid, name) select uid, name from t2;
+insert into t2(uid, name) select uid, name from t1;
+insert into t1(uid, name) select uid, name from t2;
+insert into t2(uid, name) select uid, name from t1;
+insert into t1(uid, name) select uid, name from t2;
+insert into t2(uid, name) select uid, name from t1;
+insert into t1(uid, name) select uid, name from t2;
+insert into t2(uid, name) select uid, name from t1;
+insert into t2(uid, name) select uid, name from t1;
+insert into t2(uid, name) select uid, name from t1;
+insert into t2(uid, name) select uid, name from t1;
+insert into t1(uid, name) select uid, name from t2;
+delete from t2;
+insert into t2(uid, name) values
+(1, CHAR(64+1)),
+(2, CHAR(64+2)),
+(3, CHAR(64+3)),
+(4, CHAR(64+4)),
+(5, CHAR(64+5)),
+(6, CHAR(64+6)),
+(7, CHAR(64+7)),
+(8, CHAR(64+8)),
+(9, CHAR(64+9)),
+(10, CHAR(64+10)),
+(11, CHAR(64+11)),
+(12, CHAR(64+12)),
+(13, CHAR(64+13)),
+(14, CHAR(64+14)),
+(15, CHAR(64+15)),
+(16, CHAR(64+16)),
+(17, CHAR(64+17)),
+(18, CHAR(64+18)),
+(19, CHAR(64+19)),
+(20, CHAR(64+20)),
+(21, CHAR(64+21)),
+(22, CHAR(64+22)),
+(23, CHAR(64+23)),
+(24, CHAR(64+24)),
+(25, CHAR(64+25)),
+(26, CHAR(64+26));
+insert into t1(uid, name) select uid, name from t2 order by uid;
+delete from t2;
+insert into t2(id, uid, name) select id, uid, name from t1;
+select count(*) from t1;
+count(*)
+1026
+select count(*) from t2;
+count(*)
+1026
+analyze table t1,t2;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+test.t2 analyze status Table is already up to date
+explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
+explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uid_index uid_index 4 NULL 112 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
+explain select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
+explain select * from t1, t2 where t1.uid=t2.uid AND t2.uid != 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range uid_index uid_index 4 NULL 113 Using index condition; Rowid-ordered scan
+1 SIMPLE t2 ref uid_index uid_index 4 test.t1.uid 38
+select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
+id name uid id name uid
+1001 A 1 1001 A 1
+1002 B 2 1002 B 2
+1003 C 3 1003 C 3
+1004 D 4 1004 D 4
+1005 E 5 1005 E 5
+1006 F 6 1006 F 6
+1007 G 7 1007 G 7
+1008 H 8 1008 H 8
+1009 I 9 1009 I 9
+1010 J 10 1010 J 10
+1011 K 11 1011 K 11
+1012 L 12 1012 L 12
+1013 M 13 1013 M 13
+1014 N 14 1014 N 14
+1015 O 15 1015 O 15
+1016 P 16 1016 P 16
+1017 Q 17 1017 Q 17
+1018 R 18 1018 R 18
+1019 S 19 1019 S 19
+1020 T 20 1020 T 20
+1021 U 21 1021 U 21
+1022 V 22 1022 V 22
+1023 W 23 1023 W 23
+1024 X 24 1024 X 24
+1025 Y 25 1025 Y 25
+1026 Z 26 1026 Z 26
+select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
+id name uid id name uid
+1001 A 1 1001 A 1
+1002 B 2 1002 B 2
+1003 C 3 1003 C 3
+1004 D 4 1004 D 4
+1005 E 5 1005 E 5
+1006 F 6 1006 F 6
+1007 G 7 1007 G 7
+1008 H 8 1008 H 8
+1009 I 9 1009 I 9
+1010 J 10 1010 J 10
+1011 K 11 1011 K 11
+1012 L 12 1012 L 12
+1013 M 13 1013 M 13
+1014 N 14 1014 N 14
+1015 O 15 1015 O 15
+1016 P 16 1016 P 16
+1017 Q 17 1017 Q 17
+1018 R 18 1018 R 18
+1019 S 19 1019 S 19
+1020 T 20 1020 T 20
+1021 U 21 1021 U 21
+1022 V 22 1022 V 22
+1023 W 23 1023 W 23
+1024 X 24 1024 X 24
+1025 Y 25 1025 Y 25
+1026 Z 26 1026 Z 26
+drop table t1,t2;
+create table t1 (x bigint unsigned not null);
+insert into t1(x) values (0xfffffffffffffff0);
+insert into t1(x) values (0xfffffffffffffff1);
+select * from t1;
+x
+18446744073709551600
+18446744073709551601
+select count(*) from t1 where x>0;
+count(*)
+2
+select count(*) from t1 where x=0;
+count(*)
+0
+select count(*) from t1 where x<0;
+count(*)
+0
+select count(*) from t1 where x < -16;
+count(*)
+0
+select count(*) from t1 where x = -16;
+count(*)
+0
+select count(*) from t1 where x > -16;
+count(*)
+2
+select count(*) from t1 where x = 18446744073709551601;
+count(*)
+1
+create table t2 (x bigint not null);
+insert into t2(x) values (-16);
+insert into t2(x) values (-15);
+select * from t2;
+x
+-16
+-15
+select count(*) from t2 where x>0;
+count(*)
+0
+select count(*) from t2 where x=0;
+count(*)
+0
+select count(*) from t2 where x<0;
+count(*)
+2
+select count(*) from t2 where x < -16;
+count(*)
+0
+select count(*) from t2 where x = -16;
+count(*)
+1
+select count(*) from t2 where x > -16;
+count(*)
+1
+select count(*) from t2 where x = 18446744073709551601;
+count(*)
+0
+drop table t1,t2;
+create table t1 (x bigint unsigned not null primary key) engine=innodb;
+insert into t1(x) values (0xfffffffffffffff0);
+insert into t1(x) values (0xfffffffffffffff1);
+select * from t1;
+x
+18446744073709551600
+18446744073709551601
+select count(*) from t1 where x>0;
+count(*)
+2
+select count(*) from t1 where x=0;
+count(*)
+0
+select count(*) from t1 where x<0;
+count(*)
+0
+select count(*) from t1 where x < -16;
+count(*)
+0
+select count(*) from t1 where x = -16;
+count(*)
+0
+select count(*) from t1 where x > -16;
+count(*)
+2
+select count(*) from t1 where x = 18446744073709551601;
+count(*)
+1
+drop table t1;
+create table t1 (a bigint unsigned);
+create index t1i on t1(a);
+insert into t1 select 18446744073709551615;
+insert into t1 select 18446744073709551614;
+explain select * from t1 where a <> -1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index t1i t1i 9 NULL 2 Using where; Using index
+select * from t1 where a <> -1;
+a
+18446744073709551614
+18446744073709551615
+explain select * from t1 where a > -1 or a < -1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index t1i t1i 9 NULL 2 Using where; Using index
+select * from t1 where a > -1 or a < -1;
+a
+18446744073709551614
+18446744073709551615
+explain select * from t1 where a > -1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index t1i t1i 9 NULL 2 Using where; Using index
+select * from t1 where a > -1;
+a
+18446744073709551614
+18446744073709551615
+explain select * from t1 where a < -1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+select * from t1 where a < -1;
+a
+drop table t1;
+set names latin1;
+create table t1 (a char(10), b text, key (a)) character set latin1;
+INSERT INTO t1 (a) VALUES
+('111'),('222'),('222'),('222'),('222'),('444'),('aaa'),('AAA'),('bbb');
+explain select * from t1 where a='aaa';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref a a 11 const 2 Using index condition
+explain select * from t1 where a=binary 'aaa';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 11 NULL 2 Using index condition; Rowid-ordered scan
+explain select * from t1 where a='aaa' collate latin1_bin;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 11 NULL 2 Using index condition; Rowid-ordered scan
+explain select * from t1 where a='aaa' collate latin1_german1_ci;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL a NULL NULL NULL 9 Using where
+drop table t1;
+CREATE TABLE t1 (
+`CLIENT` char(3) character set latin1 collate latin1_bin NOT NULL default '000',
+`ARG1` char(3) character set latin1 collate latin1_bin NOT NULL default '',
+`ARG2` char(3) character set latin1 collate latin1_bin NOT NULL default '',
+`FUNCTION` varchar(10) character set latin1 collate latin1_bin NOT NULL default '',
+`FUNCTINT` int(11) NOT NULL default '0',
+KEY `VERI_CLNT~2` (`ARG1`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES ('000',' 0',' 0','Text 001',0), ('000',' 0',' 1','Text 002',0),
+('000',' 1',' 2','Text 003',0), ('000',' 2',' 3','Text 004',0),
+('001',' 3',' 0','Text 017',0);
+SELECT count(*) FROM t1 WHERE CLIENT='000' AND (ARG1 != ' 1' OR ARG1 != ' 2');
+count(*)
+4
+SELECT count(*) FROM t1 WHERE CLIENT='000' AND (ARG1 != ' 2' OR ARG1 != ' 1');
+count(*)
+4
+drop table t1;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+CREATE TABLE t2 (
+pk1 int(11) NOT NULL,
+pk2 int(11) NOT NULL,
+pk3 int(11) NOT NULL,
+pk4 int(11) NOT NULL,
+filler char(82),
+PRIMARY KEY (pk1,pk2,pk3,pk4)
+) DEFAULT CHARSET=latin1;
+insert into t2 select 1, A.a+10*B.a, 432, 44, 'fillerZ' from t1 A, t1 B;
+INSERT INTO t2 VALUES (2621, 2635, 0, 0,'filler'), (2621, 2635, 1, 0,'filler'),
+(2621, 2635, 10, 0,'filler'), (2621, 2635, 11, 0,'filler'),
+(2621, 2635, 14, 0,'filler'), (2621, 2635, 1000015, 0,'filler');
+SELECT * FROM t2
+WHERE ((((pk4 =0) AND (pk1 =2621) AND (pk2 =2635)))
+OR ((pk4 =1) AND (((pk1 IN ( 7, 2, 1 ))) OR (pk1 =522)) AND ((pk2 IN ( 0, 2635))))
+) AND (pk3 >=1000000);
+pk1 pk2 pk3 pk4 filler
+2621 2635 1000015 0 filler
+drop table t1, t2;
+create table t1(a char(2), key(a(1)));
+insert into t1 values ('x'), ('xx');
+explain select a from t1 where a > 'x';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 2 NULL 2 Using where
+select a from t1 where a > 'x';
+a
+xx
+drop table t1;
+CREATE TABLE t1 (
+OXID varchar(32) COLLATE latin1_german2_ci NOT NULL DEFAULT '',
+OXPARENTID varchar(32) COLLATE latin1_german2_ci NOT NULL DEFAULT 'oxrootid',
+OXLEFT int NOT NULL DEFAULT '0',
+OXRIGHT int NOT NULL DEFAULT '0',
+OXROOTID varchar(32) COLLATE latin1_german2_ci NOT NULL DEFAULT '',
+PRIMARY KEY (OXID),
+KEY OXNID (OXID),
+KEY OXLEFT (OXLEFT),
+KEY OXRIGHT (OXRIGHT),
+KEY OXROOTID (OXROOTID)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci;
+INSERT INTO t1 VALUES
+('d8c4177d09f8b11f5.52725521','oxrootid',1,40,'d8c4177d09f8b11f5.52725521'),
+('d8c4177d151affab2.81582770','d8c4177d09f8b11f5.52725521',2,3,
+'d8c4177d09f8b11f5.52725521'),
+('d8c4177d206a333d2.74422679','d8c4177d09f8b11f5.52725521',4,5,
+'d8c4177d09f8b11f5.52725521'),
+('d8c4177d225791924.30714720','d8c4177d09f8b11f5.52725521',6,7,
+'d8c4177d09f8b11f5.52725521'),
+('d8c4177d2380fc201.39666693','d8c4177d09f8b11f5.52725521',8,9,
+'d8c4177d09f8b11f5.52725521'),
+('d8c4177d24ccef970.14957924','d8c4177d09f8b11f5.52725521',10,11,
+'d8c4177d09f8b11f5.52725521');
+INSERT INTO t1 VALUES
+('d8c4177d09f8b11f5.52725522','oxrootid',1,40,'d8c4177d09f8b11f5.52725522'),
+('d8c4177d151affab2.81582771','d8c4177d09f8b11f5.52725521',2,3,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d206a333d2.74422678','d8c4177d09f8b11f5.52725521',4,5,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d225791924.30714721','d8c4177d09f8b11f5.52725521',6,7,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d2380fc201.39666694','d8c4177d09f8b11f5.52725521',8,9,
+'d8c4177d09f8b11f5.52725522'),
+('d8c4177d24ccef970.14957925','d8c4177d09f8b11f5.52725521',10,11,
+'d8c4177d09f8b11f5.52725522');
+EXPLAIN
+SELECT s.oxid FROM t1 v, t1 s
+WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
+v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
+s.oxleft > v.oxleft AND s.oxleft < v.oxright;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE v ref OXLEFT,OXRIGHT,OXROOTID OXROOTID 34 const 5 Using index condition
+1 SIMPLE s ALL OXLEFT NULL NULL NULL 12 Range checked for each record (index map: 0x4)
+SELECT s.oxid FROM t1 v, t1 s
+WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
+v.oxrootid ='d8c4177d09f8b11f5.52725521' AND
+s.oxleft > v.oxleft AND s.oxleft < v.oxright;
+oxid
+d8c4177d151affab2.81582770
+d8c4177d206a333d2.74422679
+d8c4177d225791924.30714720
+d8c4177d2380fc201.39666693
+d8c4177d24ccef970.14957924
+DROP TABLE t1;
+create table t1 (
+c1 char(10), c2 char(10), c3 char(10), c4 char(10),
+c5 char(10), c6 char(10), c7 char(10), c8 char(10),
+c9 char(10), c10 char(10), c11 char(10), c12 char(10),
+c13 char(10), c14 char(10), c15 char(10), c16 char(10),
+index(c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12,c13,c14,c15,c16)
+);
+insert into t1 (c1) values ('1'),('1'),('1'),('1');
+select * from t1 where
+c1 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c2 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c3 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c4 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c5 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c6 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c7 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c8 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c9 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC")
+and c10 in ("abcdefgh", "123456789", "qwertyuio", "asddfgh",
+"abcdefg1", "123456781", "qwertyui1", "asddfg1",
+"abcdefg2", "123456782", "qwertyui2", "asddfg2",
+"abcdefg3", "123456783", "qwertyui3", "asddfg3",
+"abcdefg4", "123456784", "qwertyui4", "asddfg4",
+"abcdefg5", "123456785", "qwertyui5", "asddfg5",
+"abcdefg6", "123456786", "qwertyui6", "asddfg6",
+"abcdefg7", "123456787", "qwertyui7", "asddfg7",
+"abcdefg8", "123456788", "qwertyui8", "asddfg8",
+"abcdefg9", "123456789", "qwertyui9", "asddfg9",
+"abcdefgA", "12345678A", "qwertyuiA", "asddfgA",
+"abcdefgB", "12345678B", "qwertyuiB", "asddfgB",
+"abcdefgC", "12345678C", "qwertyuiC", "asddfgC");
+c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16
+drop table t1;
+End of 4.1 tests
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+status varchar(20),
+PRIMARY KEY (id),
+KEY (status)
+);
+INSERT INTO t1 VALUES
+(1,'B'), (2,'B'), (3,'B'), (4,'B'), (5,'B'), (6,'B'),
+(7,'B'), (8,'B'), (9,'B'), (10,'B'), (11,'B'), (12,'B'),
+(13,'B'), (14,'B'), (15,'B'), (16,'B'), (17,'B'), (18,'B'),
+(19,'B'), (20,'B'), (21,'B'), (22,'B'), (23,'B'), (24,'B'),
+(25,'A'), (26,'A'), (27,'A'), (28,'A'), (29,'A'), (30,'A'),
+(31,'A'), (32,'A'), (33,'A'), (34,'A'), (35,'A'), (36,'A'),
+(37,'A'), (38,'A'), (39,'A'), (40,'A'), (41,'A'), (42,'A'),
+(43,'A'), (44,'A'), (45,'A'), (46,'A'), (47,'A'), (48,'A'),
+(49,'A'), (50,'A'), (51,'A'), (52,'A'), (53,'C'), (54,'C'),
+(55,'C'), (56,'C'), (57,'C'), (58,'C'), (59,'C'), (60,'C');
+EXPLAIN SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range status status 23 NULL 11 Using index condition; Rowid-ordered scan
+EXPLAIN SELECT * FROM t1 WHERE status NOT IN ('A','B');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range status status 23 NULL 11 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE status <> 'A' AND status <> 'B';
+id status
+53 C
+54 C
+55 C
+56 C
+57 C
+58 C
+59 C
+60 C
+SELECT * FROM t1 WHERE status NOT IN ('A','B');
+id status
+53 C
+54 C
+55 C
+56 C
+57 C
+58 C
+59 C
+60 C
+EXPLAIN SELECT status FROM t1 WHERE status <> 'A' AND status <> 'B';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range status status 23 NULL 11 Using where; Using index
+EXPLAIN SELECT status FROM t1 WHERE status NOT IN ('A','B');
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range status status 23 NULL 11 Using where; Using index
+EXPLAIN SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range status status 23 NULL 10 Using index condition; Rowid-ordered scan
+EXPLAIN SELECT * FROM t1 WHERE status < 'A' OR status > 'B';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range status status 23 NULL 10 Using index condition; Using where; Rowid-ordered scan
+SELECT * FROM t1 WHERE status NOT BETWEEN 'A' AND 'B';
+id status
+53 C
+54 C
+55 C
+56 C
+57 C
+58 C
+59 C
+60 C
+SELECT * FROM t1 WHERE status < 'A' OR status > 'B';
+id status
+53 C
+54 C
+55 C
+56 C
+57 C
+58 C
+59 C
+60 C
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int, primary key(a,b));
+INSERT INTO t1 VALUES
+(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3),(4,1),(4,2),(4,3);
+CREATE VIEW v1 as SELECT a,b FROM t1 WHERE b=3;
+EXPLAIN SELECT a,b FROM t1 WHERE a < 2 and b=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
+EXPLAIN SELECT a,b FROM v1 WHERE a < 2 and b=3;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
+EXPLAIN SELECT a,b FROM t1 WHERE a < 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
+EXPLAIN SELECT a,b FROM v1 WHERE a < 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using index
+SELECT a,b FROM t1 WHERE a < 2 and b=3;
+a b
+1 3
+SELECT a,b FROM v1 WHERE a < 2 and b=3;
+a b
+1 3
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 (name varchar(15) NOT NULL, KEY idx(name));
+INSERT INTO t1 VALUES ('Betty'), ('Anna');
+SELECT * FROM t1;
+name
+Anna
+Betty
+DELETE FROM t1 WHERE name NOT LIKE 'A%a';
+SELECT * FROM t1;
+name
+Anna
+DROP TABLE t1;
+CREATE TABLE t1 (a int, KEY idx(a));
+INSERT INTO t1 VALUES (NULL), (1), (2), (3);
+SELECT * FROM t1;
+a
+NULL
+1
+2
+3
+DELETE FROM t1 WHERE NOT(a <=> 2);
+SELECT * FROM t1;
+a
+2
+DROP TABLE t1;
+create table t1 (a int, b int, primary key(a,b));
+create view v1 as select a, b from t1;
+INSERT INTO `t1` VALUES
+(0,0),(1,0),(2,0),(3,0),(4,0),(5,1),(6,1),(7,1),(8,1),(9,1),(10,2),(11,2),(12,2)
+,(13,2),(14,2),(15,3),(16,3),(17,3),(18,3),(19,3);
+explain select * from t1 where a in (3,4) and b in (1,2,3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
+explain select * from v1 where a in (3,4) and b in (1,2,3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
+explain select * from t1 where a between 3 and 4 and b between 1 and 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
+explain select * from v1 where a between 3 and 4 and b between 1 and 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 8 NULL # Using where; Using index
+drop view v1;
+drop table t1;
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (a varchar(10), filler char(200), key(a)) charset=binary;
+insert into t1 values ('a','');
+insert into t1 values ('a ','');
+insert into t1 values ('a ', '');
+insert into t1 select concat('a', 1000 + A.a + 10 * (B.a + 10 * C.a)), ''
+ from t3 A, t3 B, t3 C;
+create table t2 (a varchar(10), filler char(200), key(a));
+insert into t2 select * from t1;
+explain select * from t1 where a between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 13 NULL # Using index condition; Rowid-ordered scan
+explain select * from t1 where a = 'a' or a='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 13 NULL # Using index condition; Using where; Rowid-ordered scan
+explain select * from t2 where a between 'a' and 'a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref a a 13 const # Using index condition
+explain select * from t2 where a = 'a' or a='a ';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref a a 13 const # Using index condition; Using where
+update t1 set a='b' where a<>'a';
+explain select * from t1 where a not between 'b' and 'b';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 13 NULL # Using index condition; Rowid-ordered scan
+select a, hex(filler) from t1 where a not between 'b' and 'b';
+a hex(filler)
+a 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+drop table t1,t2,t3;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, key(a));
+insert into t2 select 2*(A.a + 10*(B.a + 10*C.a)) from t1 A, t1 B, t1 C;
+set @a="select * from t2 force index (a) where a NOT IN(0";
+select count(*) from (select @a:=concat(@a, ',', a) from t2 ) Z;
+count(*)
+1000
+set @a=concat(@a, ')');
+insert into t2 values (11),(13),(15);
+set @b= concat("explain ", @a);
+prepare stmt1 from @b;
+execute stmt1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index a a 5 NULL 1003 Using where; Using index
+prepare stmt1 from @a;
+execute stmt1;
+a
+11
+13
+15
+drop table t1, t2;
+CREATE TABLE t1 (
+id int NOT NULL DEFAULT '0',
+b int NOT NULL DEFAULT '0',
+c int NOT NULL DEFAULT '0',
+INDEX idx1(b,c), INDEX idx2(c));
+INSERT INTO t1(id) VALUES (1), (2), (3), (4), (5), (6), (7), (8);
+INSERT INTO t1(b,c) VALUES (3,4), (3,4);
+SELECT * FROM t1 WHERE b<=3 AND 3<=c;
+id b c
+0 3 4
+0 3 4
+SELECT * FROM t1 WHERE 3 BETWEEN b AND c;
+id b c
+0 3 4
+0 3 4
+EXPLAIN SELECT * FROM t1 WHERE b<=3 AND 3<=c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using index condition; Using where; Rowid-ordered scan
+EXPLAIN SELECT * FROM t1 WHERE 3 BETWEEN b AND c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range idx1,idx2 idx2 4 NULL 3 Using where; Rowid-ordered scan
+SELECT * FROM t1 WHERE 0 < b OR 0 > c;
+id b c
+0 3 4
+0 3 4
+SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c;
+id b c
+0 3 4
+0 3 4
+EXPLAIN SELECT * FROM t1 WHERE 0 < b OR 0 > c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where
+EXPLAIN SELECT * FROM t1 WHERE 0 NOT BETWEEN b AND c;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge idx1,idx2 idx1,idx2 4,4 NULL 4 Using sort_union(idx1,idx2); Using where
+DROP TABLE t1;
+CREATE TABLE t1 (
+item char(20) NOT NULL default '',
+started datetime NOT NULL default '0000-00-00 00:00:00',
+price decimal(16,3) NOT NULL default '0.000',
+PRIMARY KEY (item,started)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES
+('A1','2005-11-01 08:00:00',1000),
+('A1','2005-11-15 00:00:00',2000),
+('A1','2005-12-12 08:00:00',3000),
+('A2','2005-12-01 08:00:00',1000);
+EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using index condition
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+item started price
+Warnings:
+Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00'
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
+item started price
+A1 2005-11-01 08:00:00 1000.000
+A1 2005-11-15 00:00:00 2000.000
+DROP INDEX `PRIMARY` ON t1;
+EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
+item started price
+Warnings:
+Warning 1292 Incorrect datetime value: '2005-12-01 24:00:00'
+SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-02 00:00:00';
+item started price
+A1 2005-11-01 08:00:00 1000.000
+A1 2005-11-15 00:00:00 2000.000
+DROP TABLE t1;
+
+BUG#32198 "Comparison of DATE with DATETIME still not using indexes correctly"
+
+CREATE TABLE t1 (
+id int(11) NOT NULL auto_increment,
+dateval date default NULL,
+PRIMARY KEY (id),
+KEY dateval (dateval)
+) AUTO_INCREMENT=173;
+INSERT INTO t1 VALUES
+(1,'2007-01-01'),(2,'2007-01-02'),(3,'2007-01-03'),(4,'2007-01-04'),
+(5,'2007-01-05'),(6,'2007-01-06'),(7,'2007-01-07'),(8,'2007-01-08'),
+(9,'2007-01-09'),(10,'2007-01-10'),(11,'2007-01-11');
+This must use range access:
+explain select * from t1 where dateval >= '2007-01-01 00:00:00' and dateval <= '2007-01-02 23:59:59';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range dateval dateval 4 NULL 2 Using index condition; Rowid-ordered scan
+drop table t1;
+CREATE TABLE t1 (
+a varchar(32), index (a)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_bin;
+INSERT INTO t1 VALUES
+('B'), ('A'), ('A'), ('C'), ('B'), ('A'), ('A');
+SELECT a FROM t1 WHERE a='b' OR a='B';
+a
+B
+B
+EXPLAIN SELECT a FROM t1 WHERE a='b' OR a='B';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 35 NULL 3 Using where; Using index
+DROP TABLE t1;
+CREATE TABLE t1 (f1 TINYINT(11) UNSIGNED NOT NULL, PRIMARY KEY (f1));
+INSERT INTO t1 VALUES (127),(254),(0),(1),(255);
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 256;
+COUNT(*)
+5
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 256.0;
+COUNT(*)
+5
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 255;
+COUNT(*)
+4
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < -1;
+COUNT(*)
+0
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 > -1;
+COUNT(*)
+5
+DROP TABLE t1;
+CREATE TABLE t1 ( f1 TINYINT(11) NOT NULL, PRIMARY KEY (f1));
+INSERT INTO t1 VALUES (127),(126),(0),(-128),(-127);
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 128;
+COUNT(*)
+5
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 128.0;
+COUNT(*)
+5
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 < 127;
+COUNT(*)
+4
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 > -129;
+COUNT(*)
+5
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 > -129.0;
+COUNT(*)
+5
+SELECT SQL_NO_CACHE COUNT(*) FROM t1 WHERE f1 > -128;
+COUNT(*)
+4
+DROP TABLE t1;
+create table t1 (a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, b int, filler char(100));
+insert into t2 select A.a + 10 * (B.a + 10 * C.a), 10, 'filler' from t1 A,
+t1 B, t1 C where A.a < 5;
+insert into t2 select 1000, b, 'filler' from t2;
+alter table t2 add index (a,b);
+select 'In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)' Z;
+Z
+In following EXPLAIN the access method should be ref, #rows~=500 (and not 2)
+explain select * from t2 where a=1000 and b<11;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref a a 5 const 502 Using index condition
+drop table t1, t2;
+CREATE TABLE t1( a INT, b INT, KEY( a, b ) );
+CREATE TABLE t2( a INT, b INT, KEY( a, b ) );
+CREATE TABLE t3( a INT, b INT, KEY( a, b ) );
+INSERT INTO t1( a, b )
+VALUES (0, 1), (1, 2), (1, 4), (2, 3), (5, 0), (9, 7);
+INSERT INTO t2( a, b )
+VALUES ( 1, 1), ( 2, 1), ( 3, 1), ( 4, 1), ( 5, 1),
+( 6, 1), ( 7, 1), ( 8, 1), ( 9, 1), (10, 1),
+(11, 1), (12, 1), (13, 1), (14, 1), (15, 1),
+(16, 1), (17, 1), (18, 1), (19, 1), (20, 1);
+INSERT INTO t2 SELECT a, 2 FROM t2 WHERE b = 1;
+INSERT INTO t2 SELECT a, 3 FROM t2 WHERE b = 1;
+INSERT INTO t2 SELECT -1, -1 FROM t2;
+INSERT INTO t2 SELECT -1, -1 FROM t2;
+INSERT INTO t2 SELECT -1, -1 FROM t2;
+INSERT INTO t3
+VALUES (1, 0), (2, 0), (3, 0), (4, 0), (5, 0),
+(6, 0), (7, 0), (8, 0), (9, 0), (10, 0);
+INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
+INSERT INTO t3 SELECT * FROM t3 WHERE a = 10;
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 < a AND b = 3 OR
+3 <= a;
+a b
+5 0
+9 7
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 < a AND b = 3 OR
+3 <= a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+a b
+5 0
+9 7
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a < 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+a b
+5 0
+9 7
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+5 <= a AND b = 3 OR
+3 <= a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+3 <= a;
+a b
+5 0
+9 7
+EXPLAIN
+SELECT * FROM t1 WHERE
+3 <= a AND a <= 5 OR
+3 <= a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 1 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+a b
+1 1
+2 1
+3 1
+4 1
+5 1
+6 1
+7 1
+8 1
+9 1
+10 1
+11 1
+12 1
+13 1
+14 1
+15 1
+15 3
+16 1
+16 3
+17 1
+17 3
+18 1
+18 3
+19 1
+19 3
+20 1
+EXPLAIN
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 1 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 2 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+a b
+1 1
+2 1
+3 1
+4 1
+5 1
+5 2
+6 1
+6 2
+7 1
+7 2
+8 1
+8 2
+9 1
+9 2
+10 1
+11 1
+12 1
+13 1
+14 1
+15 1
+15 3
+16 1
+16 3
+17 1
+17 3
+18 1
+18 3
+19 1
+19 3
+20 1
+EXPLAIN
+SELECT * FROM t2 WHERE
+5 <= a AND a < 10 AND b = 2 OR
+15 <= a AND a < 20 AND b = 3
+OR
+1 <= a AND b = 1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range a a 10 NULL 50 Using where; Using index
+SELECT * FROM t3 WHERE
+5 <= a AND a < 10 AND b = 3 OR
+a < 5 OR
+a < 10;
+a b
+1 0
+2 0
+3 0
+4 0
+5 0
+6 0
+7 0
+8 0
+9 0
+EXPLAIN
+SELECT * FROM t3 WHERE
+5 <= a AND a < 10 AND b = 3 OR
+a < 5 OR
+a < 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t3 range a a 5 NULL 8 Using where; Using index
+DROP TABLE t1, t2, t3;
+#
+# Bug #47123: Endless 100% CPU loop with STRAIGHT_JOIN
+#
+CREATE TABLE t1(a INT, KEY(a));
+INSERT INTO t1 VALUES (1), (NULL);
+SELECT * FROM t1 WHERE a <> NULL and (a <> NULL or a <= NULL);
+a
+DROP TABLE t1;
+#
+# Bug#47925: regression of range optimizer and date comparison in 5.1.39!
+#
+CREATE TABLE t1 ( a DATE, KEY ( a ) );
+CREATE TABLE t2 ( a DATETIME, KEY ( a ) );
+# Make optimizer choose range scan
+INSERT INTO t1 VALUES ('2009-09-22'), ('2009-09-22'), ('2009-09-22');
+INSERT INTO t1 VALUES ('2009-09-23'), ('2009-09-23'), ('2009-09-23');
+INSERT INTO t2 VALUES ('2009-09-22 12:00:00'), ('2009-09-22 12:00:00'),
+('2009-09-22 12:00:00');
+INSERT INTO t2 VALUES ('2009-09-23 12:00:00'), ('2009-09-23 12:00:00'),
+('2009-09-23 12:00:00');
+# DATE vs DATE
+EXPLAIN
+SELECT * FROM t1 WHERE a >= '2009/09/23';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t1 WHERE a >= '2009/09/23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '20090923';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= 20090923;
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009-9-23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009.09.23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009:09:23';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+# DATE vs DATETIME
+EXPLAIN
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009/09/23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '20090923';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= 20090923;
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009-9-23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009.09.23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009:09:23';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+# DATETIME vs DATETIME
+EXPLAIN
+SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t2 WHERE a >= '2009/09/23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '20090923120000';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= 20090923120000;
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009-9-23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009.09.23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+SELECT * FROM t2 WHERE a >= '2009:09:23 12:00:00';
+a
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+2009-09-23 12:00:00
+# DATETIME vs DATE
+EXPLAIN
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+id select_type table type possible_keys key key_len ref rows Extra
+X X X range a a X X X X
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009/09/23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '20090923000000';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= 20090923000000;
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009-9-23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009.09.23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+SELECT * FROM t1 WHERE a >= '2009:09:23 00:00:00';
+a
+2009-09-23
+2009-09-23
+2009-09-23
+# Test of the new get_date_from_str implementation
+# Behavior differs slightly between the trunk and mysql-pe.
+# The former may give errors for the truncated values, while the latter
+# gives warnings. The purpose of this test is not to interfere, and only
+# preserve existing behavior.
+SELECT str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND
+str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20';
+str_to_date('2007-10-00', '%Y-%m-%d') >= '' AND
+str_to_date('2007-10-00', '%Y-%m-%d') <= '2007/10/20'
+1
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND
+str_to_date('2007-20-00', '%Y-%m-%d') <= '';
+str_to_date('2007-20-00', '%Y-%m-%d') >= '2007/10/20' AND
+str_to_date('2007-20-00', '%Y-%m-%d') <= ''
+NULL
+Warnings:
+Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
+Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
+SELECT str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20';
+str_to_date('2007-10-00', '%Y-%m-%d') BETWEEN '' AND '2007/10/20'
+1
+Warnings:
+Warning 1292 Incorrect datetime value: ''
+SELECT str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND '';
+str_to_date('2007-20-00', '%Y-%m-%d') BETWEEN '2007/10/20' AND ''
+NULL
+Warnings:
+Error 1411 Incorrect datetime value: '2007-20-00' for function str_to_date
+SELECT str_to_date('', '%Y-%m-%d');
+str_to_date('', '%Y-%m-%d')
+0000-00-00
+DROP TABLE t1, t2;
+#
+# Bug#48459: valgrind errors with query using 'Range checked for each
+# record'
+#
+CREATE TABLE t1 (
+a INT,
+b CHAR(2),
+c INT,
+d INT,
+KEY ( c ),
+KEY ( d, a, b ( 2 ) ),
+KEY ( b ( 1 ) )
+);
+INSERT INTO t1 VALUES ( NULL, 'a', 1, 2 ), ( NULL, 'a', 1, 2 ),
+( 1, 'a', 1, 2 ), ( 1, 'a', 1, 2 );
+CREATE TABLE t2 (
+a INT,
+c INT,
+e INT,
+KEY ( e )
+);
+INSERT INTO t2 VALUES ( 1, 1, NULL ), ( 1, 1, NULL );
+# Should not give Valgrind warnings
+SELECT 1
+FROM t1, t2
+WHERE t1.d <> '1' AND t1.b > '1'
+AND t1.a = t2.a AND t1.c = t2.c;
+1
+1
+1
+1
+1
+DROP TABLE t1, t2;
+#
+# Bug #48665: sql-bench's insert test fails due to wrong result
+#
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a));
+INSERT INTO t1 VALUES (0,0), (1,1);
+EXPLAIN
+SELECT * FROM t1 FORCE INDEX (PRIMARY)
+WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
+id select_type table type possible_keys key key_len ref rows Extra
+@ @ @ range @ @ @ @ @ @
+# Should return 2 rows
+SELECT * FROM t1 FORCE INDEX (PRIMARY)
+WHERE (a>=1 AND a<=2) OR (a>=4 AND a<=5) OR (a>=0 AND a <=10);
+a b
+0 0
+1 1
+DROP TABLE t1;
+#
+# Bug #54802: 'NOT BETWEEN' evaluation is incorrect
+#
+CREATE TABLE t1 (c_key INT, c_notkey INT, KEY(c_key));
+INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3);
+EXPLAIN SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL c_key NULL NULL NULL 3 Using where
+SELECT * FROM t1 WHERE 2 NOT BETWEEN c_notkey AND c_key;
+c_key c_notkey
+1 1
+3 3
+DROP TABLE t1;
+#
+# Bug #57030: 'BETWEEN' evaluation is incorrect
+#
+CREATE TABLE t1(pk INT PRIMARY KEY, i4 INT);
+CREATE UNIQUE INDEX i4_uq ON t1(i4);
+INSERT INTO t1 VALUES (1,10), (2,20), (3,30);
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const i4_uq i4_uq 5 const 1
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 10;
+pk i4
+1 10
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND i4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 const i4_uq i4_uq 5 const 1
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND i4;
+pk i4
+1 10
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 3 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND i4;
+pk i4
+1 10
+2 20
+3 30
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE 10 BETWEEN i4 AND 10;
+pk i4
+1 10
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t1 WHERE 10 BETWEEN 10 AND 10;
+pk i4
+1 10
+2 20
+3 30
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 11 AND 11;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+SELECT * FROM t1 WHERE 10 BETWEEN 11 AND 11;
+pk i4
+EXPLAIN
+SELECT * FROM t1 WHERE 10 BETWEEN 100 AND 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+SELECT * FROM t1 WHERE 10 BETWEEN 100 AND 0;
+pk i4
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 100 AND 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT * FROM t1 WHERE i4 BETWEEN 100 AND 0;
+pk i4
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 2 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND 99999999999999999;
+pk i4
+1 10
+2 20
+3 30
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 999999999999999 AND 30;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT * FROM t1 WHERE i4 BETWEEN 999999999999999 AND 30;
+pk i4
+EXPLAIN
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range i4_uq i4_uq 5 NULL 1 Using index condition; Rowid-ordered scan
+SELECT * FROM t1 WHERE i4 BETWEEN 10 AND '20';
+pk i4
+1 10
+2 20
+EXPLAIN
+SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using index condition
+SELECT * FROM t1, t1 as t2 WHERE t2.pk BETWEEN t1.i4 AND t1.i4;
+pk i4 pk i4
+EXPLAIN
+SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL i4_uq NULL NULL NULL 3
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.i4 1 Using index condition
+SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk;
+pk i4 pk i4
+DROP TABLE t1;
+End of 5.1 tests
+create table t1 (f1 datetime, key (f1));
+insert into t1 values ('2000-03-09 15:56:59'),('2000-05-05 23:24:28'),('2000-06-13 13:12:06');
+select min(f1) from t1 where f1 >= '2006-05-25 07:00:20' and f1 between '2003-11-23 10:00:09' and '2010-01-01 01:01:01' and f1 > '2001-01-01 01:01:01';
+min(f1)
+NULL
+drop table t1;
+#
+# BUG#11765831: 'RANGE ACCESS' MAY INCORRECTLY FILTER
+# AWAY QUALIFYING ROWS
+#
+CREATE TABLE t10(
+K INT NOT NULL AUTO_INCREMENT,
+I INT, J INT,
+PRIMARY KEY(K),
+KEY(I,J)
+);
+INSERT INTO t10(I,J) VALUES (6,1),(6,2),(6,3),(6,4),(6,5),
+(6,6),(6,7),(6,8),(6,9),(6,0);
+CREATE TABLE t100 LIKE t10;
+INSERT INTO t100(I,J) SELECT X.I, X.K+(10*Y.K) FROM t10 AS X,t10 AS Y;
+INSERT INTO t100(I,J) VALUES(8,26);
+
+EXPLAIN SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t100 range I I 10 NULL 4 Using index condition; Using where; Rowid-ordered scan
+
+SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5);
+K I J
+101 8 26
+DROP TABLE t10,t100;
+#
+# lp:817363: Wrong result with sort_union and multipart key in maria-5.3
+#
+CREATE TABLE t1 (a int NOT NULL , b int, c int, d varchar(32), KEY (d,b), PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (7,7,NULL,'e'),(8,1,0,'p'),(9,7,1,'s'),(10,1,1,'j'),(12,2,0,'c'),(13,0,0,'a'),(14,1,1,'q');
+SELECT c FROM t1 WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
+c
+1
+1
+SELECT c FROM t1 ignore index (d) WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
+c
+1
+1
+SELECT * FROM t1 ignore index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
+a b c d
+9 7 1 s
+14 1 1 q
+SELECT * FROM t1 force index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
+a b c d
+9 7 1 s
+14 1 1 q
+DROP TABLE t1;
+set optimizer_switch=@mrr_icp_extra_tmp;
diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result
index 07b54400b9f..f1838bc9aae 100644
--- a/mysql-test/r/range_vs_index_merge.result
+++ b/mysql-test/r/range_vs_index_merge.result
@@ -49,14 +49,14 @@ SELECT * FROM City
WHERE (Population >= 100000 OR Name LIKE 'P%') AND Country='CAN' OR
(Population < 100000 OR Name Like 'T%') AND Country='ARG';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population,Country,Name Country 3 NULL 104 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range Population,Country,Name Country 3 NULL 104 Using where
EXPLAIN
SELECT * FROM City
WHERE Population < 200000 AND Name LIKE 'P%' AND
(Population > 300000 OR Name LIKE 'T%') AND
(Population < 100000 OR Name LIKE 'Pa%');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population,Name Name 35 NULL 135 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range Population,Name Name 35 NULL 135 Using where
EXPLAIN
SELECT * FROM City
WHERE Population > 100000 AND Name LIKE 'Aba%' OR
@@ -69,12 +69,12 @@ EXPLAIN
SELECT * FROM City
WHERE (Population > 101000 AND Population < 115000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 459 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 459 Using where
EXPLAIN
SELECT * FROM City
WHERE (Population > 101000 AND Population < 102000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 39 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 39 Using where
EXPLAIN
SELECT * FROM City
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'));
@@ -91,7 +91,7 @@ SELECT * FROM City
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
AND (Population > 101000 AND Population < 102000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population,Country,Name Population 4 NULL 39 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range Population,Country,Name Population 4 NULL 39 Using where
SELECT * FROM City USE INDEX ()
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
AND (Population > 101000 AND Population < 115000);
@@ -164,44 +164,44 @@ SELECT * FROM City
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
AND (Population > 101000 AND Population < 102000);
ID Name Country Population
-637 Mit Ghamr EGY 101801
707 Marbella ESP 101144
3792 Tartu EST 101246
4032 Cambridge USA 101355
+637 Mit Ghamr EGY 101801
EXPLAIN
SELECT * FROM City WHERE (Name < 'Ac');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 13 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 13 Using where
EXPLAIN
SELECT * FROM City WHERE (Name < 'Bb');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 208 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 208 Using where
EXPLAIN
SELECT * FROM City WHERE (Country > 'A' AND Country < 'B');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Country Country 3 NULL 104 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Country Country 3 NULL 104 Using where
EXPLAIN
SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'Pb');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 39 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 39 Using where
EXPLAIN
SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'S');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 221 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 221 Using where
EXPLAIN
SELECT * FROM City WHERE (Population > 101000 AND Population < 110000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 328 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 328 Using where
EXPLAIN
SELECT * FROM City WHERE (Population > 103000 AND Population < 104000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 37 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 37 Using where
EXPLAIN
SELECT * FROM City
WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population,Country,Name Name 35 NULL 52 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range Population,Country,Name Name 35 NULL 52 Using where
EXPLAIN
SELECT * FROM City
WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
@@ -234,10 +234,10 @@ WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
ID Name Country Population
65 Abu Dhabi ARE 398695
-168 Pabna BGD 103277
-189 Parakou BEN 103577
750 Paarl ZAF 105768
+168 Pabna BGD 103277
2865 Pak Pattan PAK 107800
+189 Parakou BEN 103577
SELECT * FROM City USE INDEX ()
WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
@@ -327,11 +327,11 @@ ID Name Country Population
EXPLAIN
SELECT * FROM City WHERE (ID < 10) OR (ID BETWEEN 100 AND 110);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY PRIMARY 4 NULL 21 Using index condition; Rowid-ordered scan
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 21 Using where
EXPLAIN
SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY PRIMARY 4 NULL 201 Using index condition; Rowid-ordered scan
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 201 Using where
EXPLAIN
SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500);
id select_type table type possible_keys key key_len ref rows Extra
@@ -339,22 +339,22 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN
SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Country Country 3 NULL 19 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Country Country 3 NULL 19 Using where
EXPLAIN
SELECT * FROM City WHERE Name LIKE 'H%' OR Name LIKE 'P%' ;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 222 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 222 Using where
EXPLAIN
SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 72 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 72 Using where
EXPLAIN
SELECT * FROM City
WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
OR ((ID BETWEEN 100 AND 110) AND
(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 21 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 21 Using where
EXPLAIN
SELECT * FROM City
WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
@@ -576,39 +576,39 @@ ID Name Country Population
EXPLAIN
SELECT * FROM City WHERE Population > 101000 AND Population < 102000;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 39 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 39 Using where
EXPLAIN
SELECT * FROM City WHERE Population > 101000 AND Population < 110000;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 328 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 328 Using where
EXPLAIN
SELECT * FROM City WHERE Country < 'C';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Country Country 3 NULL 436 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Country Country 3 NULL 436 Using where
EXPLAIN
SELECT * FROM City WHERE Country < 'AGO';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Country Country 3 NULL 6 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Country Country 3 NULL 6 Using where
EXPLAIN
SELECT * FROM City WHERE Name BETWEEN 'P' AND 'S';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 221 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 221 Using where
EXPLAIN
SELECT * FROM City WHERE Name BETWEEN 'P' AND 'Pb';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 39 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 39 Using where
EXPLAIN
SELECT * FROM City WHERE ID BETWEEN 3400 AND 3800;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY PRIMARY 4 NULL 401 Using index condition; Rowid-ordered scan
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 401 Using where
EXPLAIN
SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition; Rowid-ordered scan
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where
EXPLAIN
SELECT * FROM City WHERE Name LIKE 'P%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 135 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 135 Using where
EXPLAIN
SELECT * FROM City
WHERE ((Population > 101000 AND Population < 102000) AND
@@ -679,23 +679,23 @@ CREATE INDEX CountryPopulation ON City(Country,Population);
EXPLAIN
SELECT * FROM City WHERE Name LIKE 'Pas%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 5 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 5 Using where
EXPLAIN
SELECT * FROM City WHERE Name LIKE 'P%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 135 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 135 Using where
EXPLAIN
SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 81 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 81 Using where
EXPLAIN
SELECT * FROM City WHERE Country='USA';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref Country,CountryPopulation Country 3 const 267 Using index condition
+1 SIMPLE City ref Country,CountryPopulation Country 3 const 267 Using where
EXPLAIN
SELECT * FROM City WHERE Country='FIN';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref Country,CountryPopulation Country 3 const 6 Using index condition
+1 SIMPLE City ref Country,CountryPopulation Country 3 const 6 Using where
EXPLAIN
SELECT * FROM City
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
@@ -707,7 +707,7 @@ SELECT * FROM City
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
AND Country='FIN';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 6 Using index condition; Using where
+1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 6 Using where
SELECT * FROM City
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
AND Country='USA';
@@ -752,51 +752,51 @@ CREATE INDEX CountryName ON City(Country,Name);
EXPLAIN
SELECT * FROM City WHERE Country='USA';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 267 Using index condition
+1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 267 Using where
EXPLAIN
SELECT * FROM City WHERE Country='FIN';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref Country,CountryPopulation,CountryName CountryName 3 const 5 Using index condition
+1 SIMPLE City ref Country,CountryPopulation,CountryName CountryName 3 const 5 Using where
EXPLAIN
SELECT * FROM City WHERE Country='BRA';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref Country,CountryPopulation,CountryName CountryName 3 const 221 Using index condition
+1 SIMPLE City ref Country,CountryPopulation,CountryName CountryName 3 const 221 Using where
EXPLAIN
SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition; Rowid-ordered scan
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where
EXPLAIN
SELECT * FROM City WHERE ID BETWEEN 4025 AND 4035;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition; Rowid-ordered scan
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where
EXPLAIN
SELECT * FROM City WHERE ID BETWEEN 4028 AND 4032;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY PRIMARY 4 NULL 5 Using index condition; Rowid-ordered scan
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 5 Using where
EXPLAIN
SELECT * FROM City WHERE ID BETWEEN 3500 AND 3800;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY PRIMARY 4 NULL 301 Using index condition; Rowid-ordered scan
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 301 Using where
EXPLAIN
SELECT * FROM City WHERE ID BETWEEN 4000 AND 4300;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY PRIMARY 4 NULL 80 Using index condition; Rowid-ordered scan
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 80 Using where
EXPLAIN
SELECT * FROM City WHERE ID BETWEEN 250 and 260 ;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition; Rowid-ordered scan
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where
EXPLAIN
SELECT * FROM City WHERE (Population > 101000 AND Population < 102000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 39 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 39 Using where
EXPLAIN
SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 81 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 81 Using where
EXPLAIN
SELECT * FROM City WHERE Name LIKE 'Pa%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 41 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 41 Using where
EXPLAIN
SELECT * FROM City
WHERE ((Population > 101000 AND Population < 102000) OR
@@ -817,7 +817,7 @@ WHERE ((Population > 101000 AND Population < 110000) OR
ID BETWEEN 3500 AND 3800) AND Country='FIN'
AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName 3 const 5 Using index condition; Using where
+1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName 3 const 5 Using where
SELECT * FROM City USE INDEX ()
WHERE ((Population > 101000 AND Population < 102000) OR
ID BETWEEN 3790 AND 3800) AND Country='USA'
@@ -949,14 +949,14 @@ WHERE ((Population > 101000 AND Population < 11000) OR
ID BETWEEN 3500 AND 3800) AND Country='USA'
AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName 38 NULL 23 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName 38 NULL 23 Using where
EXPLAIN
SELECT * FROM City
WHERE ((Population > 101000 AND Population < 11000) OR
ID BETWEEN 3500 AND 3800) AND Country='USA'
AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName Name 35 NULL 1 Using where; Rowid-ordered scan
+1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName Name 35 NULL 1 Using where
SELECT * FROM City USE INDEX ()
WHERE ((Population > 101000 AND Population < 11000) OR
ID BETWEEN 3500 AND 3800) AND Country='USA'
@@ -1377,4 +1377,41 @@ SELECT * FROM t1,t2,t3
WHERE (t2.f3 = 1 OR t3.f1=t2.f1) AND t3.f1 <> t2.f2 AND t3.f2 = t2.f4;
f1 f1 f2 f3 f4 f1 f2
DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (
+a int, b int, c int, d int,
+PRIMARY KEY(b), INDEX idx1(d), INDEX idx2(d,b,c)
+);
+INSERT INTO t1 VALUES
+(0,58,7,7),(0,63,2,0),(0,64,186,8),(0,65,1,-2), (0,71,190,-3),
+(0,72,321,-7),(0,73,0,3),(0,74,5,25),(0,75,5,3);
+SET SESSION optimizer_switch='index_merge_sort_union=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 9 Using where
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+a b c d
+0 58 7 7
+0 64 186 8
+0 73 0 3
+0 74 5 25
+0 75 5 3
+SET SESSION optimizer_switch='index_merge_sort_union=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 9 Using where
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+a b c d
+0 58 7 7
+0 64 186 8
+0 73 0 3
+0 74 5 25
+0 75 5 3
+SET SESSION optimizer_switch=DEFAULT;
+DROP TABLE t1;
set session optimizer_switch='index_merge_sort_intersection=default';
diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result
index 2ca8c0ca37a..82297158c8c 100644
--- a/mysql-test/r/range_vs_index_merge_innodb.result
+++ b/mysql-test/r/range_vs_index_merge_innodb.result
@@ -50,14 +50,14 @@ SELECT * FROM City
WHERE (Population >= 100000 OR Name LIKE 'P%') AND Country='CAN' OR
(Population < 100000 OR Name Like 'T%') AND Country='ARG';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population,Country,Name Country 3 NULL 106 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range Population,Country,Name Country 3 NULL 106 Using where
EXPLAIN
SELECT * FROM City
WHERE Population < 200000 AND Name LIKE 'P%' AND
(Population > 300000 OR Name LIKE 'T%') AND
(Population < 100000 OR Name LIKE 'Pa%');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population,Name Name 35 NULL 235 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range Population,Name Name 35 NULL 235 Using where
EXPLAIN
SELECT * FROM City
WHERE Population > 100000 AND Name LIKE 'Aba%' OR
@@ -70,12 +70,12 @@ EXPLAIN
SELECT * FROM City
WHERE (Population > 101000 AND Population < 115000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 458 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 458 Using where
EXPLAIN
SELECT * FROM City
WHERE (Population > 101000 AND Population < 102000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 38 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 38 Using where
EXPLAIN
SELECT * FROM City
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'));
@@ -92,7 +92,7 @@ SELECT * FROM City
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
AND (Population > 101000 AND Population < 102000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population,Country,Name Population 4 NULL 38 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range Population,Country,Name Population 4 NULL 38 Using where
SELECT * FROM City USE INDEX ()
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
AND (Population > 101000 AND Population < 115000);
@@ -165,44 +165,44 @@ SELECT * FROM City
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
AND (Population > 101000 AND Population < 102000);
ID Name Country Population
-637 Mit Ghamr EGY 101801
707 Marbella ESP 101144
3792 Tartu EST 101246
4032 Cambridge USA 101355
+637 Mit Ghamr EGY 101801
EXPLAIN
SELECT * FROM City WHERE (Name < 'Ac');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 23 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 23 Using where
EXPLAIN
SELECT * FROM City WHERE (Name < 'Bb');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 373 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 373 Using where
EXPLAIN
SELECT * FROM City WHERE (Country > 'A' AND Country < 'B');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Country Country 3 NULL 106 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Country Country 3 NULL 106 Using where
EXPLAIN
SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'Pb');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 71 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 71 Using where
EXPLAIN
SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'S');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 384 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 384 Using where
EXPLAIN
SELECT * FROM City WHERE (Population > 101000 AND Population < 110000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 327 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 327 Using where
EXPLAIN
SELECT * FROM City WHERE (Population > 103000 AND Population < 104000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 36 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 36 Using where
EXPLAIN
SELECT * FROM City
WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population,Country,Name Name 35 NULL 94 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range Population,Country,Name Name 35 NULL 94 Using where
EXPLAIN
SELECT * FROM City
WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
@@ -235,10 +235,10 @@ WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
ID Name Country Population
65 Abu Dhabi ARE 398695
-168 Pabna BGD 103277
-189 Parakou BEN 103577
750 Paarl ZAF 105768
+168 Pabna BGD 103277
2865 Pak Pattan PAK 107800
+189 Parakou BEN 103577
SELECT * FROM City USE INDEX ()
WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000));
@@ -332,7 +332,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN
SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY PRIMARY 4 NULL 199 Using where
+1 SIMPLE City range PRIMARY PRIMARY 4 NULL 200 Using where
EXPLAIN
SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500);
id select_type table type possible_keys key key_len ref rows Extra
@@ -340,15 +340,15 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN
SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Country Country 3 NULL 19 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Country Country 3 NULL 19 Using where
EXPLAIN
SELECT * FROM City WHERE Name LIKE 'H%' OR Name LIKE 'P%' ;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 394 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 394 Using where
EXPLAIN
SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 133 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 133 Using where
EXPLAIN
SELECT * FROM City
WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
@@ -369,7 +369,7 @@ WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
OR ((ID BETWEEN 100 AND 200) AND
(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 199 Using where
+1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 200 Using where
SELECT * FROM City USE INDEX ()
WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
OR ((ID BETWEEN 100 AND 110) AND
@@ -577,27 +577,27 @@ ID Name Country Population
EXPLAIN
SELECT * FROM City WHERE Population > 101000 AND Population < 102000;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 38 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 38 Using where
EXPLAIN
SELECT * FROM City WHERE Population > 101000 AND Population < 110000;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 327 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 327 Using where
EXPLAIN
SELECT * FROM City WHERE Country < 'C';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Country Country 3 NULL 446 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Country Country 3 NULL 446 Using where
EXPLAIN
SELECT * FROM City WHERE Country < 'AGO';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Country Country 3 NULL 5 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Country Country 3 NULL 5 Using where
EXPLAIN
SELECT * FROM City WHERE Name BETWEEN 'P' AND 'S';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 384 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 384 Using where
EXPLAIN
SELECT * FROM City WHERE Name BETWEEN 'P' AND 'Pb';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 71 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 71 Using where
EXPLAIN
SELECT * FROM City WHERE ID BETWEEN 3400 AND 3800;
id select_type table type possible_keys key key_len ref rows Extra
@@ -609,7 +609,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN
SELECT * FROM City WHERE Name LIKE 'P%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 235 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 235 Using where
EXPLAIN
SELECT * FROM City
WHERE ((Population > 101000 AND Population < 102000) AND
@@ -680,23 +680,23 @@ CREATE INDEX CountryPopulation ON City(Country,Population);
EXPLAIN
SELECT * FROM City WHERE Name LIKE 'Pas%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 8 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 8 Using where
EXPLAIN
SELECT * FROM City WHERE Name LIKE 'P%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 235 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 235 Using where
EXPLAIN
SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 80 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 80 Using where
EXPLAIN
SELECT * FROM City WHERE Country='USA';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref Country,CountryPopulation Country 3 const 274 Using index condition
+1 SIMPLE City ref Country,CountryPopulation Country 3 const 274 Using where
EXPLAIN
SELECT * FROM City WHERE Country='FIN';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref Country,CountryPopulation Country 3 const 7 Using index condition
+1 SIMPLE City ref Country,CountryPopulation Country 3 const 7 Using where
EXPLAIN
SELECT * FROM City
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
@@ -708,7 +708,7 @@ SELECT * FROM City
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
AND Country='FIN';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 7 Using index condition; Using where
+1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 7 Using where
SELECT * FROM City
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
AND Country='USA';
@@ -753,15 +753,15 @@ CREATE INDEX CountryName ON City(Country,Name);
EXPLAIN
SELECT * FROM City WHERE Country='USA';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 274 Using index condition
+1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 274 Using where
EXPLAIN
SELECT * FROM City WHERE Country='FIN';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 7 Using index condition
+1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 7 Using where
EXPLAIN
SELECT * FROM City WHERE Country='BRA';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 250 Using index condition
+1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 250 Using where
EXPLAIN
SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800;
id select_type table type possible_keys key key_len ref rows Extra
@@ -789,15 +789,15 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN
SELECT * FROM City WHERE (Population > 101000 AND Population < 102000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 38 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 38 Using where
EXPLAIN
SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Population Population 4 NULL 80 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Population Population 4 NULL 80 Using where
EXPLAIN
SELECT * FROM City WHERE Name LIKE 'Pa%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range Name Name 35 NULL 71 Using index condition; Rowid-ordered scan
+1 SIMPLE City range Name Name 35 NULL 71 Using where
EXPLAIN
SELECT * FROM City
WHERE ((Population > 101000 AND Population < 102000) OR
@@ -818,7 +818,7 @@ WHERE ((Population > 101000 AND Population < 110000) OR
ID BETWEEN 3500 AND 3800) AND Country='FIN'
AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName Country 3 const 7 Using index condition; Using where
+1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName Country 3 const 7 Using where
SELECT * FROM City USE INDEX ()
WHERE ((Population > 101000 AND Population < 102000) OR
ID BETWEEN 3790 AND 3800) AND Country='USA'
@@ -950,14 +950,14 @@ WHERE ((Population > 101000 AND Population < 11000) OR
ID BETWEEN 3500 AND 3800) AND Country='USA'
AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName 38 NULL 18 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName 38 NULL 18 Using where
EXPLAIN
SELECT * FROM City
WHERE ((Population > 101000 AND Population < 11000) OR
ID BETWEEN 3500 AND 3800) AND Country='USA'
AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName Name 35 NULL 1 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName Name 35 NULL 1 Using where
SELECT * FROM City USE INDEX ()
WHERE ((Population > 101000 AND Population < 11000) OR
ID BETWEEN 3500 AND 3800) AND Country='USA'
@@ -1378,5 +1378,42 @@ SELECT * FROM t1,t2,t3
WHERE (t2.f3 = 1 OR t3.f1=t2.f1) AND t3.f1 <> t2.f2 AND t3.f2 = t2.f4;
f1 f1 f2 f3 f4 f1 f2
DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (
+a int, b int, c int, d int,
+PRIMARY KEY(b), INDEX idx1(d), INDEX idx2(d,b,c)
+);
+INSERT INTO t1 VALUES
+(0,58,7,7),(0,63,2,0),(0,64,186,8),(0,65,1,-2), (0,71,190,-3),
+(0,72,321,-7),(0,73,0,3),(0,74,5,25),(0,75,5,3);
+SET SESSION optimizer_switch='index_merge_sort_union=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 9 Using where
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+a b c d
+0 58 7 7
+0 64 186 8
+0 73 0 3
+0 74 5 25
+0 75 5 3
+SET SESSION optimizer_switch='index_merge_sort_union=on';
+EXPLAIN
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL PRIMARY,idx1,idx2 NULL NULL NULL 9 Using where
+SELECT * FROM t1
+WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+a b c d
+0 58 7 7
+0 64 186 8
+0 73 0 3
+0 74 5 25
+0 75 5 3
+SET SESSION optimizer_switch=DEFAULT;
+DROP TABLE t1;
set session optimizer_switch='index_merge_sort_intersection=default';
SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 9a4d521293a..fde22cb20fb 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -185,37 +185,37 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
fld1 fld3
-012001 flanking
-013602 foldout
-013606 fingerings
+218401 faithful
018007 fanatic
+228311 fated
018017 featherweight
-018054 fetters
-018103 flint
-018104 flopping
-036002 funereal
+218022 feed
+088303 feminine
+058004 Fenton
038017 fetched
+018054 fetters
+208101 fiftieth
+238007 filial
+013606 fingerings
+218008 finishers
038205 firearm
-058004 Fenton
-088303 feminine
-186002 freakish
-188007 flurried
188505 fitting
-198006 furthermore
202301 Fitzpatrick
-208101 fiftieth
-208113 freest
-218008 finishers
-218022 feed
-218401 faithful
+238008 fixedly
+012001 flanking
+018103 flint
+018104 flopping
+188007 flurried
+013602 foldout
226205 foothill
-226209 furnishings
+232102 forgivably
228306 forthcoming
-228311 fated
+186002 freakish
+208113 freest
231315 freezes
-232102 forgivably
-238007 filial
-238008 fixedly
+036002 funereal
+226209 furnishings
+198006 furthermore
select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
fld3
select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
@@ -2394,6 +2394,7 @@ CREATE TABLE t1 ( a BLOB, INDEX (a(20)) );
CREATE TABLE t2 ( a BLOB, INDEX (a(20)) );
INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five');
INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
+INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
@@ -3417,7 +3418,7 @@ SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
DROP TABLE t1,t2;
CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
INSERT t1 SET i = 0;
@@ -3453,7 +3454,7 @@ In next EXPLAIN, B.rows must be exactly 10:
explain select * from t2 A, t2 B where A.a=5 and A.b=5 and A.C<5
and B.a=5 and B.b=A.e and (B.b =1 or B.b = 3 or B.b=5);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE A range PRIMARY PRIMARY 12 NULL 4 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE A range PRIMARY PRIMARY 12 NULL 4 Using where
1 SIMPLE B ref PRIMARY PRIMARY 8 const,test.A.e 10
drop table t1, t2;
CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX(b));
@@ -3467,12 +3468,12 @@ INSERT INTO t2 VALUES
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
1 SIMPLE t2 ref c c 5 test.t1.a 2
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
1 SIMPLE t2 ref c c 5 test.t1.a 2
DROP TABLE t1, t2;
create table t1 (
@@ -3562,19 +3563,19 @@ EXPLAIN SELECT t2.*
FROM t1 JOIN t2 ON t2.fk=t1.pk
WHERE t2.fk < 'c' AND t2.pk=t1.fk;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using where
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
EXPLAIN SELECT t2.*
FROM t1 JOIN t2 ON t2.fk=t1.pk
WHERE t2.fk BETWEEN 'a' AND 'b' AND t2.pk=t1.fk;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
EXPLAIN SELECT t2.*
FROM t1 JOIN t2 ON t2.fk=t1.pk
WHERE t2.fk IN ('a','b') AND t2.pk=t1.fk;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
DROP TABLE t1,t2;
CREATE TABLE t1 (a int, b varchar(20) NOT NULL, PRIMARY KEY(a));
@@ -3608,7 +3609,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
t3.a=t2.a AND t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si si 5 NULL 4 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 range si si 5 NULL 4 Using where
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
EXPLAIN
SELECT t3.a FROM t1,t2,t3
@@ -3616,7 +3617,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
t3.a=t2.a AND t3.c IN ('bb','ee') ;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si,ai si 5 NULL 4 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 range si,ai si 5 NULL 4 Using where
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
EXPLAIN
SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
@@ -3624,7 +3625,7 @@ WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si si 5 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 range si si 5 NULL 2 Using where
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
EXPLAIN
SELECT t3.a FROM t1,t2,t3
@@ -3632,7 +3633,7 @@ WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si,ai si 5 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 range si,ai si 5 NULL 2 Using where
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
DROP TABLE t1,t2,t3;
CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int);
@@ -3752,7 +3753,7 @@ AND t1.ts BETWEEN t2.dt1 AND t2.dt2
AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31";
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t1 range ts ts 4 NULL 1 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range ts ts 4 NULL 1 Using where
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30
AND t1.ts BETWEEN t2.dt1 AND t2.dt2
AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31";
@@ -4377,12 +4378,12 @@ CREATE TABLE t1 (a INT KEY, b INT);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
DROP TABLE t1;
@@ -4895,6 +4896,7 @@ INSERT INTO t3 VALUES
(4,'z'), (3,'zzz'), (5,'zzzzz'), (3,'z'), (4,'zzz'), (3,'zzzz'),
(9,'zzzzz'), (2,'zzz'), (1,'zzzz'), (9,'zzz'), (1,'zzzz'), (5,'zzzzz'),
(4,'zzz'), (3,'zzzz'), (5,'zzzz'), (3,'zzz'), (4,'zz'), (3,'zzzzz');
+set @tmp= @@optimizer_switch;
SET SESSION optimizer_switch='index_condition_pushdown=off';
EXPLAIN SELECT * from t1,t2,t3 WHERE t3.a3=t1.a1 AND t2.a2=t1.a1;
id select_type table type possible_keys key key_len ref rows Extra
@@ -4974,7 +4976,7 @@ a1 b1 a2 b2 a3 b3
2 xx 2 y 2 zzzz
2 xx 2 yy 2 zz
2 xx 2 yy 2 zzz
-SET SESSION optimizer_switch=DEFAULT;
+SET SESSION optimizer_switch=@tmp;
DROP TABLE t1,t2,t3;
#
# Bug #707555: crash with equality substitution in ref
@@ -5030,3 +5032,40 @@ SELECT * FROM t1 WHERE a = b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
DROP TABLE t1;
+#
+# lp:822760 Wrong result with view + invalid dates
+#
+CREATE TABLE t1 (f1 date);
+INSERT IGNORE INTO t1 VALUES ('0000-00-00');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t1 HAVING f1 = 'zz';
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+SELECT * FROM t1 HAVING f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'aa'
+SELECT * FROM t1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+SELECT * FROM t1 WHERE f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+Warning 1292 Incorrect datetime value: 'zz'
+SELECT * FROM v1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+DROP TABLE t1;
+DROP VIEW v1;
diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result
index 0f591570a99..1c36b1e99cd 100644
--- a/mysql-test/r/select_jcl6.result
+++ b/mysql-test/r/select_jcl6.result
@@ -1,6 +1,8 @@
set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
+set @@optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set join_cache_level=6;
show variables like 'join_cache_level';
Variable_name Value
@@ -2401,6 +2403,7 @@ CREATE TABLE t1 ( a BLOB, INDEX (a(20)) );
CREATE TABLE t2 ( a BLOB, INDEX (a(20)) );
INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five');
INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
+INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
@@ -3424,7 +3427,7 @@ SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Rowid-ordered scan
DROP TABLE t1,t2;
CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
INSERT t1 SET i = 0;
@@ -4902,6 +4905,7 @@ INSERT INTO t3 VALUES
(4,'z'), (3,'zzz'), (5,'zzzzz'), (3,'z'), (4,'zzz'), (3,'zzzz'),
(9,'zzzzz'), (2,'zzz'), (1,'zzzz'), (9,'zzz'), (1,'zzzz'), (5,'zzzzz'),
(4,'zzz'), (3,'zzzz'), (5,'zzzz'), (3,'zzz'), (4,'zz'), (3,'zzzzz');
+set @tmp= @@optimizer_switch;
SET SESSION optimizer_switch='index_condition_pushdown=off';
EXPLAIN SELECT * from t1,t2,t3 WHERE t3.a3=t1.a1 AND t2.a2=t1.a1;
id select_type table type possible_keys key key_len ref rows Extra
@@ -4981,7 +4985,7 @@ a1 b1 a2 b2 a3 b3
2 xx 2 y 2 zzzz
2 xx 2 yy 2 zz
2 xx 2 yy 2 zzz
-SET SESSION optimizer_switch=DEFAULT;
+SET SESSION optimizer_switch=@tmp;
DROP TABLE t1,t2,t3;
#
# Bug #707555: crash with equality substitution in ref
@@ -5037,6 +5041,43 @@ SELECT * FROM t1 WHERE a = b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
DROP TABLE t1;
+#
+# lp:822760 Wrong result with view + invalid dates
+#
+CREATE TABLE t1 (f1 date);
+INSERT IGNORE INTO t1 VALUES ('0000-00-00');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t1 HAVING f1 = 'zz';
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+SELECT * FROM t1 HAVING f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'aa'
+SELECT * FROM t1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+SELECT * FROM t1 WHERE f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+Warning 1292 Incorrect datetime value: 'zz'
+SELECT * FROM v1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+DROP TABLE t1;
+DROP VIEW v1;
set join_cache_level=default;
show variables like 'join_cache_level';
Variable_name Value
diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result
index 9a4d521293a..fde22cb20fb 100644
--- a/mysql-test/r/select_pkeycache.result
+++ b/mysql-test/r/select_pkeycache.result
@@ -185,37 +185,37 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index
select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%';
fld1 fld3
-012001 flanking
-013602 foldout
-013606 fingerings
+218401 faithful
018007 fanatic
+228311 fated
018017 featherweight
-018054 fetters
-018103 flint
-018104 flopping
-036002 funereal
+218022 feed
+088303 feminine
+058004 Fenton
038017 fetched
+018054 fetters
+208101 fiftieth
+238007 filial
+013606 fingerings
+218008 finishers
038205 firearm
-058004 Fenton
-088303 feminine
-186002 freakish
-188007 flurried
188505 fitting
-198006 furthermore
202301 Fitzpatrick
-208101 fiftieth
-208113 freest
-218008 finishers
-218022 feed
-218401 faithful
+238008 fixedly
+012001 flanking
+018103 flint
+018104 flopping
+188007 flurried
+013602 foldout
226205 foothill
-226209 furnishings
+232102 forgivably
228306 forthcoming
-228311 fated
+186002 freakish
+208113 freest
231315 freezes
-232102 forgivably
-238007 filial
-238008 fixedly
+036002 funereal
+226209 furnishings
+198006 furthermore
select fld3 from t2 where fld3 like "L%" and fld3 = "ok";
fld3
select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
@@ -2394,6 +2394,7 @@ CREATE TABLE t1 ( a BLOB, INDEX (a(20)) );
CREATE TABLE t2 ( a BLOB, INDEX (a(20)) );
INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five');
INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
+INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 5
@@ -3417,7 +3418,7 @@ SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where
DROP TABLE t1,t2;
CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
INSERT t1 SET i = 0;
@@ -3453,7 +3454,7 @@ In next EXPLAIN, B.rows must be exactly 10:
explain select * from t2 A, t2 B where A.a=5 and A.b=5 and A.C<5
and B.a=5 and B.b=A.e and (B.b =1 or B.b = 3 or B.b=5);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE A range PRIMARY PRIMARY 12 NULL 4 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE A range PRIMARY PRIMARY 12 NULL 4 Using where
1 SIMPLE B ref PRIMARY PRIMARY 8 const,test.A.e 10
drop table t1, t2;
CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX(b));
@@ -3467,12 +3468,12 @@ INSERT INTO t2 VALUES
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
1 SIMPLE t2 ref c c 5 test.t1.a 2
EXPLAIN
SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
1 SIMPLE t2 ref c c 5 test.t1.a 2
DROP TABLE t1, t2;
create table t1 (
@@ -3562,19 +3563,19 @@ EXPLAIN SELECT t2.*
FROM t1 JOIN t2 ON t2.fk=t1.pk
WHERE t2.fk < 'c' AND t2.pk=t1.fk;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 3 Using where
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
EXPLAIN SELECT t2.*
FROM t1 JOIN t2 ON t2.fk=t1.pk
WHERE t2.fk BETWEEN 'a' AND 'b' AND t2.pk=t1.fk;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
EXPLAIN SELECT t2.*
FROM t1 JOIN t2 ON t2.fk=t1.pk
WHERE t2.fk IN ('a','b') AND t2.pk=t1.fk;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 12 NULL 2 Using where
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 18 test.t1.fk 1 Using where
DROP TABLE t1,t2;
CREATE TABLE t1 (a int, b varchar(20) NOT NULL, PRIMARY KEY(a));
@@ -3608,7 +3609,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
t3.a=t2.a AND t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si si 5 NULL 4 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 range si si 5 NULL 4 Using where
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
EXPLAIN
SELECT t3.a FROM t1,t2,t3
@@ -3616,7 +3617,7 @@ WHERE t1.id = 8 AND t2.i BETWEEN t1.b AND t1.e AND
t3.a=t2.a AND t3.c IN ('bb','ee') ;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si,ai si 5 NULL 4 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 range si,ai si 5 NULL 4 Using where
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
EXPLAIN
SELECT t3.a FROM t1,t2 FORCE INDEX (si),t3
@@ -3624,7 +3625,7 @@ WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si si 5 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 range si si 5 NULL 2 Using where
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
EXPLAIN
SELECT t3.a FROM t1,t2,t3
@@ -3632,7 +3633,7 @@ WHERE t1.id = 8 AND (t2.i=t1.b OR t2.i=t1.e) AND t3.a=t2.a AND
t3.c IN ('bb','ee');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t2 range si,ai si 5 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t2 range si,ai si 5 NULL 2 Using where
1 SIMPLE t3 eq_ref PRIMARY,ci PRIMARY 4 test.t2.a 1 Using where
DROP TABLE t1,t2,t3;
CREATE TABLE t1 ( f1 int primary key, f2 int, f3 int, f4 int, f5 int, f6 int, checked_out int);
@@ -3752,7 +3753,7 @@ AND t1.ts BETWEEN t2.dt1 AND t2.dt2
AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31";
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1
-1 SIMPLE t1 range ts ts 4 NULL 1 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range ts ts 4 NULL 1 Using where
SELECT * FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=30
AND t1.ts BETWEEN t2.dt1 AND t2.dt2
AND t1.ts BETWEEN "2006-01-01" AND "2006-12-31";
@@ -4377,12 +4378,12 @@ CREATE TABLE t1 (a INT KEY, b INT);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
DROP TABLE t1;
@@ -4895,6 +4896,7 @@ INSERT INTO t3 VALUES
(4,'z'), (3,'zzz'), (5,'zzzzz'), (3,'z'), (4,'zzz'), (3,'zzzz'),
(9,'zzzzz'), (2,'zzz'), (1,'zzzz'), (9,'zzz'), (1,'zzzz'), (5,'zzzzz'),
(4,'zzz'), (3,'zzzz'), (5,'zzzz'), (3,'zzz'), (4,'zz'), (3,'zzzzz');
+set @tmp= @@optimizer_switch;
SET SESSION optimizer_switch='index_condition_pushdown=off';
EXPLAIN SELECT * from t1,t2,t3 WHERE t3.a3=t1.a1 AND t2.a2=t1.a1;
id select_type table type possible_keys key key_len ref rows Extra
@@ -4974,7 +4976,7 @@ a1 b1 a2 b2 a3 b3
2 xx 2 y 2 zzzz
2 xx 2 yy 2 zz
2 xx 2 yy 2 zzz
-SET SESSION optimizer_switch=DEFAULT;
+SET SESSION optimizer_switch=@tmp;
DROP TABLE t1,t2,t3;
#
# Bug #707555: crash with equality substitution in ref
@@ -5030,3 +5032,40 @@ SELECT * FROM t1 WHERE a = b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 1
DROP TABLE t1;
+#
+# lp:822760 Wrong result with view + invalid dates
+#
+CREATE TABLE t1 (f1 date);
+INSERT IGNORE INTO t1 VALUES ('0000-00-00');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t1 HAVING f1 = 'zz';
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+SELECT * FROM t1 HAVING f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'aa'
+SELECT * FROM t1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+SELECT * FROM t1 WHERE f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+Warning 1292 Incorrect datetime value: 'zz'
+SELECT * FROM v1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+f1
+0000-00-00
+Warnings:
+Warning 1292 Incorrect datetime value: 'zz'
+Warning 1292 Incorrect datetime value: 'aa'
+DROP TABLE t1;
+DROP VIEW v1;
diff --git a/mysql-test/r/select_safe.result b/mysql-test/r/select_safe.result
index 26fb008c2a0..39ce1fd00dd 100644
--- a/mysql-test/r/select_safe.result
+++ b/mysql-test/r/select_safe.result
@@ -64,14 +64,16 @@ analyze table t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a");
+insert into t1 values (null,"b"),(null,"b"),(null,"c"),(null,"c"),(null,"d"),(null,"d"),(null,"e"),(null,"e"),(null,"a"),(null,"e");
+insert into t1 values (null,"x"),(null,"x"),(null,"y"),(null,"y"),(null,"z"),(null,"z"),(null,"v"),(null,"v"),(null,"a"),(null,"v");
explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL b NULL NULL NULL 21 Using where
+1 SIMPLE t1 ALL b NULL NULL NULL 41 Using where
1 SIMPLE t2 ref b b 21 test.t1.b 6
set MAX_SEEKS_FOR_KEY=1;
explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL b NULL NULL NULL 21 Using where
+1 SIMPLE t1 ALL b NULL NULL NULL 41 Using where
1 SIMPLE t2 ref b b 21 test.t1.b 6
SET MAX_SEEKS_FOR_KEY=DEFAULT;
drop table t1;
diff --git a/mysql-test/r/sp-threads.result b/mysql-test/r/sp-threads.result
index d974cfb9605..6f78137dd6a 100644
--- a/mysql-test/r/sp-threads.result
+++ b/mysql-test/r/sp-threads.result
@@ -33,11 +33,11 @@ call bug9486();
lock tables t2 write;
call bug9486();
show processlist;
-Id User Host db Command Time State Info
-# root localhost test Sleep # NULL
-# root localhost test Query # Table lock update t1, t2 set val= 1 where id1=id2
-# root localhost test Query # NULL show processlist
-# root localhost test Sleep # NULL
+Id User Host db Command Time State Info Progress
+# root localhost test Sleep # NULL 0.000
+# root localhost test Query # Table lock update t1, t2 set val= 1 where id1=id2 0.000
+# root localhost test Query # NULL show processlist 0.000
+# root localhost test Sleep # NULL 0.000
unlock tables;
drop procedure bug9486;
drop table t1, t2;
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 50dd2ae7047..ffb2dd1819c 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -6420,16 +6420,16 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref c1 c1 5 const 1 Using index
EXPLAIN SELECT * FROM t1 WHERE c1=f1();
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c1 c1 5 const 1 Using index
+1 SIMPLE t1 ref c1 c1 5 const 0 Using index
EXPLAIN SELECT * FROM v1 WHERE c1=1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref c1 c1 5 const 1 Using index
EXPLAIN SELECT * FROM v1 WHERE c1=f1();
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c1 c1 5 const 1 Using index
+1 SIMPLE t1 ref c1 c1 5 const 0 Using index
EXPLAIN SELECT * FROM t1 WHERE c1=f2(10);
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c1 c1 5 const 1 Using index
+1 SIMPLE t1 ref c1 c1 5 const 0 Using index
EXPLAIN SELECT * FROM t1 WHERE c1=f2(c1);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL c1 5 NULL 5 Using where; Using index
diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result
index ce3acba9b8a..2c88345646c 100644
--- a/mysql-test/r/status.result
+++ b/mysql-test/r/status.result
@@ -156,25 +156,33 @@ Variable_name Value
Com_show_status 3
show status like 'hand%write%';
Variable_name Value
+Handler_tmp_write 0
Handler_write 0
show status like '%tmp%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 0
+Handler_tmp_update 0
+Handler_tmp_write 0
+Rows_tmp_read 5
show status like 'hand%write%';
Variable_name Value
+Handler_tmp_write 0
Handler_write 0
show status like '%tmp%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 0
+Handler_tmp_update 0
+Handler_tmp_write 0
+Rows_tmp_read 13
show status like 'com_show_status';
Variable_name Value
Com_show_status 8
rnd_diff tmp_table_diff
-20 8
+28 8
flush status;
show status like 'Com%function';
Variable_name Value
@@ -238,5 +246,57 @@ SELECT 9;
9
DROP PROCEDURE p1;
DROP FUNCTION f1;
+flush status;
+create table t1 (a int not null auto_increment primary key, g int, b blob);
+insert into t1 (g,b) values (1,'a'), (2, 'b'), (3, 'b'), (1, 'c');
+select * from t1;
+a g b
+1 1 a
+2 2 b
+3 3 b
+4 1 c
+select b, count(*) from t1 group by b;
+b count(*)
+a 1
+b 2
+c 1
+select g, count(*) from t1 group by g;
+g count(*)
+1 2
+2 1
+3 1
+show status like 'Row%';
+Variable_name Value
+Rows_read 12
+Rows_sent 10
+Rows_tmp_read 14
+show status like 'Handler%';
+Variable_name Value
+Handler_commit 0
+Handler_delete 0
+Handler_discover 0
+Handler_prepare 0
+Handler_read_first 0
+Handler_read_key 4
+Handler_read_next 0
+Handler_read_prev 0
+Handler_read_rnd 7
+Handler_read_rnd_next 23
+Handler_rollback 0
+Handler_savepoint 0
+Handler_savepoint_rollback 0
+Handler_tmp_update 2
+Handler_tmp_write 7
+Handler_update 0
+Handler_write 4
+show status like '%tmp%';
+Variable_name Value
+Created_tmp_disk_tables 1
+Created_tmp_files 0
+Created_tmp_tables 2
+Handler_tmp_update 2
+Handler_tmp_write 7
+Rows_tmp_read 34
+drop table t1;
set @@global.concurrent_insert= @old_concurrent_insert;
SET GLOBAL log_output = @old_log_output;
diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result
index 636eeabfffc..bc5f0aff7e4 100644
--- a/mysql-test/r/status_user.result
+++ b/mysql-test/r/status_user.result
@@ -94,6 +94,7 @@ show status like "rows%";
Variable_name Value
Rows_read 6
Rows_sent 1
+Rows_tmp_read 0
show status like "ha%";
Variable_name Value
Handler_commit 19
@@ -109,6 +110,8 @@ Handler_read_rnd_next 5
Handler_rollback 2
Handler_savepoint 0
Handler_savepoint_rollback 0
+Handler_tmp_update 0
+Handler_tmp_write 0
Handler_update 5
Handler_write 7
select variable_value - @global_read_key as "handler_read_key" from information_schema.global_status where variable_name="handler_read_key";
@@ -133,7 +136,7 @@ CONCURRENT_CONNECTIONS 0
ROWS_READ 6
ROWS_SENT 2
ROWS_DELETED 1
-ROWS_INSERTED 8
+ROWS_INSERTED 7
ROWS_UPDATED 5
SELECT_COMMANDS 3
UPDATE_COMMANDS 11
@@ -150,7 +153,7 @@ CONCURRENT_CONNECTIONS 0
ROWS_READ 6
ROWS_SENT 2
ROWS_DELETED 1
-ROWS_INSERTED 8
+ROWS_INSERTED 7
ROWS_UPDATED 5
SELECT_COMMANDS 3
UPDATE_COMMANDS 11
@@ -183,4 +186,33 @@ bytes_sent <> 0, binlog_bytes_written <> 0
from information_schema.client_statistics;
connected_time <> 0 busy_time <> 0 bytes_received <> 0 bytes_sent <> 0 binlog_bytes_written <> 0
1 1 1 1 1
+create table t1 (a int) engine=innodb;
+select @@in_transaction;
+@@in_transaction
+0
+begin;
+select @@in_transaction;
+@@in_transaction
+1
+insert into t1 values (1);
+select @@in_transaction;
+@@in_transaction
+1
+commit;
+select @@in_transaction;
+@@in_transaction
+0
+set @@autocommit=0;
+select @@in_transaction;
+@@in_transaction
+0
+insert into t1 values (2);
+select @@in_transaction;
+@@in_transaction
+1
+set @@autocommit=1;
+select @@in_transaction;
+@@in_transaction
+0
+drop table t1;
set @@global.general_log=@save_general_log;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index c84d4538a88..f84e0246969 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1,7 +1,9 @@
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
drop view if exists v2;
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+set @subselect_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
+"semijoin=on,firstmatch=on,loosescan=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
select (select 2);
(select 2)
2
@@ -202,10 +204,11 @@ select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
(select * from t2 where a>1) as tt;
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 <derived3> ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
Warnings:
-Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a` > 1)
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
a
2
@@ -226,7 +229,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t4.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t4`.`b` AS `b`,(select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+Note 1003 select `test`.`t4`.`b` AS `b`,<expr_cache><`test`.`t4`.`a`>((select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`)) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
select * from t3 where exists (select * from t2 where t2.b=t3.a);
a
7
@@ -272,7 +275,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2);
a
7
@@ -364,12 +367,12 @@ INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where; Using index
4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
-2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where
3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
Warnings:
-Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
+Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
ERROR 21000: Operand should contain 1 column(s)
@@ -540,18 +543,24 @@ SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT
numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY t1 ref PRIMARY PRIMARY 3 const 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select 1 from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
ERROR 21000: Subquery returns more than 1 row
EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where multiple equal(1, `test`.`t1`.`numeropost`)
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using index
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select 3 AS `numreponse` from `test`.`t1` where ((3 = 3))
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
drop table t1;
CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1);
@@ -913,6 +922,131 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
drop table t1,t2,t3;
+# check correct NULL Processing for normal IN/ALL/ANY
+# and 2 ways of max/min optimization
+create table t1 (a int);
+insert into t1 values (1), (100), (NULL), (1000);
+create table t2 (a int not null);
+# subselect returns empty set (for NULL and non-NULL left part)
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 1
+100 1
+NULL 1
+1000 1
+select a from t1 where a in (select * from t2);
+a
+select a from t1 where a > any (select * from t2);
+a
+select a from t1 where a > all (select * from t2);
+a
+1
+100
+NULL
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+select a from t1 where a > any (select * from t2 group by a);
+a
+select a from t1 where a > all (select * from t2 group by a);
+a
+1
+100
+NULL
+1000
+insert into t2 values (1),(200);
+# sebselect returns non-empty set without NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 0
+NULL NULL
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 1
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+1000
+drop table t2;
+create table t2 (a int);
+insert into t2 values (1),(NULL),(200);
+# sebselect returns non-empty set with NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 NULL
+NULL NULL
+1000 NULL
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 NULL
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 NULL
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+drop table t1, t2;
create table t1 (a float);
select 10.5 IN (SELECT * from t1 LIMIT 1);
ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
@@ -1236,7 +1370,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using index condition
+1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using index condition
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
@@ -1342,7 +1476,7 @@ a
explain extended select * from t2 where t2.a in (select a from t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
-1 PRIMARY t1 ref a a 5 test.t2.a 100 100.00 Using index; FirstMatch(t2)
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using index; FirstMatch(t2)
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where (`test`.`t1`.`a` = `test`.`t2`.`a`)
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
@@ -1352,7 +1486,7 @@ a
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
-1 PRIMARY t1 ref a a 5 test.t2.a 100 100.00 Using where; Using index; FirstMatch(t2)
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
@@ -1363,7 +1497,7 @@ explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
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 11 100.00 Using index; FirstMatch(t2)
+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`))
insert into t1 values (3,31);
@@ -1379,7 +1513,7 @@ a
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
-1 PRIMARY t1 ref a a 5 test.t2.a 100 100.00 Using where; Using index; FirstMatch(t2)
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
drop table t0, t1, t2, t3;
@@ -1416,7 +1550,7 @@ INSERT INTO t1 VALUES ('z','?');
select * from t1 where s1 > (select max(s2) from t1);
ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
select * from t1 where s1 > any (select max(s2) from t1);
-ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+ERROR HY000: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '<'
drop table t1;
create table t1(toid int,rd int);
create table t2(userid int,pmnew int,pmtotal int);
@@ -1492,7 +1626,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < 'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`)))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
drop table t1,t2;
-create table t2 (a int, b int);
+create table t2 (a int, b int not null);
create table t3 (a int);
insert into t3 values (6),(7),(3);
select * from t3 where a >= all (select b from t2);
@@ -1505,7 +1639,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2);
a
explain extended select * from t3 where a >= some (select b from t2);
@@ -1513,7 +1647,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
@@ -1524,7 +1658,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < <max>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select NULL from `test`.`t2` group by 1) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2 group by 1);
a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
@@ -1532,7 +1666,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= <min>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(<min>(select NULL from `test`.`t2` group by 1) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
@@ -1540,7 +1674,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
@@ -1548,7 +1682,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
select * from t3 where NULL >= some (select b from t2);
a
explain extended select * from t3 where NULL >= some (select b from t2);
@@ -1556,7 +1690,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
@@ -1564,7 +1698,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
a
@@ -1575,7 +1709,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= <cache>(`test`.`t3`.`a`))))
drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
@@ -1626,7 +1760,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION t1 system NULL NULL NULL NULL 1 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',('f' > <min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`))))
+Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',(<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`) < 'f')))
drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
@@ -2829,7 +2963,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
2 DEPENDENT SUBQUERY 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`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
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
@@ -2841,7 +2975,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
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; Using temporary
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
DROP TABLE t1,t2;
CREATE TABLE t1 (a char(5), b char(5));
INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
@@ -2957,7 +3091,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -2969,7 +3103,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -4030,7 +4164,7 @@ CREATE TABLE t1 (a int, b int, KEY (a));
INSERT INTO t1 VALUES (1,1),(2,1);
EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
+1 PRIMARY t1 ref a a 5 const 0 Using where; Using index
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
DROP TABLE t1;
CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
@@ -4803,7 +4937,6 @@ SELECT 1 FROM t1 GROUP BY
1
1
DROP TABLE t1;
-set @@optimizer_switch=@save_optimizer_switch;
#
# Bug #49512 : subquery with aggregate function crash
# subselect_single_select_engine::exec()
@@ -5105,6 +5238,167 @@ SELECT 1 as foo FROM t1 WHERE a < SOME
);
foo
DROP TABLE t1;
+CREATE TABLE t1 (a int(11), b varchar(1));
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+delete from t1;
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+drop table t1;
+#
+# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ;
+INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0);
+DROP TABLE IF EXISTS t3;
+Warnings:
+Note 1051 Unknown table 't3'
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ;
+r
+NULL
+5
+NULL
+5
+DROP TABLE t1, t2, t3;
+End of 5.2 tests
#
# BUG#779885: Crash in eliminate_item_equal with materialization=on in
# maria-5.3
@@ -5126,4 +5420,246 @@ ON t2.f10 = t3.f10
);
f1
DROP TABLE t1,t2,t3;
+#
+# BUG LP:813473: Wrong result with outer join + NOT IN subquery
+# This bug is a duplicate of Bug#11764086 whose test case is added below
+#
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
+create table t3 (d int, e int);
+insert into t3 values (2, 9), (3,10);
+EXPLAIN
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b , t1.c) NOT IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b, t1.c) NOT IN (SELECT * from t3);
+b c
+9 NULL
+9 NULL
+drop table t1, t2, t3;
End of 5.3 tests
+End of 5.5 tests.
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+#
+# Bug#11764086: Null left operand to NOT IN in WHERE clause
+# behaves differently than real NULL
+#
+CREATE TABLE parent (id int);
+INSERT INTO parent VALUES (1), (2);
+CREATE TABLE child (parent_id int, other int);
+INSERT INTO child VALUES (1,NULL);
+# Offending query (c.parent_id is NULL for null-complemented rows only)
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id NOT IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+);
+id parent_id
+1 1
+2 NULL
+# Some syntactic variations with IS FALSE and IS NOT TRUE
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS NOT TRUE;
+id parent_id
+1 1
+2 NULL
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS FALSE;
+id parent_id
+1 1
+2 NULL
+DROP TABLE parent, child;
+# End of test for bug#11764086.
+#
+# BUG#50257: Missing info in REF column of the EXPLAIN
+# lines for subselects
+#
+CREATE TABLE t1 (a INT, b INT, INDEX (a));
+INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+
+EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ref a a 5 const 1
+
+EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 SUBQUERY t1 ref a a 5 const 1 Using index
+
+DROP TABLE t1;
+#
+# Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET ||
+# BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0), (1);
+CREATE TABLE t2(
+b TEXT,
+c INT,
+PRIMARY KEY (b(1))
+);
+INSERT INTO t2 VALUES ('a', 2), ('b', 3);
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ORDER BY b
+);
+1
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+GROUP BY b
+);
+1
+DROP TABLE t1, t2;
+#
+# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS)
+#
+CREATE TABLE t1 (f1 varchar(1));
+INSERT INTO t1 VALUES ('v'),('s');
+CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key));
+INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'),
+('d'),('y'),('t'),('d'),('s');
+SELECT table1.f1, table2.f1_key
+FROM t1 AS table1, t2 AS table2
+WHERE EXISTS
+(
+SELECT DISTINCT f1_key
+FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
+f1 f1_key
+v j
+s j
+v v
+s v
+v c
+s c
+v m
+s m
+v d
+s d
+v d
+s d
+v y
+s y
+v t
+s t
+v d
+s d
+v s
+s s
+explain SELECT table1.f1, table2.f1_key
+FROM t1 AS table1, t2 AS table2
+WHERE EXISTS
+(
+SELECT DISTINCT f1_key
+FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY table1 ALL NULL NULL NULL NULL 2
+1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
+DROP TABLE t1,t2;
+#
+# LP bug #826279: assertion failure with GROUP BY a result of subquery
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0), (0);
+CREATE TABLE t2 (a int, b int, c int);
+INSERT INTO t2 VALUES (10,7,0), (0,7,0);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,7), (0,7);
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+7 NULL
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+7 NULL
+7 10
+DROP TABLE t1,t2,t3;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+set optimizer_switch=@subselect_tmp;
diff --git a/mysql-test/r/subselect2.result b/mysql-test/r/subselect2.result
index 9d62d3a54f1..a7b6e40d9c9 100644
--- a/mysql-test/r/subselect2.result
+++ b/mysql-test/r/subselect2.result
@@ -1,4 +1,6 @@
drop table if exists t1, t2, t3, t4;
+set @subselect2_test_tmp=@@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
CREATE TABLE t1
(
DOCID VARCHAR(32)BINARY NOT NULL
@@ -123,14 +125,14 @@ DOCID DOCNAME DOCTYPEID FOLDERID AUTHOR CREATED TITLE SUBTITLE DOCABSTRACT PUBLI
c373e9f5ad07993f3859444553544200 Last Discussion c373e9f5ad079174ff17444553544200 c373e9f5ad0796c0eca4444553544200 Goldilocks 2003-06-09 11:21:06 Title: Last Discussion NULL Setting new abstract and keeping doc checked out 2003-06-09 10:51:26 2003-06-09 10:51:26 NULL NULL NULL 03eea05112b845949f3fd03278b5fe43 2003-06-09 11:21:06 admin 0 NULL Discussion NULL NULL
EXPLAIN SELECT t2.*, t4.DOCTYPENAME, t1.CONTENTSIZE,t1.MIMETYPE FROM t2 INNER JOIN t4 ON t2.DOCTYPEID = t4.DOCTYPEID LEFT OUTER JOIN t1 ON t2.DOCID = t1.DOCID WHERE t2.FOLDERID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID IN(SELECT t3.FOLDERID FROM t3 WHERE t3.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t3.FOLDERNAME = 'Level1') AND t3.FOLDERNAME = 'Level2') AND t3.FOLDERNAME = 'Level3') AND t3.FOLDERNAME = 'CopiedFolder') AND t3.FOLDERNAME = 'Movie Reviews') AND t2.DOCNAME = 'Last Discussion';
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 ALL DDOCTYPEID_IDX NULL NULL NULL 9 Using where
+1 PRIMARY t4 ALL PRIMARY NULL NULL NULL 10
+1 PRIMARY t2 ALL DDOCTYPEID_IDX,DFOLDERID_IDX NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 34 test.t2.DOCID 1
-1 PRIMARY t4 eq_ref PRIMARY PRIMARY 34 test.t2.DOCTYPEID 1
-2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 func 1 Using where
-2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
-2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
-2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
-2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
+1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t2.FOLDERID 1 Using where
+1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
+1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
+1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
+1 PRIMARY t3 eq_ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX PRIMARY 34 test.t3.PARENTID 1 Using where
drop table t1, t2, t3, t4;
CREATE TABLE t1 (a int(10) , PRIMARY KEY (a)) Engine=InnoDB;
INSERT INTO t1 VALUES (1),(2);
@@ -144,3 +146,4 @@ and t2.a='1' AND t1.a=t3.b) > 0;
a
2
DROP TABLE t1,t2,t3;
+set optimizer_switch=@subselect2_test_tmp;
diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result
index e88461173df..1279fc6b8f4 100644
--- a/mysql-test/r/subselect3.result
+++ b/mysql-test/r/subselect3.result
@@ -1,5 +1,6 @@
drop table if exists t0, t1, t2, t3, t4, t5, t11, t12, t21, t22;
-set @save_optimizer_switch=@@optimizer_switch;
+set @subselect3_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
create table t1 (oref int, grp int, ie int) ;
insert into t1 (oref, grp, ie) values
(1, 1, 1),
@@ -81,6 +82,7 @@ insert into t1 values
(2, 3),
(2, NULL),
(3, NULL);
+insert into t1 values (5, 7), (8, 9), (4, 1);
create table t2 (a int, oref int);
insert into t2 values (1, 1), (2,2), (NULL, 3), (NULL, 4);
select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
@@ -103,7 +105,7 @@ oref a
1 1
show status like '%Handler_read_rnd_next';
Variable_name Value
-Handler_read_rnd_next 11
+Handler_read_rnd_next 14
delete from t2;
insert into t2 values (NULL, 0),(NULL, 0), (NULL, 0), (NULL, 0);
set optimizer_switch='subquery_cache=off';
@@ -121,7 +123,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
-Handler_read_rnd_next 35
+Handler_read_rnd_next 50
select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z;
Z
No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.
@@ -247,7 +249,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 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`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`b`,`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`))))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<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 a checking NULL where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`))))))) AS `Z` from `test`.`t2`
select a,b, oref, (a,b) in (select a,b from t1 where c=t2.oref) Z from t2;
a b oref Z
NULL 1 100 0
@@ -264,7 +266,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 100 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`b`,`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(select `test`.`t1`.`a`,`test`.`t1`.`b` from `test`.`t1` join `test`.`t4` where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`)))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(select `test`.`t1`.`a`,`test`.`t1`.`b` from `test`.`t1` join `test`.`t4` where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`)))))) AS `Z` from `test`.`t2`
select a,b, oref,
(a,b) in (select a,b from t1,t4 where c=t2.oref) Z
from t2;
@@ -309,7 +311,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`.`b`,`test`.`t2`.`a`,`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`.`b` = 10) and (`test`.`t2`.`a` = 10))
drop table t1, t2;
create table t1 (oref char(4), grp int, ie int);
insert into t1 (oref, grp, ie) values
@@ -579,7 +581,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`.`b`,`test`.`t2`.`a`,`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`
+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`
drop table t1,t2;
create table t1 (oref char(4), grp int, ie int primary key);
insert into t1 (oref, grp, ie) values
@@ -698,7 +700,6 @@ a MAX(b) test
2 3 h
3 4 i
DROP TABLE t1, t2;
-set @save_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
CREATE TABLE t1 (a int);
CREATE TABLE t2 (b int, PRIMARY KEY(b));
@@ -1084,7 +1085,8 @@ a
17
18
19
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
explain select * from t1 where 2 in (select a from t0);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 11 Using where; FirstMatch
@@ -1114,8 +1116,9 @@ a
set @@optimizer_switch=@save_optimizer_switch;
explain select * from (select a from t0) X where a in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 11
-1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(t0)
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11
+1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(<derived2>)
+2 DERIVED t0 ALL NULL NULL NULL NULL 11
drop table t0, t1;
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
@@ -1133,9 +1136,9 @@ insert into t4 select a from t3;
explain select * from t3 where a in (select t1.kp1 from t1,t4 where kp1<20
and t4.pk=t1.c);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where
-1 PRIMARY t1 ref kp1 kp1 5 test.t3.a 1 Using where
-1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index; FirstMatch(t3)
+1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using where; LooseScan
+1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index; FirstMatch(t1)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
drop table t1, t3, t4;
create table t1 (a int) as select * from t0 where a < 5;
set @save_max_heap_table_size=@@max_heap_table_size;
@@ -1399,7 +1402,7 @@ drop table t1,t2,t3;
#
# BUG#47367 Crash in Name_resolution_context::process_error
#
-SET SESSION optimizer_switch = 'default,semijoin=off';
+SET SESSION optimizer_switch = 'semijoin=off';
CREATE TABLE t1 (f1 INTEGER);
CREATE TABLE t2 LIKE t1;
CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t1 WHERE f1 IN (SELECT f1 FROM t2); END|
@@ -1421,4 +1424,4 @@ CALL p1;
ERROR 42S22: Unknown column 'f1' in 'where clause'
DROP PROCEDURE p1;
DROP TABLE t1, t2;
-set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch=@subselect3_tmp;
diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result
index e254fad2300..15dd920d95d 100644
--- a/mysql-test/r/subselect3_jcl6.result
+++ b/mysql-test/r/subselect3_jcl6.result
@@ -1,12 +1,15 @@
set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set join_cache_level=6;
show variables like 'join_cache_level';
Variable_name Value
join_cache_level 6
drop table if exists t0, t1, t2, t3, t4, t5, t11, t12, t21, t22;
-set @save_optimizer_switch=@@optimizer_switch;
+set @subselect3_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
create table t1 (oref int, grp int, ie int) ;
insert into t1 (oref, grp, ie) values
(1, 1, 1),
@@ -88,6 +91,7 @@ insert into t1 values
(2, 3),
(2, NULL),
(3, NULL);
+insert into t1 values (5, 7), (8, 9), (4, 1);
create table t2 (a int, oref int);
insert into t2 values (1, 1), (2,2), (NULL, 3), (NULL, 4);
select oref, a, a in (select a from t1 where oref=t2.oref) Z from t2;
@@ -110,7 +114,7 @@ oref a
1 1
show status like '%Handler_read_rnd_next';
Variable_name Value
-Handler_read_rnd_next 11
+Handler_read_rnd_next 14
delete from t2;
insert into t2 values (NULL, 0),(NULL, 0), (NULL, 0), (NULL, 0);
set optimizer_switch='subquery_cache=off';
@@ -128,7 +132,7 @@ Handler_read_key 0
Handler_read_next 0
Handler_read_prev 0
Handler_read_rnd 0
-Handler_read_rnd_next 35
+Handler_read_rnd_next 50
select 'No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.' Z;
Z
No key lookups, seq reads: 29= 5 reads from t2 + 4 * 6 reads from t1.
@@ -254,7 +258,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 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`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`b`,`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`))))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<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 a checking NULL where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`))))))) AS `Z` from `test`.`t2`
select a,b, oref, (a,b) in (select a,b from t1 where c=t2.oref) Z from t2;
a b oref Z
NULL 1 100 0
@@ -271,7 +275,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 100 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
Note 1276 Field or reference 'test.t2.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`b`,`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(select `test`.`t1`.`a`,`test`.`t1`.`b` from `test`.`t1` join `test`.`t4` where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`)))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`b`,`test`.`t2`.`oref`>(<in_optimizer>((`test`.`t2`.`a`,`test`.`t2`.`b`),<exists>(select `test`.`t1`.`a`,`test`.`t1`.`b` from `test`.`t1` join `test`.`t4` where ((`test`.`t1`.`c` = `test`.`t2`.`oref`) and trigcond(((<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`b`) or isnull(`test`.`t1`.`b`)))) having (trigcond(<is_not_null_test>(`test`.`t1`.`a`)) and trigcond(<is_not_null_test>(`test`.`t1`.`b`)))))) AS `Z` from `test`.`t2`
select a,b, oref,
(a,b) in (select a,b from t1,t4 where c=t2.oref) Z
from t2;
@@ -316,7 +320,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`.`b`,`test`.`t2`.`a`,`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`.`b` = 10) and (`test`.`t2`.`a` = 10))
drop table t1, t2;
create table t1 (oref char(4), grp int, ie int);
insert into t1 (oref, grp, ie) values
@@ -586,7 +590,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`.`b`,`test`.`t2`.`a`,`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`
+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`
drop table t1,t2;
create table t1 (oref char(4), grp int, ie int primary key);
insert into t1 (oref, grp, ie) values
@@ -705,7 +709,6 @@ a MAX(b) test
2 3 h
3 4 i
DROP TABLE t1, t2;
-set @save_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
CREATE TABLE t1 (a int);
CREATE TABLE t2 (b int, PRIMARY KEY(b));
@@ -1091,7 +1094,8 @@ a
17
18
19
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
explain select * from t1 where 2 in (select a from t0);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 11 Using where; FirstMatch
@@ -1121,8 +1125,9 @@ a
set @@optimizer_switch=@save_optimizer_switch;
explain select * from (select a from t0) X where a in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 11
-1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(t0); Using join buffer (flat, BNL join)
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 11
+1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(<derived2>); Using join buffer (flat, BNL join)
+2 DERIVED t0 ALL NULL NULL NULL NULL 11
drop table t0, t1;
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
@@ -1140,9 +1145,9 @@ insert into t4 select a from t3;
explain select * from t3 where a in (select t1.kp1 from t1,t4 where kp1<20
and t4.pk=t1.c);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where
-1 PRIMARY t1 ref kp1 kp1 5 test.t3.a 1 Using where
-1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index; FirstMatch(t3)
+1 PRIMARY t1 range kp1 kp1 5 NULL 48 Using index condition; Using where; Rowid-ordered scan; LooseScan
+1 PRIMARY t4 eq_ref PRIMARY PRIMARY 4 test.t1.c 1 Using index; FirstMatch(t1)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where; Using join buffer (flat, BNL join)
drop table t1, t3, t4;
create table t1 (a int) as select * from t0 where a < 5;
set @save_max_heap_table_size=@@max_heap_table_size;
@@ -1406,7 +1411,7 @@ drop table t1,t2,t3;
#
# BUG#47367 Crash in Name_resolution_context::process_error
#
-SET SESSION optimizer_switch = 'default,semijoin=off';
+SET SESSION optimizer_switch = 'semijoin=off';
CREATE TABLE t1 (f1 INTEGER);
CREATE TABLE t2 LIKE t1;
CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t1 WHERE f1 IN (SELECT f1 FROM t2); END|
@@ -1428,7 +1433,7 @@ CALL p1;
ERROR 42S22: Unknown column 'f1' in 'where clause'
DROP PROCEDURE p1;
DROP TABLE t1, t2;
-set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch=@subselect3_tmp;
set join_cache_level=default;
show variables like 'join_cache_level';
Variable_name Value
diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result
index 5a382730a99..ddf339ba1b5 100644
--- a/mysql-test/r/subselect4.result
+++ b/mysql-test/r/subselect4.result
@@ -1,4 +1,7 @@
drop table if exists t1,t2,t3,t4,t5,t6;
+set @subselect4_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
#
# Bug #46791: Assertion failed:(table->key_read==0),function unknown
# function,file sql_base.cc
@@ -221,7 +224,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
-Note 1003 select <expr_cache><NULL>((select 1 from `test`.`t2` where 0)) AS `RESULT` from `test`.`t1`
+Note 1003 select <expr_cache><>((select 1 from `test`.`t2` where 0)) AS `RESULT` from `test`.`t1`
first equivalent variant
SELECT (SELECT 1 FROM t2 WHERE d = IFNULL(c,NULL)) AS RESULT FROM t1 GROUP BY c ;
RESULT
@@ -232,7 +235,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
-Note 1003 select <expr_cache><NULL>((select 1 from `test`.`t2` where 0)) AS `RESULT` from `test`.`t1` group by NULL
+Note 1003 select <expr_cache><>((select 1 from `test`.`t2` where 0)) AS `RESULT` from `test`.`t1` group by NULL
second equivalent variant
SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 GROUP BY c ;
RESULT
@@ -243,7 +246,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
-Note 1003 select <expr_cache><NULL>((select 1 from `test`.`t2` where 0)) AS `RESULT` from `test`.`t1` group by NULL
+Note 1003 select <expr_cache><>((select 1 from `test`.`t2` where 0)) AS `RESULT` from `test`.`t1` group by NULL
DROP TABLE t1,t2;
#
# BUG#45928 "Differing query results depending on MRR and
@@ -270,31 +273,6 @@ set @@session.optimizer_switch = @old_optimizer_switch,
@@session.engine_condition_pushdown = @old_engine_condition_pushdown;
DROP TABLE t1;
#
-# BUG#45863 "Assertion failed: (fixed == 0), function fix_fields(),
-# file item.cc, line 4448"
-#
-DROP TABLE IF EXISTS C, BB;
-CREATE TABLE C (
-varchar_nokey varchar(1) NOT NULL
-);
-INSERT INTO C VALUES
-('k'),('a'),(''),('u'),('e'),('v'),('i'),
-('t'),('u'),('f'),('u'),('m'),('j'),('f'),
-('v'),('j'),('g'),('e'),('h'),('z');
-CREATE TABLE BB (
-varchar_nokey varchar(1) NOT NULL
-);
-INSERT INTO BB VALUES ('i'),('t');
-SELECT varchar_nokey FROM C
-WHERE (varchar_nokey, OUTR) IN (SELECT varchar_nokey
-FROM BB);
-ERROR 21000: Operand should contain 2 column(s)
-SELECT varchar_nokey FROM C
-WHERE (varchar_nokey, OUTR) IN (SELECT varchar_nokey, varchar_nokey
-FROM BB);
-ERROR 42S22: Unknown column 'OUTR' in 'IN/ALL/ANY subquery'
-DROP TABLE C,BB;
-#
# During work with BUG#45863 I had problems with a query that was
# optimized differently in regular and prepared mode.
# Because there was a bug in one of the selected strategies, I became
@@ -731,7 +709,7 @@ WHERE f3 = (
SELECT t1.f3 FROM t1
WHERE ( t1.f10 ) IN ( SELECT f11 FROM t2 GROUP BY f11 ));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+1 PRIMARY t1 ref f3 f3 5 const 0 Using index condition
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
2 SUBQUERY <subquery3> eq_ref distinct_key distinct_key 5 test.t1.f10 1
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using temporary
@@ -746,7 +724,7 @@ WHERE f3 = (
SELECT f3 FROM t1
WHERE ( f10, f10 ) IN ( SELECT f11, f11 FROM t2 GROUP BY f11 ));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+1 PRIMARY t1 ref f3 f3 5 const 0 Using index condition
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
2 SUBQUERY <subquery3> eq_ref distinct_key distinct_key 10 test.t1.f10,test.t1.f10 1
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using temporary
@@ -1187,6 +1165,54 @@ set @@optimizer_switch='materialization=off,semijoin=on';
set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
#
+# LP BUG#777691 Wrong result with subqery in select list and subquery cache=off in maria-5.3
+#
+CREATE TABLE t1 ( f1 varchar(32)) ;
+INSERT INTO t1 VALUES ('b'),('x'),('c'),('x');
+CREATE TABLE t2 ( f2 int, f3 varchar(32)) ;
+INSERT INTO t2 VALUES (1,'x');
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off';
+EXPLAIN
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+f1 max_f2
+b NULL
+x 1
+c NULL
+x 1
+set @@optimizer_switch='materialization=on,in_to_exists=off,subquery_cache=off';
+EXPLAIN
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+f1 max_f2
+b NULL
+x 1
+c NULL
+x 1
+set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off';
+Even when t2 is not constant table, the result must be the same.
+INSERT INTO t2 VALUES (2,'y');
+EXPLAIN
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+f1 max_f2
+b NULL
+x 1
+c NULL
+x 1
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;
+#
# LP BUG#641203 Query returns rows where no result is expected (impossible WHERE)
#
CREATE TABLE t1 (c1 varchar(1) DEFAULT NULL);
@@ -1200,33 +1226,33 @@ EXPLAIN
SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY t2 ALL NULL NULL NULL NULL 2
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
c1 c1
EXPLAIN
SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY t2 ALL NULL NULL NULL NULL 2
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t1)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
SELECT * FROM t2 LEFT JOIN t1 ON t1.c1 WHERE 's' IN (SELECT c1 FROM t2);
c1 c1
EXPLAIN
SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 0 const row not found
-1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary; End temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
SELECT * FROM (t2 LEFT JOIN t1 ON t1.c1) LEFT JOIN t3 on t3.c1 WHERE 's' IN (SELECT c1 FROM t2);
c1 c1 c1
EXPLAIN
SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t4 index NULL PRIMARY 3 NULL 2 Using index
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Start temporary; End temporary
+1 PRIMARY t4 index NULL PRIMARY 3 NULL 2 Using index; Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
SELECT * FROM t4 LEFT JOIN t2 ON t4.c1 WHERE 's' IN (SELECT c1 FROM t2);
c1 c1
drop table t1, t2, t3, t4;
@@ -1303,7 +1329,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
3 SUBQUERY SQ1_t1 index NULL f4 5 NULL 2 Using index; Using temporary
-3 SUBQUERY SQ1_t3 index NULL f4 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
+3 SUBQUERY SQ1_t3 index f4 f4 5 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
drop table t1, t2, t3;
#
# BUG#52317: Assertion failing in Field_varstring::store()
@@ -1736,3 +1762,374 @@ id select_type table type possible_keys key key_len ref rows Extra
2 SUBQUERY t3 ALL NULL NULL NULL NULL 2
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
drop table t1, t2, t3;
+#
+# LP BUG#802979 Assertion `table->key_read == 0' in close_thread_table
+#
+CREATE TABLE t1 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t1 VALUES (1,0),(5,0);
+CREATE TABLE t2 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t2 VALUES (1,0),(5,0);
+CREATE TABLE t3 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES (1,0),(5,0);
+CREATE TABLE t4 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t4 VALUES (1,0),(5,0);
+EXPLAIN
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+WHERE EXISTS (SELECT DISTINCT f1 FROM t4))
+AND t2.f2 = t1.f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref f1 f1 5 const 0 Using index condition
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 2
+3 SUBQUERY t4 index NULL f1 5 NULL 2 Using index; Using temporary
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+WHERE EXISTS (SELECT DISTINCT f1 FROM t4))
+AND t2.f2 = t1.f1;
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+WHERE EXISTS (SELECT DISTINCT f1 FROM t4) LIMIT 1)
+AND t2.f2 = t1.f1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref f1 f1 5 const 0 Using index condition
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 2
+3 SUBQUERY t4 index NULL f1 5 NULL 2 Using index; Using temporary
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+WHERE EXISTS (SELECT DISTINCT f1 FROM t4) LIMIT 1)
+AND t2.f2 = t1.f1;
+f1 f2 f1 f2
+drop table t1,t2,t3,t4;
+#
+# LP BUG#806943 Second crash with select_describe with nested subqueries in maria-5.3
+#
+CREATE TABLE t1 ( f4 int) ;
+INSERT INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f2 int) ;
+CREATE TABLE t3 ( f1 int NOT NULL );
+CREATE TABLE t4 ( f2 int, f3 int) ;
+INSERT INTO t4 VALUES (8,0),(3,0);
+EXPLAIN SELECT *
+FROM t2, t3
+WHERE t3.f1 = (
+SELECT SUM( f2 )
+FROM t4
+WHERE EXISTS (
+SELECT DISTINCT f4
+FROM t1));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY t4 ALL NULL NULL NULL NULL 2
+3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT *
+FROM t2, t3
+WHERE t3.f1 = (
+SELECT SUM( f2 )
+FROM t4
+WHERE EXISTS (
+SELECT DISTINCT f4
+FROM t1));
+f2 f1
+drop table t1, t2, t3, t4;
+#
+# LP BUG#611690 Crash in select_describe() with nested subqueries
+#
+CREATE TABLE t1 (
+col_int_key int(11) DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_int_key (col_int_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (8,'v','v');
+INSERT INTO t1 VALUES (9,'r','r');
+CREATE TABLE t2 (
+col_int_key int(11) DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_int_key (col_int_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (2,'w','w');
+INSERT INTO t2 VALUES (9,'m','m');
+set @old_optimizer_switch = @@optimizer_switch;
+set @@optimizer_switch='subquery_cache=off,materialization=on,in_to_exists=off,semijoin=off';
+EXPLAIN
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ON SUBQUERY2_t2.col_varchar_key
+WHERE SUBQUERY2_t2.col_varchar_nokey IN
+(SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index NULL col_int_key 5 NULL 2 Using index
+2 SUBQUERY SUBQUERY2_t1 index NULL col_int_key 5 NULL 2 Using index
+2 SUBQUERY SUBQUERY2_t2 ALL col_varchar_key NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ON SUBQUERY2_t2.col_varchar_key
+WHERE SUBQUERY2_t2.col_varchar_nokey IN
+(SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+col_int_key
+set @@optimizer_switch='subquery_cache=off,materialization=off,in_to_exists=on,semijoin=off';
+EXPLAIN
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ON SUBQUERY2_t2.col_varchar_key
+WHERE SUBQUERY2_t2.col_varchar_nokey IN
+(SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index NULL col_int_key 5 NULL 2 Using index
+2 SUBQUERY SUBQUERY2_t1 index NULL col_int_key 5 NULL 2 Using index
+2 SUBQUERY SUBQUERY2_t2 ALL col_varchar_key NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ON SUBQUERY2_t2.col_varchar_key
+WHERE SUBQUERY2_t2.col_varchar_nokey IN
+(SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+col_int_key
+drop table t1, t2;
+set @@optimizer_switch = @old_optimizer_switch;
+#
+# LP BUG#612543 Crash in Item_field::used_tables() with view + subquery + prepared statements
+#
+CREATE TABLE t1 ( f1 int(11), f2 varchar(1));
+CREATE TABLE t2 ( f3 varchar(1));
+insert into t1 values (2,'x'), (5,'y');
+insert into t2 values ('x'), ('z');
+CREATE VIEW v2 AS SELECT * FROM t2;
+set @old_optimizer_switch = @@optimizer_switch;
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+PREPARE st1 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )";
+EXECUTE st1;
+f1 f2 f3
+2 x x
+5 y x
+EXECUTE st1;
+f1 f2 f3
+2 x x
+5 y x
+set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
+PREPARE st2 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )";
+EXECUTE st2;
+f1 f2 f3
+2 x x
+5 y x
+EXECUTE st2;
+f1 f2 f3
+2 x x
+5 y x
+set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+PREPARE st3 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )";
+EXECUTE st3;
+f1 f2 f3
+2 x x
+5 y x
+EXECUTE st3;
+f1 f2 f3
+2 x x
+5 y x
+set @@optimizer_switch = @old_optimizer_switch;
+drop table t1, t2;
+drop view v2;
+#
+# LP BUG#611396 RQG: crash in Item_field::register_field_in_read_map with semijoin=off
+# and prepared statements and materialization
+CREATE TABLE t1 ( f1 int(11), f2 int(11)) ;
+CREATE TABLE t2 ( f1 int(11), f4 varchar(1), PRIMARY KEY (f1)) ;
+INSERT INTO t2 VALUES ('23','j'),('24','e');
+CREATE TABLE t3 ( f1 int(11), f4 varchar(1)) ;
+INSERT INTO t3 VALUES ('8','j');
+set @old_optimizer_switch = @@optimizer_switch;
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+EXPLAIN
+SELECT t2.f1, (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1))
+FROM t2 JOIN t3 ON t3.f4 = t2.f4
+WHERE t3.f1 = 8
+GROUP BY 1, 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 system NULL NULL NULL NULL 1 Using temporary; Using filesort
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+3 SUBQUERY t1 system NULL NULL NULL NULL 0 const row not found
+PREPARE st1 FROM "
+SELECT t2.f1, (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1))
+FROM t2 JOIN t3 ON t3.f4 = t2.f4
+WHERE t3.f1 = 8
+GROUP BY 1, 2";
+EXECUTE st1;
+f1 (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1))
+23 NULL
+EXECUTE st1;
+f1 (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1))
+23 NULL
+set @@optimizer_switch = @old_optimizer_switch;
+drop table t1, t2, t3;
+#
+# LP BUG#611382 RQG: Query returns extra rows when executed with materialization=on
+#
+CREATE TABLE t1 ( f4 varchar(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2 ( f2 date, f3 varchar(1), f4 varchar(1)) ;
+INSERT INTO t2 VALUES ('2005-05-03','c','c'),('1900-01-01','d','d');
+CREATE TABLE t3 ( f3 varchar(1)) ;
+INSERT INTO t3 VALUES ('c');
+set @old_optimizer_switch = @@optimizer_switch;
+set @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off';
+EXPLAIN SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+f4
+set @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off';
+EXPLAIN SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t3 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+f4
+set @@optimizer_switch = @old_optimizer_switch;
+drop table t1, t2, t3;
+#
+# LP BUG#782305: Wrong result/valgrind warning in Item_sum_hybrid::any_value()
+#
+CREATE TABLE t1 ( f1 int) ;
+INSERT INTO t1 VALUES (2),(3);
+CREATE TABLE t2 (f2 int) ;
+INSERT INTO t2 VALUES (2),(3);
+PREPARE st1 FROM '
+SELECT * FROM t2
+WHERE f2 <= SOME ( SELECT f1 FROM t1 );
+';
+EXECUTE st1;
+f2
+2
+3
+EXECUTE st1;
+f2
+2
+3
+PREPARE st2 FROM '
+SELECT * FROM t2
+WHERE f2 <= SOME (SELECT f1-2 FROM t1 UNION SELECT f1-1 FROM t1);
+';
+EXECUTE st2;
+f2
+2
+EXECUTE st2;
+f2
+2
+drop table t1, t2;
+#
+# LP BUG#825018: Crash in check_and_do_in_subquery_rewrites() with corrlated subquery in select list
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (10,1),(11,7);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (2),(3);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (1,1);
+CREATE PROCEDURE sp1 () LANGUAGE SQL
+SELECT (SELECT t1.a
+FROM t1
+WHERE t1.b = t3.b
+AND t1.b IN ( SELECT a FROM t2 )) sq
+FROM t3
+GROUP BY 1;
+CALL sp1();
+sq
+NULL
+CALL sp1();
+sq
+NULL
+drop procedure sp1;
+prepare st1 from "
+SELECT (SELECT t1.a
+ FROM t1
+ WHERE t1.b = t3.b
+ AND t1.b IN ( SELECT a FROM t2 )) sq
+FROM t3
+GROUP BY 1";
+execute st1;
+sq
+NULL
+execute st1;
+sq
+NULL
+deallocate prepare st1;
+drop table t1, t2, t3;
+set optimizer_switch=@subselect4_tmp;
+#
+# LP BUG#833702 Wrong result with nested IN and singlerow subqueries and equality propagation
+#
+CREATE TABLE t2 (c int , a int, b int);
+INSERT INTO t2 VALUES (10,7,0);
+CREATE TABLE t3 (a int, b int) ;
+INSERT INTO t3 VALUES (5,0),(7,0);
+CREATE TABLE t4 (a int);
+INSERT INTO t4 VALUES (2),(8);
+set @@optimizer_switch='semijoin=off,in_to_exists=on,materialization=off,subquery_cache=off';
+SELECT * FROM t2
+WHERE t2.b IN (SELECT b FROM t3 WHERE t3.a = t2.a AND a < SOME (SELECT * FROM t4))
+OR ( t2.c > 242 );
+c a b
+10 7 0
+EXPLAIN SELECT * FROM t2
+WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.a < ANY (SELECT t4.a FROM t4) and t3.a = 7);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+3 SUBQUERY t4 ALL NULL NULL NULL NULL 2
+SELECT * FROM t2
+WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.a < ANY (SELECT t4.a FROM t4) and t3.a = 7);
+c a b
+10 7 0
+drop table t2, t3, t4;
+set optimizer_switch=@subselect4_tmp;
+SET optimizer_switch= @@global.optimizer_switch;
+set @@tmp_table_size= @@global.tmp_table_size;
diff --git a/mysql-test/r/subselect_cache.result b/mysql-test/r/subselect_cache.result
index f80b9882c60..8758497f7d7 100644
--- a/mysql-test/r/subselect_cache.result
+++ b/mysql-test/r/subselect_cache.result
@@ -1,3 +1,5 @@
+drop table if exists t1,t2,t3,t4,t5;
+drop view if exists v1;
set optimizer_switch='subquery_cache=on';
create table t1 (a int, b int);
insert into t1 values (1,2),(3,4),(1,2),(3,4),(3,4),(4,5),(4,5),(5,6),(5,6),(4,5);
@@ -3272,6 +3274,7 @@ FROM t2 ) AND table1 .`col_varchar_key` OR table1 .`pk` ;
col_varchar_nokey
drop table t1,t2;
set @@optimizer_switch= default;
+set optimizer_switch='subquery_cache=on';
# LP BUG#615378 (incorrect NULL result returning in Item_cache)
CREATE TABLE `t1` (
`pk` int(11) NOT NULL AUTO_INCREMENT,
@@ -3310,3 +3313,74 @@ GROUP BY field3
HAVING (field3 <= 'h' AND field2 != 4) ;
field2 field3
drop tables t1, t2, t3;
+#
+# Test aggregate functions as parameters to subquery cache
+#
+CREATE TABLE t1 ( a INT, b INT, c INT, KEY (a, b));
+INSERT INTO t1 VALUES
+( 1, 1, 1 ),
+( 1, 2, 2 ),
+( 1, 3, 3 ),
+( 1, 4, 6 ),
+( 1, 5, 5 ),
+( 1, 9, 13 ),
+( 2, 1, 6 ),
+( 2, 2, 7 ),
+( 2, 3, 8 );
+SELECT a, AVG(t1.b),
+(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c
+FROM t1 GROUP BY a;
+a AVG(t1.b) t11c
+1 4.0000 6
+2 2.0000 7
+DROP TABLE t1;
+#
+# Test of LP BUG#800696 (deleting list of Items (OR arguments)
+# in optimization)
+#
+set optimizer_switch='subquery_cache=on,in_to_exists=on';
+CREATE TABLE t1 ( f3 int) ;
+INSERT INTO t1 VALUES (0),(0);
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+CREATE TABLE t2 ( f1 int, f2 int, f3 int) ;
+INSERT INTO t2 VALUES (7,0,0);
+SELECT *
+FROM t2, t3
+WHERE t2.f2 OR t3.f3 IN
+(
+SELECT t2.f2
+FROM t1
+WHERE t2.f1 OR t2.f3 );
+f1 f2 f3 f3
+7 0 0 0
+7 0 0 0
+drop tables t1, t2, t3;
+#
+# Test of LP BUG#872775 view with "outer references" bug
+#
+set @@optimizer_switch= default;
+set optimizer_switch='subquery_cache=on';
+CREATE TABLE t1 (a int) ;
+CREATE TABLE t2 (b int, c varchar(1) NOT NULL ) ;
+INSERT INTO t2 VALUES (1,'x'),(2,'y');
+CREATE TABLE t3 (a int) ;
+CREATE TABLE t4 ( pk int(11) NOT NULL , b int(11) NOT NULL ) ;
+INSERT INTO t4 VALUES (26,9),(27,5),(28,0),(29,3);
+CREATE OR REPLACE VIEW v1 AS
+SELECT t2.b
+FROM t1
+JOIN t2
+WHERE t2 .c > (
+SELECT t2.c FROM t3
+);
+SELECT * FROM t4 WHERE b NOT IN ( SELECT * FROM v1 );
+pk b
+26 9
+27 5
+28 0
+29 3
+drop view v1;
+drop table t1,t2,t3,t4;
+# restore default
+set @@optimizer_switch= default;
diff --git a/mysql-test/r/subselect_extra.result b/mysql-test/r/subselect_extra.result
new file mode 100644
index 00000000000..3dfe2bab4a6
--- /dev/null
+++ b/mysql-test/r/subselect_extra.result
@@ -0,0 +1,475 @@
+drop table if exists t1,t2,t3,t4;
+drop view if exists v1,v2,v3;
+# From explain.test:
+#
+# Bug#37870: Usage of uninitialized value caused failed assertion.
+#
+create table t1 (dt datetime not null, t time not null);
+create table t2 (dt datetime not null);
+insert into t1 values ('2001-01-01 1:1:1', '1:1:1'),
+('2001-01-01 1:1:1', '1:1:1');
+insert into t2 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where; Start temporary
+1 PRIMARY INNR ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+dt
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where; Start temporary
+1 PRIMARY INNR ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+dt
+2001-01-01 01:01:01
+2001-01-01 01:01:01
+drop tables t1, t2;
+# From type_datetime.test:
+#
+# Bug #32694: NOT NULL table field in a subquery produces invalid results
+#
+create table t1 (id int(10) not null, cur_date datetime not null);
+create table t2 (id int(10) not null, cur_date date not null);
+insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22');
+insert into t2 (id, cur_date) values (1, '2007-04-25');
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select 1 AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` semi join (`test`.`t1` `x1`) where (('2007-04-25 18:30:22' = 0))
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id cur_date
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select 1 AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` semi join (`test`.`t2` `x1`) where (('2007-04-25' = 0))
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id cur_date
+insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22');
+insert into t2 (id, cur_date) values (2, '2007-04-26');
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+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 Using where; Start temporary
+1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`cur_date` AS `cur_date` from `test`.`t1` semi join (`test`.`t1` `x1`) where ((`test`.`x1`.`id` = `test`.`t1`.`id`) and (`test`.`t1`.`cur_date` = 0))
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id cur_date
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+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; Start temporary
+1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+Warnings:
+Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t2`.`id` AS `id`,`test`.`t2`.`cur_date` AS `cur_date` from `test`.`t2` semi join (`test`.`t2` `x1`) where ((`test`.`x1`.`id` = `test`.`t2`.`id`) and (`test`.`t2`.`cur_date` = 0))
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id cur_date
+drop table t1,t2;
+#
+# From group_min_max.test
+#
+create table t1 (
+a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
+);
+insert into t1 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'),
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4');
+create index idx_t1_0 on t1 (a1);
+create index idx_t1_1 on t1 (a1,a2,b,c);
+create index idx_t1_2 on t1 (a1,a2,b);
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Table is already up to date
+create table t2 (
+a1 char(64), a2 char(64) not null, b char(16), c char(16), d char(16), dummy char(64) default ' '
+);
+insert into t2 select * from t1;
+insert into t2 (a1, a2, b, c, d) values
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz');
+create index idx_t2_0 on t2 (a1);
+create index idx_t2_1 on t2 (a1,a2,b,c);
+create index idx_t2_2 on t2 (a1,a2,b);
+analyze table t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status Table is already up to date
+create table t3 (
+a1 char(1), a2 char(1), b char(1), c char(4) not null, d char(3), dummy char(1) default ' '
+);
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+create index idx_t3_0 on t3 (a1);
+create index idx_t3_1 on t3 (a1,a2,b,c);
+create index idx_t3_2 on t3 (a1,a2,b);
+analyze table t3;
+Table Op Msg_type Msg_text
+test.t3 analyze status Table is already up to date
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.b) and
+t2.c > 'b1' )
+group by a1,a2,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+2 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index; FirstMatch(t2)
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.b) and
+t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b c min(c) max(c)
+a a a d111 a111 d111
+a a b h112 e112 h112
+a b a l121 i121 l121
+a b b p122 m122 p122
+b a a d211 a211 d211
+b a b h212 e212 h212
+b b a l221 i221 l221
+b b b p222 m222 p222
+c a a d311 a311 d311
+c a b h312 e312 h312
+c b a l321 i321 l321
+c b b p322 m322 p322
+d a a d411 a411 d411
+d a b h412 e412 h412
+d b a l421 i421 l421
+d b b p422 m422 p422
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.c) and
+t2.c > 'b1' )
+group by a1,a2,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
+2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+2 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index; FirstMatch(t2)
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.c) and
+t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b c min(c) max(c)
+a a a a111 a111 d111
+a a b e112 e112 h112
+a b a i121 i121 l121
+a b b m122 m122 p122
+b a a a211 a211 d211
+b a b e212 e212 h212
+b b a i221 i221 l221
+b b b m222 m222 p222
+c a a a311 a311 d311
+c a b e312 e312 h312
+c b a i321 i321 l321
+c b b m322 m322 o322
+d a a a411 a411 d411
+d a b e412 e412 h412
+d b a i421 i421 l421
+d b b m422 m422 o422
+drop table t1, t2, t3;
+#
+# From group_by.test
+#
+# Bug #21174: Index degrades sort performance and
+# optimizer does not honor IGNORE INDEX.
+# a.k.a WL3527.
+#
+CREATE TABLE t1 (a INT, b INT,
+PRIMARY KEY (a),
+KEY i2(a,b));
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8);
+INSERT INTO t1 SELECT a + 8,b FROM t1;
+INSERT INTO t1 SELECT a + 16,b FROM t1;
+INSERT INTO t1 SELECT a + 32,b FROM t1;
+INSERT INTO t1 SELECT a + 64,b FROM t1;
+INSERT INTO t1 SELECT a + 128,b FROM t1 limit 16;
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+EXPLAIN SELECT 1 FROM t1 WHERE a IN
+(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index PRIMARY,i2 PRIMARY 4 NULL 144 Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 144 Using where; FirstMatch(t1)
+CREATE TABLE t2 (a INT, b INT, KEY(a));
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3,3), (4,4);
+EXPLAIN SELECT a, SUM(b) FROM t2 GROUP BY a LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL a 5 NULL 2
+EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
+EXPLAIN SELECT 1 FROM t2 WHERE a IN
+(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index a a 5 NULL 4 Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 144 Using where; FirstMatch(t2)
+DROP TABLE t1, t2;
+#
+# From derived_view.test
+#
+set @tmp_subselect_extra_derived=@@optimizer_switch;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+#
+# LP bug #806504: right join over a view/derived table
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (0), (0);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+a a b
+NULL 0 0
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` semi join (`test`.`t1`) left join `test`.`t2` on((0 <> 0)) where 1
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+a a b
+NULL 0 0
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` semi join (`test`.`t1`) left join `test`.`t2` on((0 <> 0)) where 1
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #793448: materialized view accessed by two-component key
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (9,3), (2,5);
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (9,3), (3,7), (9,1), (2,5), (2,4), (3,8);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,3), (9,7), (9,1), (2,4);
+CREATE VIEW v1(a,b) AS SELECT a, MAX(b) FROM t2 GROUP BY a;
+CREATE VIEW v2(a,b) AS SELECT a,b FROM t2 UNION SELECT a,b FROM t3;
+SELECT * FROM v1;
+a b
+2 5
+3 8
+9 3
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+a
+9
+2
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1)
+3 DERIVED t2 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
+SELECT * FROM v2;
+a b
+9 3
+3 7
+9 1
+2 5
+2 4
+3 8
+10 3
+9 7
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+a
+9
+2
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.a,test.t1.b 2 FirstMatch(t1)
+3 DERIVED t2 ALL NULL NULL NULL NULL 6
+4 UNION t3 ALL NULL NULL NULL NULL 4
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #874006: materialized view used in IN subquery
+#
+CREATE TABLE t3 (a int NOT NULL, b varchar(1), c varchar(1));
+INSERT INTO t3 VALUES (19,NULL,NULL), (20,'r','r');
+CREATE TABLE t1 (a int, b varchar(1) , c varchar(1));
+INSERT INTO t1 VALUES (1,NULL,NULL), (5,'r','r'), (7,'y','y');
+CREATE TABLE t2 (a int NOT NULL , b int, c varchar(1));
+INSERT INTO t2 VALUES (4,3,'r');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Start temporary
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 Using where; End temporary; Using join buffer (flat, BNL join)
+3 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+a b c
+20 r r
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY <derived3> ref key1 key1 10 const,const 0 Start temporary
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+3 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+a b c
+20 r r
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #873263: materialized view used in correlated IN subquery
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (5,4), (9,8);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (4,5), (5,1);
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY <derived3> ref key0 key0 10 test.t1.b,test.t1.a 2 FirstMatch(t1)
+3 DERIVED t2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+a b
+5 4
+DROP VIEW v2;
+DROP TABLE t1,t2;
+set optimizer_switch= @tmp_subselect_extra_derived;
diff --git a/mysql-test/r/subselect_extra_no_semijoin.result b/mysql-test/r/subselect_extra_no_semijoin.result
new file mode 100644
index 00000000000..c1ca1186259
--- /dev/null
+++ b/mysql-test/r/subselect_extra_no_semijoin.result
@@ -0,0 +1,480 @@
+set @subselect_extra_no_sj_tmp=@@optimizer_switch;
+set optimizer_switch='semijoin=off,firstmatch=off,loosescan=off';
+drop table if exists t1,t2,t3,t4;
+drop view if exists v1,v2,v3;
+# From explain.test:
+#
+# Bug#37870: Usage of uninitialized value caused failed assertion.
+#
+create table t1 (dt datetime not null, t time not null);
+create table t2 (dt datetime not null);
+insert into t1 values ('2001-01-01 1:1:1', '1:1:1'),
+('2001-01-01 1:1:1', '1:1:1');
+insert into t2 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY INNR ALL NULL NULL NULL NULL 2 Using where
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+dt
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY INNR ALL NULL NULL NULL NULL 2 Using where
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+dt
+2001-01-01 01:01:01
+2001-01-01 01:01:01
+drop tables t1, t2;
+# From type_datetime.test:
+#
+# Bug #32694: NOT NULL table field in a subquery produces invalid results
+#
+create table t1 (id int(10) not null, cur_date datetime not null);
+create table t2 (id int(10) not null, cur_date date not null);
+insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22');
+insert into t2 (id, cur_date) values (1, '2007-04-25');
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select 1 AS `id`,'2007-04-25 18:30:22' AS `cur_date` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,<exists>(select `test`.`x1`.`id` from `test`.`t1` `x1` where 0)))
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id cur_date
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+Warnings:
+Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select 1 AS `id`,'2007-04-25' AS `cur_date` from `test`.`t2` where <expr_cache><1>(<in_optimizer>(1,<exists>(select `test`.`x1`.`id` from `test`.`t2` `x1` where 0)))
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id cur_date
+insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22');
+insert into t2 (id, cur_date) values (2, '2007-04-26');
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+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 Using where
+2 DEPENDENT SUBQUERY x1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`cur_date` AS `cur_date` from `test`.`t1` where <expr_cache><`test`.`t1`.`id`,`test`.`t1`.`cur_date`>(<in_optimizer>(`test`.`t1`.`id`,<exists>(select `test`.`x1`.`id` from `test`.`t1` `x1` where ((`test`.`t1`.`cur_date` = 0) and (<cache>(`test`.`t1`.`id`) = `test`.`x1`.`id`)))))
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+id cur_date
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+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
+2 DEPENDENT SUBQUERY x1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t2.cur_date' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t2`.`id` AS `id`,`test`.`t2`.`cur_date` AS `cur_date` from `test`.`t2` where <expr_cache><`test`.`t2`.`id`,`test`.`t2`.`cur_date`>(<in_optimizer>(`test`.`t2`.`id`,<exists>(select `test`.`x1`.`id` from `test`.`t2` `x1` where ((`test`.`t2`.`cur_date` = 0) and (<cache>(`test`.`t2`.`id`) = `test`.`x1`.`id`)))))
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+id cur_date
+drop table t1,t2;
+#
+# From group_min_max.test
+#
+create table t1 (
+a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
+);
+insert into t1 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'),
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4');
+create index idx_t1_0 on t1 (a1);
+create index idx_t1_1 on t1 (a1,a2,b,c);
+create index idx_t1_2 on t1 (a1,a2,b);
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Table is already up to date
+create table t2 (
+a1 char(64), a2 char(64) not null, b char(16), c char(16), d char(16), dummy char(64) default ' '
+);
+insert into t2 select * from t1;
+insert into t2 (a1, a2, b, c, d) values
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz');
+create index idx_t2_0 on t2 (a1);
+create index idx_t2_1 on t2 (a1,a2,b,c);
+create index idx_t2_2 on t2 (a1,a2,b);
+analyze table t2;
+Table Op Msg_type Msg_text
+test.t2 analyze status Table is already up to date
+create table t3 (
+a1 char(1), a2 char(1), b char(1), c char(4) not null, d char(3), dummy char(1) default ' '
+);
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+create index idx_t3_0 on t3 (a1);
+create index idx_t3_1 on t3 (a1,a2,b,c);
+create index idx_t3_2 on t3 (a1,a2,b);
+analyze table t3;
+Table Op Msg_type Msg_text
+test.t3 analyze status Table is already up to date
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.b) and
+t2.c > 'b1' )
+group by a1,a2,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 range NULL idx_t1_1 147 NULL 17 Using where; Using index for group-by
+2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+3 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.b) and
+t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b c min(c) max(c)
+a a a d111 a111 d111
+a a b h112 e112 h112
+a b a l121 i121 l121
+a b b p122 m122 p122
+b a a d211 a211 d211
+b a b h212 e212 h212
+b b a l221 i221 l221
+b b b p222 m222 p222
+c a a d311 a311 d311
+c a b h312 e312 h312
+c b a l321 i321 l321
+c b b p322 m322 p322
+d a a d411 a411 d411
+d a b h412 e412 h412
+d b a l421 i421 l421
+d b b p422 m422 p422
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.c) and
+t2.c > 'b1' )
+group by a1,a2,b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL idx_t1_1 163 NULL 128 Using where; Using index
+2 DEPENDENT SUBQUERY t2 index NULL idx_t2_1 163 NULL 164 Using where; Using index
+3 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+where t2.c in (select c from t3 where t3.c > t1.c) and
+t2.c > 'b1' )
+group by a1,a2,b;
+a1 a2 b c min(c) max(c)
+a a a a111 a111 d111
+a a b e112 e112 h112
+a b a i121 i121 l121
+a b b m122 m122 p122
+b a a a211 a211 d211
+b a b e212 e212 h212
+b b a i221 i221 l221
+b b b m222 m222 p222
+c a a a311 a311 d311
+c a b e312 e312 h312
+c b a i321 i321 l321
+c b b m322 m322 o322
+d a a a411 a411 d411
+d a b e412 e412 h412
+d b a i421 i421 l421
+d b b m422 m422 o422
+drop table t1, t2, t3;
+#
+# From group_by.test
+#
+# Bug #21174: Index degrades sort performance and
+# optimizer does not honor IGNORE INDEX.
+# a.k.a WL3527.
+#
+CREATE TABLE t1 (a INT, b INT,
+PRIMARY KEY (a),
+KEY i2(a,b));
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8);
+INSERT INTO t1 SELECT a + 8,b FROM t1;
+INSERT INTO t1 SELECT a + 16,b FROM t1;
+INSERT INTO t1 SELECT a + 32,b FROM t1;
+INSERT INTO t1 SELECT a + 64,b FROM t1;
+INSERT INTO t1 SELECT a + 128,b FROM t1 limit 16;
+ANALYZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status OK
+EXPLAIN SELECT 1 FROM t1 WHERE a IN
+(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 144 Using where; Using index
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 144 Using where
+CREATE TABLE t2 (a INT, b INT, KEY(a));
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3,3), (4,4);
+EXPLAIN SELECT a, SUM(b) FROM t2 GROUP BY a LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 index NULL a 5 NULL 2
+EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
+EXPLAIN SELECT 1 FROM t2 WHERE a IN
+(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 index NULL a 5 NULL 4 Using where; Using index
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 144 Using where
+DROP TABLE t1, t2;
+#
+# From derived_view.test
+#
+set @tmp_subselect_extra_derived=@@optimizer_switch;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+#
+# LP bug #806504: right join over a view/derived table
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (0), (0);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+a a b
+NULL 0 0
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+3 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` left join `test`.`t2` on((0 <> 0)) where <expr_cache><0>(<in_optimizer>(0,<exists>(select 0 from `test`.`t1` where (<cache>(0) = 0))))
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+a a b
+NULL 0 0
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+WHERE t.a IN (SELECT b FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t1` left join `test`.`t2` on((0 <> 0)) where <expr_cache><0>(<in_optimizer>(0,<exists>(select 0 from `test`.`t1` where (<cache>(0) = 0))))
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #793448: materialized view accessed by two-component key
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (9,3), (2,5);
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (9,3), (3,7), (9,1), (2,5), (2,4), (3,8);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,3), (9,7), (9,1), (2,4);
+CREATE VIEW v1(a,b) AS SELECT a, MAX(b) FROM t2 GROUP BY a;
+CREATE VIEW v2(a,b) AS SELECT a,b FROM t2 UNION SELECT a,b FROM t3;
+SELECT * FROM v1;
+a b
+2 5
+3 8
+9 3
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+a
+9
+2
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY <derived3> index_subquery key0 key0 10 func,func 2 Using where
+3 DERIVED t2 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
+SELECT * FROM v2;
+a b
+9 3
+3 7
+9 1
+2 5
+2 4
+3 8
+10 3
+9 7
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+a
+9
+2
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY <derived3> index_subquery key0 key0 10 func,func 2 Using where
+3 DERIVED t2 ALL NULL NULL NULL NULL 6
+4 UNION t3 ALL NULL NULL NULL NULL 4
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #874006: materialized view used in IN subquery
+#
+CREATE TABLE t3 (a int NOT NULL, b varchar(1), c varchar(1));
+INSERT INTO t3 VALUES (19,NULL,NULL), (20,'r','r');
+CREATE TABLE t1 (a int, b varchar(1) , c varchar(1));
+INSERT INTO t1 VALUES (1,NULL,NULL), (5,'r','r'), (7,'y','y');
+CREATE TABLE t2 (a int NOT NULL , b int, c varchar(1));
+INSERT INTO t2 VALUES (4,3,'r');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY <derived3> ALL NULL NULL NULL NULL 3 Using where
+3 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+a b c
+20 r r
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY <derived3> ref key1 key1 10 const,const 0 Using where
+3 DERIVED t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t3
+WHERE t3.b IN (SELECT v1.b FROM v1, t2
+WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+a b c
+20 r r
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+#
+# LP bug #873263: materialized view used in correlated IN subquery
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (5,4), (9,8);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (4,5), (5,1);
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY <derived3> ref key0 key0 5 test.t1.a 2 Using where
+3 DERIVED t2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+a b
+5 4
+DROP VIEW v2;
+DROP TABLE t1,t2;
+set optimizer_switch= @tmp_subselect_extra_derived;
+set optimizer_switch= @subselect_extra_no_sj_tmp;
diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result
index 6c6d563e284..402c18f2bbd 100644
--- a/mysql-test/r/subselect_innodb.result
+++ b/mysql-test/r/subselect_innodb.result
@@ -1,3 +1,5 @@
+set @subselect_innodb_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
drop table if exists t1,t2,t3;
CREATE TABLE t1
(
@@ -245,3 +247,62 @@ x
NULL
drop procedure p1;
drop tables t1,t2,t3;
+#
+# LP BUG#827416: Crash in select_describe() on EXPLAIN with DISTINCT in nested subqueries
+#
+CREATE TABLE t3 ( b int) ENGINE=InnoDB;
+CREATE TABLE t2 ( c int) ENGINE=InnoDB;
+CREATE TABLE t1 ( a int NOT NULL , PRIMARY KEY (a)) ENGINE=InnoDB;
+EXPLAIN SELECT *
+FROM t1
+WHERE t1.a = (
+SELECT SUM( c )
+FROM t2
+WHERE (SELECT DISTINCT b FROM t3) > 0);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using where; Using index
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 1
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using temporary
+SELECT *
+FROM t1
+WHERE t1.a = (
+SELECT SUM( c )
+FROM t2
+WHERE (SELECT DISTINCT b FROM t3) > 0);
+a
+DROP TABLE t1, t2, t3;
+#
+# LP BUG#858148 Fourth crash in select_describe() with nested subqueries
+#
+CREATE TABLE t1 ( f1 int(11)) ENGINE=InnoDB;
+CREATE TABLE t2 ( f1 int(11), f2 int(11), PRIMARY KEY (f1)) ;
+CREATE TABLE t3 ( f3 int(11)) ENGINE=InnoDB;
+EXPLAIN
+SELECT MAX( f1 ) FROM t2
+WHERE f2 >= (
+SELECT SUM( f1 )
+FROM t1
+WHERE EXISTS (
+SELECT f3
+FROM t3
+GROUP BY 1
+)
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 1
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using temporary; Using filesort
+SELECT MAX( f1 ) FROM t2
+WHERE f2 >= (
+SELECT SUM( f1 )
+FROM t1
+WHERE EXISTS (
+SELECT f3
+FROM t3
+GROUP BY 1
+)
+);
+MAX( f1 )
+NULL
+drop table t1, t2, t3;
+set optimizer_switch=@subselect_innodb_tmp;
diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result
index 889293d2908..8241d9027a5 100644
--- a/mysql-test/r/subselect_mat.result
+++ b/mysql-test/r/subselect_mat.result
@@ -1,5 +1,9 @@
-set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
-drop table if exists t1, t2, t3, t1i, t2i, t3i;
+set @subselect_mat_test_optimizer_switch_value='materialization=on,in_to_exists=off,semijoin=off';
+set @subselect_sj_mat_tmp= @@optimizer_switch;
+set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on');
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @optimizer_switch_local_default= @@optimizer_switch;
+drop table if exists t1, t2, t3, t4, t5, t1i, t2i, t3i;
drop table if exists columns;
drop table if exists t1_16, t2_16, t3_16;
drop view if exists v1, v2, v1m, v2m;
@@ -66,7 +70,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
2 SUBQUERY 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 `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`))))))
select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -77,7 +81,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
2 SUBQUERY 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 `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`min(b2)`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`min(b2)`))))))
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
@@ -110,7 +114,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1i index NULL _it1_idx # NULL 3 100.00 Using where;
2 SUBQUERY t2i index it2i1,it2i3 it2i3 # NULL 5 100.00 Using where;
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`))))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`))))))
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0');
a1 a2
1 - 01 2 - 01
@@ -121,7 +125,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1i index NULL # # # 3 100.00 #
2 SUBQUERY t2i range it2i1,it2i3 # # # 3 100.00 #
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`))))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`))))))
select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -132,7 +136,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1i index NULL # # # 3 100.00 #
2 SUBQUERY t2i range it2i1,it2i3 # # # 3 100.00 #
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`min(b2)`))))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`min(b2)`))))))
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
@@ -143,7 +147,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
2 SUBQUERY 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 `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`max(b2)`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`max(b2)`))))))
select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
a1 a2
1 - 01 2 - 01
@@ -172,7 +176,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
2 SUBQUERY 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 `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`min(b2)`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`min(b2)`))))))
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
@@ -180,28 +184,34 @@ a1 a2
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1);
ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch='default,semijoin=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
prepare st1 from
"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
execute st1;
a1 a2
1 - 01 2 - 01
1 - 02 2 - 02
-set @@optimizer_switch='default,semijoin=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
execute st1;
a1 a2
1 - 01 2 - 01
1 - 02 2 - 02
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
prepare st1 from
"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
-set @@optimizer_switch='default,semijoin=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
execute st1;
a1 a2
1 - 01 2 - 01
1 - 02 2 - 02
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
execute st1;
a1 a2
1 - 01 2 - 01
@@ -213,7 +223,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
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`))))))
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -224,7 +234,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
2 SUBQUERY 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 `test`.`t1i` where <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`))))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`))))))
select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
a1 a2
1 - 01 2 - 01
@@ -279,7 +289,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
4 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
2 SUBQUERY 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` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery4>`.`b1`) and (`test`.`t3`.`c2` = `<subquery4>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery3>`.`c1`) and (`test`.`t1`.`a2` = `<subquery3>`.`c2`)))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery4>`.`b1`) and (`test`.`t3`.`c2` = `<subquery4>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery3>`.`c1`) and (`test`.`t1`.`a2` = `<subquery3>`.`c2`)))))))
select * from t1
where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
(a1, a2) in (select c1, c2 from t3
@@ -298,7 +308,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
4 SUBQUERY t2i index it2i2 # # # 5 100.00 #
2 SUBQUERY t2i index it2i1,it2i3 # # # 5 100.00 #
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c2`,`test`.`t3i`.`c1`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `<subquery4>`.`b1`) and (`test`.`t3i`.`c2` = `<subquery4>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery3>`.`c1`) and (`test`.`t1i`.`a2` = `<subquery3>`.`c2`)))))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c1`,`test`.`t3i`.`c2`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `<subquery4>`.`b1`) and (`test`.`t3i`.`c2` = `<subquery4>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery3>`.`c1`) and (`test`.`t1i`.`a2` = `<subquery3>`.`c2`)))))))
select * from t1i
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
(a1, a2) in (select c1, c2 from t3i
@@ -321,7 +331,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
3 SUBQUERY 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` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<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`))))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<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`))))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))
select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 where c2 LIKE '%02') or
@@ -346,7 +356,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` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<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 (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where <expr_cache><`test`.`t3c`.`c2`,`test`.`t3c`.`c1`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),(`test`.`t3c`.`c1`,`test`.`t3c`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3c`.`c1` in <temporary table> on distinct_key where ((`test`.`t3c`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3c`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<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 (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where <expr_cache><`test`.`t3c`.`c1`,`test`.`t3c`.`c2`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),(`test`.`t3c`.`c1`,`test`.`t3c`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3c`.`c1` in <temporary table> on distinct_key where ((`test`.`t3c`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3c`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))
select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 t3a where c1 = a1) or
@@ -382,7 +392,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
8 SUBQUERY t2i index it2i1,it2i3 # # # 5 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` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<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`))))))) group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery8>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery8>`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a2`,`test`.`t1i`.`a1`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c2`,`test`.`t3i`.`c1`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `<subquery10>`.`b1`) and (`test`.`t3i`.`c2` = `<subquery10>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery9>`.`c1`) and (`test`.`t1i`.`a2` = `<subquery9>`.`c2`))))))))
+Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<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`))))))) group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery8>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery8>`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c1`,`test`.`t3i`.`c2`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `<subquery10>`.`b1`) and (`test`.`t3i`.`c2` = `<subquery10>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery9>`.`c1`) and (`test`.`t1i`.`a2` = `<subquery9>`.`c2`))))))))
(select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 where c2 LIKE '%02') or
@@ -411,7 +421,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` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<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 <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery5>`.`b1`) and (`test`.`t3`.`c2` = `<subquery5>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery4>`.`c1`) and (`test`.`t1`.`a2` = `<subquery4>`.`c2`)))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<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 <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery5>`.`b1`) and (`test`.`t3`.`c2` = `<subquery5>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery4>`.`c1`) and (`test`.`t1`.`a2` = `<subquery4>`.`c2`)))))))
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
@@ -434,7 +444,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` join `test`.`t3` where ((`test`.`t3`.`c1` = `test`.`t1`.`a1`) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<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 <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c2`,`test`.`t3`.`c1`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery5>`.`b1`) and (`test`.`t3`.`c2` = `<subquery5>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery4>`.`c1`) and (`test`.`t3`.`c2` = `<subquery4>`.`c2`)))))))
+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` join `test`.`t3` where ((`test`.`t3`.`c1` = `test`.`t1`.`a1`) 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 <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery5>`.`b1`) and (`test`.`t3`.`c2` = `<subquery5>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery4>`.`c1`) and (`test`.`t3`.`c2` = `<subquery4>`.`c2`)))))))
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
@@ -480,14 +490,14 @@ 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` where (<expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<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 (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where (<expr_cache><`test`.`t3c`.`c2`,`test`.`t3c`.`c1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),<exists>(<index_lookup>(<cache>(`test`.`t3c`.`c1`) in t2i on it2i3 where (((`test`.`t2i`.`b2` > '0') or (`test`.`t2i`.`b2` = `test`.`t1`.`a2`)) and (<cache>(`test`.`t3c`.`c1`) = `test`.`t2i`.`b1`) and (<cache>(`test`.`t3c`.`c2`) = `test`.`t2i`.`b2`)))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t3c`.`c1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t3c`.`c2`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (<expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<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 (<cache>(`test`.`t1`.`a1`) = `test`.`t2`.`b1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t2`.`b2`))))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where (<expr_cache><`test`.`t3c`.`c1`,`test`.`t3c`.`c2`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t3c`.`c1`,`test`.`t3c`.`c2`),<exists>(<index_lookup>(<cache>(`test`.`t3c`.`c1`) in t2i on it2i3 where (((`test`.`t2i`.`b2` > '0') or (`test`.`t2i`.`b2` = `test`.`t1`.`a2`)) and (<cache>(`test`.`t3c`.`c1`) = `test`.`t2i`.`b1`) and (<cache>(`test`.`t3c`.`c2`) = `test`.`t2i`.`b2`)))))) and (<cache>(`test`.`t1`.`a1`) = `test`.`t3c`.`c1`) and (<cache>(`test`.`t1`.`a2`) = `test`.`t3c`.`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
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (((<cache>(`test`.`t1`.`a1`) = '1 - 01') or isnull('1 - 01')) and ((<cache>(`test`.`t1`.`a2`) = '2 - 01') or isnull('2 - 01')) and <is_not_null_test>('1 - 01') and <is_not_null_test>('2 - 01')))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (((<cache>(`test`.`t1`.`a1`) = '1 - 01') or isnull('1 - 01')) and ((<cache>(`test`.`t1`.`a2`) = '2 - 01') or isnull('2 - 01')) and <is_not_null_test>('1 - 01') and <is_not_null_test>('2 - 01')))))
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
a1 a2
1 - 01 2 - 01
@@ -497,7 +507,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
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (((<cache>(`test`.`t1`.`a1`) = '1 - 01') or isnull('1 - 01')) and ((<cache>(`test`.`t1`.`a2`) = '2 - 01') or isnull('2 - 01')) and <is_not_null_test>('1 - 01') and <is_not_null_test>('2 - 01')))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (((<cache>(`test`.`t1`.`a1`) = '1 - 01') or isnull('1 - 01')) and ((<cache>(`test`.`t1`.`a2`) = '2 - 01') or isnull('2 - 01')) and <is_not_null_test>('1 - 01') and <is_not_null_test>('2 - 01')))))
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
a1 a2
1 - 01 2 - 01
@@ -600,7 +610,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
2 DEPENDENT SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
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` where <expr_cache><`test`.`t1_16`.`a2`,`test`.`t1_16`.`a1`>(<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` where ((`test`.`t2_16`.`b1` > '0') and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`)))))
+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` where <expr_cache><`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`>(<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` where ((`test`.`t2_16`.`b1` > '0') and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`)))))
select left(a1,7), left(a2,7)
from t1_16
where (a1,a2) in (select b1, b2 from t2_16 where b1 > '0');
@@ -665,7 +675,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
4 SUBQUERY 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` where <expr_cache><concat(`test`.`t1`.`a1`,'x')>(<in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(select left(`test`.`t1_16`.`a1`,8) from `test`.`t1_16` where (<expr_cache><`test`.`t1_16`.`a2`,`test`.`t1_16`.`a1`>(<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` join `test`.`t2` where ((`test`.`t2`.`b2` = substr(`test`.`t2_16`.`b2`,1,6)) and <expr_cache><`test`.`t2`.`b1`>(<in_optimizer>(`test`.`t2`.`b1`,`test`.`t2`.`b1` in ( <materialize> (select `test`.`t3`.`c1` from `test`.`t3` where (`test`.`t3`.`c2` > '0') ), <primary_index_lookup>(`test`.`t2`.`b1` in <temporary table> on distinct_key where ((`test`.`t2`.`b1` = `<subquery4>`.`c1`)))))) and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`))))) and (<cache>(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` where <expr_cache><concat(`test`.`t1`.`a1`,'x')>(<in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(select left(`test`.`t1_16`.`a1`,8) from `test`.`t1_16` where (<expr_cache><`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`>(<in_optimizer>((`test`.`t1_16`.`a1`,`test`.`t1_16`.`a2`),<exists>(select `test`.`t2_16`.`b1`,`test`.`t2_16`.`b2` from `test`.`t2_16` join `test`.`t2` where ((`test`.`t2`.`b2` = substr(`test`.`t2_16`.`b2`,1,6)) and <expr_cache><`test`.`t2`.`b1`>(<in_optimizer>(`test`.`t2`.`b1`,`test`.`t2`.`b1` in ( <materialize> (select `test`.`t3`.`c1` from `test`.`t3` where (`test`.`t3`.`c2` > '0') ), <primary_index_lookup>(`test`.`t2`.`b1` in <temporary table> on distinct_key where ((`test`.`t2`.`b1` = `<subquery4>`.`c1`)))))) and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`) and (<cache>(`test`.`t1_16`.`a2`) = `test`.`t2_16`.`b2`))))) and (<cache>(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;
@@ -713,7 +723,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
2 DEPENDENT SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
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` where <expr_cache><`test`.`t1_512`.`a2`,`test`.`t1_512`.`a1`>(<in_optimizer>((`test`.`t1_512`.`a1`,`test`.`t1_512`.`a2`),<exists>(select `test`.`t2_512`.`b1`,`test`.`t2_512`.`b2` from `test`.`t2_512` where ((`test`.`t2_512`.`b1` > '0') and (<cache>(`test`.`t1_512`.`a1`) = `test`.`t2_512`.`b1`) and (<cache>(`test`.`t1_512`.`a2`) = `test`.`t2_512`.`b2`)))))
+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` where <expr_cache><`test`.`t1_512`.`a1`,`test`.`t1_512`.`a2`>(<in_optimizer>((`test`.`t1_512`.`a1`,`test`.`t1_512`.`a2`),<exists>(select `test`.`t2_512`.`b1`,`test`.`t2_512`.`b2` from `test`.`t2_512` where ((`test`.`t2_512`.`b1` > '0') and (<cache>(`test`.`t1_512`.`a1`) = `test`.`t2_512`.`b1`) and (<cache>(`test`.`t1_512`.`a2`) = `test`.`t2_512`.`b2`)))))
select left(a1,7), left(a2,7)
from t1_512
where (a1,a2) in (select b1, b2 from t2_512 where b1 > '0');
@@ -806,7 +816,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
2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
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` where <expr_cache><`test`.`t1_1024`.`a2`,`test`.`t1_1024`.`a1`>(<in_optimizer>((`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a2`),<exists>(select `test`.`t2_1024`.`b1`,`test`.`t2_1024`.`b2` from `test`.`t2_1024` where ((`test`.`t2_1024`.`b1` > '0') and (<cache>(`test`.`t1_1024`.`a1`) = `test`.`t2_1024`.`b1`) and (<cache>(`test`.`t1_1024`.`a2`) = `test`.`t2_1024`.`b2`)))))
+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` where <expr_cache><`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a2`>(<in_optimizer>((`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a2`),<exists>(select `test`.`t2_1024`.`b1`,`test`.`t2_1024`.`b2` from `test`.`t2_1024` where ((`test`.`t2_1024`.`b1` > '0') and (<cache>(`test`.`t1_1024`.`a1`) = `test`.`t2_1024`.`b1`) and (<cache>(`test`.`t1_1024`.`a2`) = `test`.`t2_1024`.`b2`)))))
select left(a1,7), left(a2,7)
from t1_1024
where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0');
@@ -899,7 +909,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
2 DEPENDENT SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
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` where <expr_cache><`test`.`t1_1025`.`a2`,`test`.`t1_1025`.`a1`>(<in_optimizer>((`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a2`),<exists>(select `test`.`t2_1025`.`b1`,`test`.`t2_1025`.`b2` from `test`.`t2_1025` where ((`test`.`t2_1025`.`b1` > '0') and (<cache>(`test`.`t1_1025`.`a1`) = `test`.`t2_1025`.`b1`) and (<cache>(`test`.`t1_1025`.`a2`) = `test`.`t2_1025`.`b2`)))))
+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` where <expr_cache><`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a2`>(<in_optimizer>((`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a2`),<exists>(select `test`.`t2_1025`.`b1`,`test`.`t2_1025`.`b2` from `test`.`t2_1025` where ((`test`.`t2_1025`.`b1` > '0') and (<cache>(`test`.`t1_1025`.`a1`) = `test`.`t2_1025`.`b1`) and (<cache>(`test`.`t1_1025`.`a2`) = `test`.`t2_1025`.`b2`)))))
select left(a1,7), left(a2,7)
from t1_1025
where (a1,a2) in (select b1, b2 from t2_1025 where b1 > '0');
@@ -961,7 +971,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1bit ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2bit ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select conv(`test`.`t1bit`.`a1`,10,2) AS `bin(a1)`,conv(`test`.`t1bit`.`a2`,10,2) AS `bin(a2)` from `test`.`t1bit` where <expr_cache><`test`.`t1bit`.`a2`,`test`.`t1bit`.`a1`>(<in_optimizer>((`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`),(`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`) in ( <materialize> (select `test`.`t2bit`.`b1`,`test`.`t2bit`.`b2` from `test`.`t2bit` ), <primary_index_lookup>(`test`.`t1bit`.`a1` in <temporary table> on distinct_key where ((`test`.`t1bit`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1bit`.`a2` = `<subquery2>`.`b2`))))))
+Note 1003 select conv(`test`.`t1bit`.`a1`,10,2) AS `bin(a1)`,conv(`test`.`t1bit`.`a2`,10,2) AS `bin(a2)` from `test`.`t1bit` where <expr_cache><`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`>(<in_optimizer>((`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`),(`test`.`t1bit`.`a1`,`test`.`t1bit`.`a2`) in ( <materialize> (select `test`.`t2bit`.`b1`,`test`.`t2bit`.`b2` from `test`.`t2bit` ), <primary_index_lookup>(`test`.`t1bit`.`a1` in <temporary table> on distinct_key where ((`test`.`t1bit`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1bit`.`a2` = `<subquery2>`.`b2`))))))
select bin(a1), bin(a2)
from t1bit
where (a1, a2) in (select b1, b2 from t2bit);
@@ -984,7 +994,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 Using where
2 DEPENDENT SUBQUERY t2bb ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select conv(`test`.`t1bb`.`a1`,10,2) AS `bin(a1)`,`test`.`t1bb`.`a2` AS `a2` from `test`.`t1bb` where <expr_cache><`test`.`t1bb`.`a2`,`test`.`t1bb`.`a1`>(<in_optimizer>((`test`.`t1bb`.`a1`,`test`.`t1bb`.`a2`),<exists>(select `test`.`t2bb`.`b1`,`test`.`t2bb`.`b2` from `test`.`t2bb` where ((<cache>(`test`.`t1bb`.`a1`) = `test`.`t2bb`.`b1`) and (<cache>(`test`.`t1bb`.`a2`) = `test`.`t2bb`.`b2`)))))
+Note 1003 select conv(`test`.`t1bb`.`a1`,10,2) AS `bin(a1)`,`test`.`t1bb`.`a2` AS `a2` from `test`.`t1bb` where <expr_cache><`test`.`t1bb`.`a1`,`test`.`t1bb`.`a2`>(<in_optimizer>((`test`.`t1bb`.`a1`,`test`.`t1bb`.`a2`),<exists>(select `test`.`t2bb`.`b1`,`test`.`t2bb`.`b2` from `test`.`t2bb` where ((<cache>(`test`.`t1bb`.`a1`) = `test`.`t2bb`.`b1`) and (<cache>(`test`.`t1bb`.`a2`) = `test`.`t2bb`.`b2`)))))
select bin(a1), a2
from t1bb
where (a1, a2) in (select b1, b2 from t2bb);
@@ -1099,7 +1109,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`,max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`c` from `test`.`t2` where (<nop>(<expr_cache><`test`.`t2`.`d`,max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where (max(`test`.`t1`.`b`) = `test`.`t3`.`e`) having (<cache>(`test`.`t2`.`d`) >= <ref_null_helper>(`test`.`t3`.`e`)))))) and (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`,`test`.`t1`.`b`,max(`test`.`t1`.`b`),max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`c` from `test`.`t2` where (<nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`,max(`test`.`t1`.`b`),max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where (max(`test`.`t1`.`b`) = `test`.`t3`.`e`) having (<cache>(`test`.`t2`.`d`) >= <ref_null_helper>(`test`.`t3`.`e`)))))) and (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`)))))
select a from t1 group by a
having a in (select c from t2 where d >= some(select e from t3 where max(b)=e));
a
@@ -1140,40 +1150,48 @@ create table t2 (b1 int);
insert into t1 values (5);
explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+1 PRIMARY t1 system NULL NULL NULL NULL 1
2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
min(a1)
+NULL
set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+1 PRIMARY t1 system NULL NULL NULL NULL 1
2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
min(a1)
-set @@optimizer_switch='default,semijoin=off';
+NULL
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
explain select min(a1) from t1 where 7 in (select b1 from t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
select min(a1) from t1 where 7 in (select b1 from t2);
min(a1)
-set @@optimizer_switch='default,materialization=off';
+NULL
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
# with MariaDB and MWL#90, this particular case is solved:
explain select min(a1) from t1 where 7 in (select b1 from t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
select min(a1) from t1 where 7 in (select b1 from t2);
min(a1)
NULL
# but when we go around MWL#90 code, the problem still shows up:
explain select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+1 PRIMARY t1 system NULL NULL NULL NULL 1
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
min(a1)
+NULL
set @@optimizer_switch= @save_optimizer_switch;
drop table t1,t2;
create table t1 (a char(2), b varchar(10));
@@ -1191,6 +1209,228 @@ a b
execute st1;
a b
drop table t1;
+#
+# BUG#49630: Segfault in select_describe() with double
+# nested subquery and materialization
+#
+CREATE TABLE t1 (t1i int);
+CREATE TABLE t2 (t2i int);
+CREATE TABLE t3 (t3i int);
+CREATE TABLE t4 (t4i int);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1),(2);
+INSERT INTO t3 VALUES (1),(2);
+INSERT INTO t4 VALUES (1),(2);
+
+EXPLAIN
+SELECT t1i
+FROM t1 JOIN t4 ON t1i=t4i
+WHERE (t1i) IN (
+SELECT t2i
+FROM t2
+WHERE (t2i) IN (
+SELECT t3i
+FROM t3
+GROUP BY t3i
+)
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using temporary
+DROP TABLE t1,t2,t3,t4;
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT,
+col_int_nokey INTEGER,
+col_int_key INTEGER,
+col_varchar_key VARCHAR(1),
+PRIMARY KEY (pk),
+KEY (col_int_key),
+KEY (col_varchar_key, col_int_key)
+)
+;
+INSERT INTO t1 (
+col_int_key, col_int_nokey, col_varchar_key
+)
+VALUES
+(2, NULL, 'w'),
+(9, 7, 'm'),
+(3, 9, 'm'),
+(9, 7, 'k'),
+(NULL, 4, 'r'),
+(9, 2, 't'),
+(3, 6, 'j'),
+(8, 8, 'u'),
+(8, NULL, 'h'),
+(53, 5, 'o'),
+(0, NULL, NULL),
+(5, 6, 'k'),
+(166, 188, 'e'),
+(3, 2, 'n'),
+(0, 1, 't'),
+(1, 1, 'c'),
+(9, 0, 'm'),
+(5, 9, 'y'),
+(6, NULL, 'f'),
+(2, 4, 'd')
+;
+SELECT table2.col_varchar_key AS field1,
+table2.col_int_nokey AS field2
+FROM ( t1 AS table1 LEFT OUTER JOIN t1 AS table2
+ON (table2.col_varchar_key = table1.col_varchar_key ) )
+WHERE table1.pk = 6
+HAVING ( field2 ) IN
+( SELECT SUBQUERY2_t2.col_int_nokey AS SUBQUERY2_field2
+FROM ( t1 AS SUBQUERY2_t1 JOIN t1 AS SUBQUERY2_t2
+ON (SUBQUERY2_t2.col_varchar_key = SUBQUERY2_t1.col_varchar_key ) ) )
+ORDER BY field2
+;
+field1 field2
+t 1
+t 2
+drop table t1;
+#
+# BUG#53103: MTR test ps crashes in optimize_cond()
+# when running with --debug
+#
+CREATE TABLE t1(track varchar(15));
+INSERT INTO t1 VALUES ('CAD'), ('CAD');
+PREPARE STMT FROM
+"SELECT 1 FROM t1
+ WHERE
+ track IN (SELECT track FROM t1
+ GROUP BY track
+ HAVING track>='CAD')";
+EXECUTE STMT ;
+1
+1
+1
+EXECUTE STMT ;
+1
+1
+1
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
+# End of BUG#53103
+#
+# BUG#54511 - Assertion failed: cache != 0L in file
+# sql_select.cc::sub_select_cache on HAVING
+#
+CREATE TABLE t1 (i int(11));
+CREATE TABLE t2 (c char(1));
+CREATE TABLE t3 (c char(1));
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES ('a'), ('b');
+INSERT INTO t3 VALUES ('x'), ('y');
+SELECT COUNT( i ),i
+FROM t1
+HAVING ('c')
+IN (SELECT t2.c FROM (t2 JOIN t3));
+COUNT( i ) i
+DROP TABLE t1,t2,t3;
+# End BUG#54511
+#
+# BUG#56367 - Assertion exec_method != EXEC_MATERIALIZATION...
+# on subquery in FROM
+#
+CREATE TABLE t1 (a INTEGER);
+CREATE TABLE t2 (b INTEGER);
+INSERT INTO t2 VALUES (1);
+explain SELECT a FROM (
+SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT a FROM (
+SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+a
+DROP TABLE t1, t2;
+# End BUG#56367
+#
+# Bug#59833 - materialization=on/off leads to different result set
+# when using IN
+#
+CREATE TABLE t1 (
+pk int NOT NULL,
+f1 int DEFAULT NULL,
+PRIMARY KEY (pk)
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+pk int NOT NULL,
+f1 int DEFAULT NULL,
+PRIMARY KEY (pk)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (10,0);
+INSERT INTO t2 VALUES (10,0),(11,0);
+explain SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY t1 system NULL NULL NULL NULL 1
+SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+f1 pk pk
+DROP TABLE t1, t2;
+# End Bug#59833
+#
+# Bug#11852644 - CRASH IN ITEM_REF::SAVE_IN_FIELD ON SELECT DISTINCT
+#
+CREATE TABLE t1 (
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_varchar_key (col_varchar_key))
+;
+INSERT INTO t1 VALUES
+('v','v'),('r','r');
+CREATE TABLE t2 (
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_varchar_key(col_varchar_key))
+;
+INSERT INTO t2 VALUES
+('r','r'),('c','c');
+CREATE VIEW v3 AS SELECT * FROM t2;
+SELECT DISTINCT alias2.col_varchar_key
+FROM t1 AS alias1 JOIN v3 AS alias2
+ON alias2.col_varchar_key = alias1.col_varchar_key
+HAVING col_varchar_key IN (SELECT col_varchar_nokey FROM t2)
+;
+col_varchar_key
+r
+DROP TABLE t1, t2;
+DROP VIEW v3;
+# End Bug#11852644
+
+# Bug#12668294 - GROUP BY ON EMPTY RESULT GIVES EMPTY ROW
+# INSTEAD OF NULL WHEN MATERIALIZATION ON
+
+CREATE TABLE t1 (col_int_nokey INT) ENGINE=MEMORY;
+CREATE TABLE t2 (col_int_nokey INT) ENGINE=MEMORY;
+INSERT INTO t2 VALUES (8),(7);
+CREATE TABLE t3 (col_int_nokey INT) ENGINE=MEMORY;
+INSERT INTO t3 VALUES (7);
+SELECT MIN(t3.col_int_nokey),t1.col_int_nokey AS field3
+FROM t3
+LEFT JOIN t1
+ON t1.col_int_nokey
+WHERE (194, 200) IN (
+SELECT SQ4_alias1.col_int_nokey,
+SQ4_alias2.col_int_nokey
+FROM t2 AS SQ4_alias1
+JOIN
+t2 AS SQ4_alias2
+ON SQ4_alias2.col_int_nokey = 5
+)
+GROUP BY field3 ;
+MIN(t3.col_int_nokey) field3
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
CREATE TABLE t1 (f1 INT, f2 DECIMAL(5,3)) ENGINE=MyISAM;
INSERT INTO t1 (f1, f2) VALUES (1, 1.789);
INSERT INTO t1 (f1, f2) VALUES (13, 1.454);
@@ -1199,7 +1439,8 @@ CREATE TABLE t2 LIKE t1;
INSERT INTO t2 VALUES (1, 1.789);
INSERT INTO t2 VALUES (13, 1.454);
set @save_optimizer_switch=@@optimizer_switch;
-SET @@optimizer_switch='default,semijoin=on,materialization=on';
+set @@optimizer_switch=@optimizer_switch_local_default;
+SET @@optimizer_switch='semijoin=on,materialization=on';
EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
@@ -1222,7 +1463,8 @@ INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff');
CREATE TABLE t2 LIKE t1;
INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff');
set @save_optimizer_switch=@@optimizer_switch;
-SET @@optimizer_switch='default,semijoin=on,materialization=on';
+set @@optimizer_switch=@optimizer_switch_local_default;
+SET @@optimizer_switch='semijoin=on,materialization=on';
EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
@@ -1320,7 +1562,174 @@ select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,
left(a1,7) left(a2,7)
1 - 01x 2 - 01x
drop table t1_1024, t2_1024;
+#
+# BUG##836491: Crash in Item_field::Item_field from add_ref_to_table_cond() with semijoin+materialization
+#
+CREATE TABLE t1 (c int, d varchar(1), KEY(d)) ;
+INSERT INTO t1 VALUES (2,'x'),(2,'x'),(2,'j'),(2,'c');
+CREATE TABLE t2 (a int, d varchar(1)) ;
+INSERT INTO t2 VALUES (1,'x');
+CREATE TABLE t3 (d varchar(1)) ;
+INSERT INTO t3 VALUES ('x'),('x'),('j'),('c');
+SELECT t2.a, t1.c
+FROM t1, t2
+WHERE t2.d IN ( SELECT d FROM t3 )
+AND t1.d = t2.d
+GROUP BY 1 , 2;
+a c
+1 2
+drop table t1,t2,t3;
+#
+# BUG#836523: Crash in JOIN::get_partial_cost_and_fanout with semijoin+materialization
+#
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('a'),('a');
+CREATE TABLE t2 (a varchar(1));
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (1),(2);
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('a'),('a');
+SELECT t1.a
+FROM t1
+WHERE t1.a IN (
+SELECT t2.a
+FROM t2, t3
+)
+HAVING a IN (
+SELECT a
+FROM t4
+);
+a
+DROP TABLE t1, t2, t3, t4;
+#
+# BUG#836507: Crash in setup_sj_materialization_part1() with semijoin+materialization
+#
+CREATE TABLE t1 (a int) ;
+INSERT IGNORE INTO t1 VALUES (1),(1);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1);
+CREATE TABLE t3 (a int);
+CREATE TABLE t4 (a int);
+INSERT INTO t4 VALUES (2),(2);
+CREATE TABLE t5 (a int);
+INSERT INTO t5 VALUES (1);
+SELECT * FROM t1
+WHERE (a) IN (
+SELECT t5.a
+FROM (
+t2
+LEFT JOIN ( t3 , t4 )
+ON 1 = 1
+)
+JOIN t5
+);
+a
+1
+1
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# BUG#836532: Crash in Item_equal_fields_iterator::get_curr_field with semijoin+materialization
+#
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES ('a'),('a');
+Warnings:
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 2
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('m'),('o');
+CREATE TABLE t3 (a varchar(1) , b varchar(1) ) ;
+INSERT INTO t3 VALUES ('b','b');
+CREATE TABLE t5 (a varchar(1), KEY (a)) ;
+INSERT INTO t5 VALUES ('d'),('e');
+SELECT *
+FROM t2
+WHERE t2.a = ALL (
+SELECT t4.a
+FROM t4
+WHERE t4.a IN (
+SELECT t3.a
+FROM t3 , t5
+WHERE ( t5.a = t3.b )
+)
+);
+a
+0
+0
+DROP TABLE t2,t3,t4,t5;
+#
+# BUG#860300: Second crash with get_fanout_with_deps() with semijoin + materialization
+#
+set @tmp_860300=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f2 int);
+INSERT INTO t1 VALUES (9),(6);
+CREATE TABLE t3 (f4 int);
+CREATE TABLE t4 (f6 varchar(1));
+SELECT *
+FROM t3
+WHERE 'h' IN (SELECT f6
+FROM t4
+WHERE 5 IN (SELECT f2 FROM t1)
+GROUP BY t4.f6);
+f4
+DROP TABLE t1,t3,t4;
+set optimizer_switch=@tmp_860300;
+#
+# BUG#860535: Assertion `keypart_map' failed in mi_rkey with semijoin
+#
+set @tmp_860535=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f3 int) ;
+INSERT INTO t1 VALUES (1),(7);
+CREATE TABLE t2 (f3 int , f5 varchar(1), KEY (f3)) ;
+INSERT INTO t2 VALUES (7,'b');
+CREATE TABLE t3 (f3 int , f4 varchar(1) , KEY(f3), KEY (f4,f3)) ;
+INSERT INTO t3 VALUES (1,'t'),(7,'g');
+CREATE TABLE t4
+SELECT f3
+FROM t1 WHERE ( f3 ) NOT IN (
+SELECT f3
+FROM t2
+WHERE f5 IN (
+SELECT f4
+FROM t3
+WHERE t3.f3 < 3
+)
+);
+SELECT * FROM t4;
+f3
+1
+7
+DROP TABLE t1, t2, t3, t4;
+set optimizer_switch=@tmp_860535;
+#
+# BUG#860553: Crash in create_ref_for_key with semijoin + materialization
+#
+CREATE TABLE t1 (f1 int) ;
+CREATE TABLE t2 (f5 varchar(52) NOT NULL) ;
+CREATE TABLE t3 (f1 varchar(3), f4 varchar(52) , KEY (f4), PRIMARY KEY (f1));
+CREATE TABLE t4 (f3 int, KEY (f3));
+INSERT INTO t4 VALUES (17),(20);
+CREATE TABLE t5 (f2 int);
+INSERT INTO t5 VALUES (0),(0);
+SELECT *
+FROM t1
+JOIN t2
+ON ( t2.f5 ) IN (
+SELECT t3.f4
+FROM t3
+WHERE ( 1 ) IN (
+SELECT t4.f3
+FROM t4 , t5
+)
+);
+f1 f5
+DROP TABLE t1, t2, t3, t4, t5;
+# This must be at the end:
+set optimizer_switch=@subselect_sj_mat_tmp;
+set @subselect_mat_test_optimizer_switch_value=null;
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
create table t0 (a int);
insert into t0 values (0),(1),(2);
create table t1 (a int);
@@ -1386,7 +1795,7 @@ EXPLAIN
SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
2 SUBQUERY t3 system NULL NULL NULL NULL 0 const row not found
SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT k FROM t3);
i
@@ -1395,7 +1804,7 @@ EXPLAIN
SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
2 SUBQUERY t3 system NULL NULL NULL NULL 0 const row not found
SELECT i FROM t1 LEFT JOIN t2 ON (j) IN (SELECT max(k) FROM t3);
i
@@ -1414,10 +1823,10 @@ SELECT *
FROM t2 LEFT JOIN t2 t3 ON (8, 4) IN (SELECT c1, c1 FROM t1)";
EXECUTE st1;
c2 c2
-10 10
+10 NULL
EXECUTE st1;
c2 c2
-10 10
+10 NULL
DROP TABLE t1, t2;
#
# Testcase backport: BUG#46548 IN-subqueries return 0 rows with materialization=on
@@ -1438,7 +1847,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
-2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Rowid-ordered scan
+2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 Using where
SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
pk
2
@@ -1537,3 +1946,65 @@ FROM t2;
(SELECT COUNT(DISTINCT f2), f1, f3 FROM t1 GROUP BY f1, f3)
1
drop table t1, t2;
+#
+# LPBUG#702301: MAX in select + always false WHERE with SQ
+#
+CREATE TABLE t1 (a int, b int, KEY (b));
+INSERT INTO t1 VALUES (3,1), (4,2);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (7), (8);
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+max_res
+NULL
+EXPLAIN EXTENDED
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL b 5 NULL 2 100.00 Using index
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1003 select max(`test`.`t1`.`b`) AS `max_res` from `test`.`t1` where <expr_cache><9>(<in_optimizer>(9,9 in ( <materialize> (select `test`.`t2`.`a` from `test`.`t2` ), <primary_index_lookup>(9 in <temporary table> on distinct_key where ((9 = `<subquery2>`.`a`))))))
+set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off';
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+max_res
+NULL
+EXPLAIN EXTENDED
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL b 5 NULL 2 100.00 Using index
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select max(`test`.`t1`.`b`) AS `max_res` from `test`.`t1` where <expr_cache><9>(<in_optimizer>(9,<exists>(select `test`.`t2`.`a` from `test`.`t2` where (9 = `test`.`t2`.`a`))))
+DROP TABLE t1,t2;
+#
+# LPBUG#825095: Wrong result with materialization and NOT IN with 2 expressions
+#
+CREATE TABLE t1 (a int,b int);
+INSERT INTO t1 VALUES (4,4),(4,2);
+CREATE TABLE t2 (b int, a int);
+INSERT INTO t2 VALUES (4,3),(8,4);
+set @@optimizer_switch='semijoin=off,in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN SELECT *
+FROM t1
+WHERE (a, b) NOT IN (SELECT a, b FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+SELECT *
+FROM t1
+WHERE (a, b) NOT IN (SELECT a, b FROM t2);
+a b
+4 4
+4 2
+EXPLAIN
+SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
+FROM t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
+FROM t1;
+a b sq
+4 4 1
+4 2 1
+drop table t1, t2;
diff --git a/mysql-test/r/subselect_mat_cost.result b/mysql-test/r/subselect_mat_cost.result
index 9d6986cf092..7a28b82455c 100644
--- a/mysql-test/r/subselect_mat_cost.result
+++ b/mysql-test/r/subselect_mat_cost.result
@@ -1,3771 +1,565 @@
-drop table if exists t1, t2, t1_1024, t2_1024;
-drop procedure if exists make_t1_indexes;
-drop procedure if exists make_t2_indexes;
-drop procedure if exists remove_t1_indexes;
-drop procedure if exists remove_t2_indexes;
-drop procedure if exists add_materialization_data;
-drop procedure if exists delete_materialization_data;
-drop procedure if exists set_all_columns_not_null;
-drop procedure if exists set_all_columns_nullable;
-create table t1 (a1 char(8), a2 char(8), a3 char(8), a4 int);
-insert into t1 values ('1 - 00', '2 - 00', '3 - 00', 0);
-insert into t1 values ('1 - 01', '2 - 01', '3 - 01', 1);
-insert into t1 values ('1 - 02', '2 - 02', '3 - 02', 2);
-create table t2 (b1 char(8), b2 char(8), b3 char(8), b4 int);
-insert into t2 values ('1 - 01', '2 - 01', '3 - 01', 1);
-insert into t2 values ('1 - 01', '2 - 01', '3 - 02', 2);
-insert into t2 values ('1 - 02', '2 - 02', '3 - 03', 3);
-insert into t2 values ('1 - 02', '2 - 02', '3 - 04', 4);
-insert into t2 values ('1 - 03', '2 - 03', '3 - 05', 5);
-create table t1_1024 (a1 blob(1024), a2 blob(1024));
-insert into t1_1024 values (concat('1 - 00', repeat('x', 1018)), concat('2 - 00', repeat('x', 1018)));
-insert into t1_1024 values (concat('1 - 01', repeat('x', 1018)), concat('2 - 01', repeat('x', 1018)));
-create table t2_1024 (b1 blob(1024), b2 blob(1024));
-insert into t2_1024 values (concat('1 - 01', repeat('x', 1018)), concat('2 - 01', repeat('x', 1018)));
-insert into t2_1024 values (concat('1 - 02', repeat('x', 1018)), concat('2 - 02', repeat('x', 1018)));
-insert into t2_1024 values (concat('1 - 03', repeat('x', 1018)), concat('2 - 03', repeat('x', 1018)));
-insert into t2_1024 values (concat('1 - 04', repeat('x', 1018)), concat('2 - 04', repeat('x', 1018)));
-create procedure make_t1_indexes()
-begin
-create index it1i1 on t1 (a1);
-create index it1i2 on t1 (a2);
-create index it1i3 on t1 (a1, a2);
-create index it1_1024i1 on t1_1024 (a1(6));
-create index it1_1024i2 on t1_1024 (a2(6));
-create index it1_1024i3 on t1_1024 (a1(6), a2(6));
-end|
-create procedure make_t2_indexes()
-begin
-create index it2i1 on t2 (b1);
-create index it2i2 on t2 (b2);
-create index it2i3 on t2 (b1, b2);
-create unique index it2i4 on t2 (b1, b2, b3);
-create index it2_1024i1 on t2_1024 (b1(6));
-create index it2_1024i2 on t2_1024 (b2(6));
-create index it2_1024i3 on t2_1024 (b1(6), b2(6));
-end|
-create procedure remove_t1_indexes()
-begin
-drop index it1i1 on t1;
-drop index it1i2 on t1;
-drop index it1i3 on t1;
-drop index it1_1024i1 on t1_1024;
-drop index it1_1024i2 on t1_1024;
-drop index it1_1024i3 on t1_1024;
-end|
-create procedure remove_t2_indexes()
-begin
-drop index it2i1 on t2;
-drop index it2i2 on t2;
-drop index it2i3 on t2;
-drop index it2i4 on t2;
-drop index it2_1024i1 on t2_1024;
-drop index it2_1024i2 on t2_1024;
-drop index it2_1024i3 on t2_1024;
-end|
-create procedure add_materialization_data()
-begin
-insert into t1 values ('1 - 03', '2 - 03', '3 - 03', 3);
-insert into t1 values ('1 - 04', '2 - 04', '3 - 04', 4);
-insert into t1 values ('1 - 05', '2 - 05', '3 - 05', 5);
-insert into t1 values ('1 - 06', '2 - 06', '3 - 06', 6);
-insert into t1 values ('1 - 07', '2 - 07', '3 - 07', 7);
-insert into t1_1024 values (concat('1 - 03', repeat('x', 1018)), concat('2 - 03', repeat('x', 1018)));
-end|
-create procedure delete_materialization_data()
-begin
-delete from t1 where a1 >= '1 - 03';
-delete from t1_1024 where a1 >= '1 - 03';
-end|
-create procedure set_all_columns_not_null()
-begin
-alter table t1 modify a1 char(8) not null, modify a2 char(8) not null, modify a3 char(8) not null;
-alter table t2 modify b1 char(8) not null, modify b2 char(8) not null, modify b3 char(8) not null;
-end|
-create procedure set_all_columns_nullable()
-begin
-alter table t1 modify a1 char(8) null, modify a2 char(8) null, modify a3 char(8) null;
-alter table t2 modify b1 char(8) null, modify b2 char(8) null, modify b3 char(8) null;
-end|
-
-/******************************************************************************
-1. Both materialization and in-to-exists are ON, make a cost-based choice.
-******************************************************************************/
-set @@optimizer_switch='materialization=on,in_to_exists=on';
-
-/* 1.1 In-to-exists is cheaper */
-call make_t1_indexes();
-/* 1.1.1 non-indexed table access */
-
-/* A. Subqueries in the SELECT clause. */
-explain
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using index
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-a1 a1 in (select b1 from t2 where b1 > '0')
-1 - 00 0
-1 - 01 1
-1 - 02 1
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 18 NULL 3 Using index
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 18 NULL 3 Using index
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-
-/*
-B. "Natural" examples of subqueries without grouping that
-cannot be flattened into semijoin.
-*/
-explain
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 18 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 18 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-a1 a2
-1 - 00 2 - 00
-1 - 01 2 - 01
-1 - 02 2 - 02
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i2 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-3 DEPENDENT UNION t3 ALL NULL NULL NULL NULL 5 Using where
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-a2
-2 - 01
-2 - 02
-
-explain
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref it1i1,it1i3 it1i1 9 const 1 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-a1
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 18 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-a1 a2
-1 - 01 2 - 01
-1 - 02 2 - 02
-
-/* C. Subqueries in the WHERE clause with GROUP BY. */
-explain
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-a1 a2 a3 a4
-
-explain
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-/*
-D. Subqueries for which materialization is not possible, and the
-optimizer reverts to in-to-exists.
-*/
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-
-
-/* E. Edge cases. */
-
-/* E.1 Both materialization and in_to_exists cannot be off. */
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off,in_to_exists=off';
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-ERROR HY000: At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'.
-set @@optimizer_switch = @save_optimizer_switch;
-/* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-'1 - 03' in (select b1 from t2 where b1 > '0')
-1
-/* E.3 Subqueries without tables. */
-explain
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i1,it1i2,it1i3 it1i3 18 NULL 3 Using where; Using index
-Warnings:
-Note 1249 Select 2 was reduced during optimization
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-a1
-1 - 02
-/* E.4 optimize_cond detects FALSE where/having clause. */
-explain
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 18 NULL 3 Using where; Using index
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-/* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
-TODO this test produces wrong result due to missing logic to handle the case
-when JOIN::optimize detects an empty subquery result.
-explain
-select a1 from t1 where a1 in (select max(b1) from t2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5
-select a1 from t1 where a1 in (select max(b1) from t2);
-a1
-
-explain
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-a1
-/* E.6 make_join_select detects impossible WHERE. *
-TODO
-/* E.7 constant optimization detects "no matching row in const table". */
-TODO
-/* E.8 Impossible WHERE noticed after reading const tables. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-'1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0')
-0
-
-/* F. UPDATE/DELETE with subqueries. */
-
-TODO
-
-/* 1.1.2 indexed table access, nullabale columns. */
-call make_t2_indexes();
-
-/* A. Subqueries in the SELECT clause. */
-explain
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using index
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i3 it2i1 9 func 2 Using index; Using where; Full scan on NULL key
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-a1 a1 in (select b1 from t2 where b1 > '0')
-1 - 00 0
-1 - 01 1
-1 - 02 1
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 18 NULL 3 Using index
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i2,it2i3 it2i3 9 func 2 Using index; Using where; Full scan on NULL key
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 18 NULL 3 Using index
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i2,it2i3 it2i3 9 func 2 Using index; Using where; Full scan on NULL key
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-
-/*
-B. "Natural" examples of subqueries without grouping that
-cannot be flattened into semijoin.
-*/
-explain
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 18 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 index_subquery it2i2 it2i2 9 func 2 Using index
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 18 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i2,it2i3 it2i4 18 func,func 1 Using index; Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-a1 a2
-1 - 00 2 - 00
-1 - 01 2 - 01
-1 - 02 2 - 02
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i2 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ref it2i2 it2i2 9 func 2 Using index
-3 DEPENDENT UNION t3 index NULL it2i4 27 NULL 5 Using where; Using index
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-a2
-2 - 01
-2 - 02
-
-explain
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref it1i1,it1i3 it1i1 9 const 1 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ref it2i2 it2i2 9 const 1 Using index condition
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-a1
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 18 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i2,it2i3 it2i4 18 func,func 1 Using index; Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-a1 a2
-1 - 01 2 - 01
-1 - 02 2 - 02
-
-/* C. Subqueries in the WHERE clause with GROUP BY. */
-explain
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index it2i4,it2i1,it2i3 it2i1 9 NULL 1 Using where; Using index
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 18 NULL 1 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 18 NULL 1 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index NULL it2i4 27 NULL 1 Using index
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index NULL it2i4 27 NULL 1 Using where; Using index
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-a1 a2 a3 a4
-
-explain
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 range it2i4,it2i1,it2i3 it2i4 27 NULL 2 Using where; Using index for group-by
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-/*
-D. Subqueries for which materialization is not possible, and the
-optimizer reverts to in-to-exists.
-*/
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i3 it2_1024i3 9 func 1 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i2,it2_1024i3 it2_1024i1 9 func 2 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-
-
-/* E. Edge cases. */
-
-/* E.1 Both materialization and in_to_exists cannot be off. */
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off,in_to_exists=off';
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-ERROR HY000: At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'.
-set @@optimizer_switch = @save_optimizer_switch;
-/* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i3 it2i1 9 const 2 Using index; Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-'1 - 03' in (select b1 from t2 where b1 > '0')
-1
-/* E.3 Subqueries without tables. */
-explain
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i1,it1i2,it1i3 it1i3 18 NULL 3 Using where; Using index
-Warnings:
-Note 1249 Select 2 was reduced during optimization
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-a1
-1 - 02
-/* E.4 optimize_cond detects FALSE where/having clause. */
-explain
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 18 NULL 3 Using where; Using index
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-/* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
-TODO this test produces wrong result due to missing logic to handle the case
-when JOIN::optimize detects an empty subquery result.
-explain
-select a1 from t1 where a1 in (select max(b1) from t2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-select a1 from t1 where a1 in (select max(b1) from t2);
-a1
-
-explain
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-a1
-/* E.6 make_join_select detects impossible WHERE. *
-TODO
-/* E.7 constant optimization detects "no matching row in const table". */
-TODO
-/* E.8 Impossible WHERE noticed after reading const tables. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-'1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0')
-0
-
-/* F. UPDATE/DELETE with subqueries. */
-
-TODO
-
-/* 1.1.3 indexed table access, non-nullabale columns. */
-call set_all_columns_not_null();
-
-/* A. Subqueries in the SELECT clause. */
-explain
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 8 NULL 3 Using index
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i3 it2i4 8 func 1 Using index; Using where
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-a1 a1 in (select b1 from t2 where b1 > '0')
-1 - 00 0
-1 - 01 1
-1 - 02 1
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 16 NULL 3 Using index
-2 DEPENDENT SUBQUERY t2 ref it2i4,it2i1,it2i2,it2i3 it2i4 8 func 2 Using where; Using index
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 16 NULL 3 Using index
-2 DEPENDENT SUBQUERY t2 ref it2i4,it2i1,it2i2,it2i3 it2i4 8 func 2 Using where; Using index
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-
-/*
-B. "Natural" examples of subqueries without grouping that
-cannot be flattened into semijoin.
-*/
-explain
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 16 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 index_subquery it2i2 it2i2 8 func 2 Using index
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 16 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i2,it2i3 it2i4 16 func,func 1 Using index; Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-a1 a2
-1 - 00 2 - 00
-1 - 01 2 - 01
-1 - 02 2 - 02
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i2 8 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ref it2i2 it2i2 8 func 2 Using index
-3 DEPENDENT UNION t3 index NULL it2i4 24 NULL 5 Using where; Using index
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-a2
-2 - 01
-2 - 02
-
-explain
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref it1i1,it1i3 it1i1 8 const 1 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ref it2i2 it2i2 8 const 1 Using index condition
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-a1
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 16 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i2,it2i3 it2i4 16 func,func 1 Using index; Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-a1 a2
-1 - 01 2 - 01
-1 - 02 2 - 02
-
-/* C. Subqueries in the WHERE clause with GROUP BY. */
-explain
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index it2i4,it2i1,it2i3 it2i1 8 NULL 1 Using where; Using index
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 16 NULL 1 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 16 NULL 1 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index NULL it2i4 24 NULL 1 Using index
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index NULL it2i4 24 NULL 1 Using where; Using index
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-a1 a2 a3 a4
-
-explain
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 range it2i4,it2i1,it2i3 it2i4 24 NULL 2 Using where; Using index for group-by
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-/*
-D. Subqueries for which materialization is not possible, and the
-optimizer reverts to in-to-exists.
-*/
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i3 it2_1024i3 9 func 1 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i2,it2_1024i3 it2_1024i1 9 func 2 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-
-
-/* E. Edge cases. */
-
-/* E.1 Both materialization and in_to_exists cannot be off. */
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off,in_to_exists=off';
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-ERROR HY000: At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'.
-set @@optimizer_switch = @save_optimizer_switch;
-/* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i3 it2i1 8 const 5 Using index; Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-'1 - 03' in (select b1 from t2 where b1 > '0')
-1
-/* E.3 Subqueries without tables. */
-explain
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i1,it1i2,it1i3 it1i3 16 NULL 3 Using where; Using index
-Warnings:
-Note 1249 Select 2 was reduced during optimization
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 8 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-a1
-1 - 02
-/* E.4 optimize_cond detects FALSE where/having clause. */
-explain
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 16 NULL 3 Using where; Using index
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-/* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
-TODO this test produces wrong result due to missing logic to handle the case
-when JOIN::optimize detects an empty subquery result.
-explain
-select a1 from t1 where a1 in (select max(b1) from t2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 8 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-select a1 from t1 where a1 in (select max(b1) from t2);
-a1
-
-explain
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 8 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-a1
-/* E.6 make_join_select detects impossible WHERE. *
-TODO
-/* E.7 constant optimization detects "no matching row in const table". */
-TODO
-/* E.8 Impossible WHERE noticed after reading const tables. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-'1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0')
-0
-
-/* F. UPDATE/DELETE with subqueries. */
-
-TODO
-
-call set_all_columns_nullable();
-
-/* 1.2 Materialization is cheaper */
-call add_materialization_data();
-call remove_t1_indexes();
-/* 1.2.1 non-indexed table access */
-call remove_t2_indexes();
-
-/* A. Subqueries in the SELECT clause. */
-explain
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-a1 a1 in (select b1 from t2 where b1 > '0')
-1 - 00 0
-1 - 01 1
-1 - 02 1
-1 - 03 1
-1 - 04 0
-1 - 05 0
-1 - 06 0
-1 - 07 0
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-1 - 03 2 - 03 1
-1 - 04 2 - 04 0
-1 - 05 2 - 05 0
-1 - 06 2 - 06 0
-1 - 07 2 - 07 0
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-1 - 03 2 - 03 1
-1 - 04 2 - 04 0
-1 - 05 2 - 05 0
-1 - 06 2 - 06 0
-1 - 07 2 - 07 0
-
-/*
-B. "Natural" examples of subqueries without grouping that
-cannot be flattened into semijoin.
-*/
-explain
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-a1 a2
-1 - 00 2 - 00
-1 - 01 2 - 01
-1 - 02 2 - 02
-1 - 03 2 - 03
-1 - 04 2 - 04
-1 - 05 2 - 05
-1 - 06 2 - 06
-1 - 07 2 - 07
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-3 DEPENDENT UNION t3 ALL NULL NULL NULL NULL 5 Using where
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-a2
-2 - 01
-2 - 02
-2 - 03
-
-explain
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-a1
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-a1 a2
-1 - 01 2 - 01
-1 - 02 2 - 02
-1 - 03 2 - 03
-
-/* C. Subqueries in the WHERE clause with GROUP BY. */
-explain
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-a1 a2 a3 a4
-
-explain
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-/*
-D. Subqueries for which materialization is not possible, and the
-optimizer reverts to in-to-exists.
-*/
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-
-
-/* E. Edge cases. */
-
-/* E.1 Both materialization and in_to_exists cannot be off. */
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off,in_to_exists=off';
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-ERROR HY000: At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'.
-set @@optimizer_switch = @save_optimizer_switch;
-/* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-'1 - 03' in (select b1 from t2 where b1 > '0')
-1
-/* E.3 Subqueries without tables. */
-explain
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-Warnings:
-Note 1249 Select 2 was reduced during optimization
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-a1
-1 - 02
-1 - 03
-/* E.4 optimize_cond detects FALSE where/having clause. */
-explain
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-/* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
-TODO this test produces wrong result due to missing logic to handle the case
-when JOIN::optimize detects an empty subquery result.
-explain
-select a1 from t1 where a1 in (select max(b1) from t2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5
-select a1 from t1 where a1 in (select max(b1) from t2);
-a1
-1 - 03
-
-explain
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-a1
-/* E.6 make_join_select detects impossible WHERE. *
-TODO
-/* E.7 constant optimization detects "no matching row in const table". */
-TODO
-/* E.8 Impossible WHERE noticed after reading const tables. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-'1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0')
-0
-
-/* F. UPDATE/DELETE with subqueries. */
-
-TODO
-
-/* 1.2.2 indexed table access, nullabale columns. */
-call make_t2_indexes();
-
-/* A. Subqueries in the SELECT clause. */
-explain
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i1 9 NULL 5 Using where; Using index
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-a1 a1 in (select b1 from t2 where b1 > '0')
-1 - 00 0
-1 - 01 1
-1 - 02 1
-1 - 03 1
-1 - 04 0
-1 - 05 0
-1 - 06 0
-1 - 07 0
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 SUBQUERY t2 index it2i4,it2i1,it2i2,it2i3 it2i3 18 NULL 5 Using where; Using index
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-1 - 03 2 - 03 1
-1 - 04 2 - 04 0
-1 - 05 2 - 05 0
-1 - 06 2 - 06 0
-1 - 07 2 - 07 0
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 SUBQUERY t2 range it2i4,it2i1,it2i2,it2i3 it2i3 9 NULL 4 Using where; Using index
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-1 - 03 2 - 03 1
-1 - 04 2 - 04 0
-1 - 05 2 - 05 0
-1 - 06 2 - 06 0
-1 - 07 2 - 07 0
-
-/*
-B. "Natural" examples of subqueries without grouping that
-cannot be flattened into semijoin.
-*/
-explain
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 index it2i2 it2i2 9 NULL 5 Using index
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i2,it2i3 it2i3 18 NULL 5 Using where; Using index
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-a1 a2
-1 - 00 2 - 00
-1 - 01 2 - 01
-1 - 02 2 - 02
-1 - 03 2 - 03
-1 - 04 2 - 04
-1 - 05 2 - 05
-1 - 06 2 - 06
-1 - 07 2 - 07
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ref it2i2 it2i2 9 func 2 Using index
-3 DEPENDENT UNION t3 index NULL it2i4 27 NULL 5 Using where; Using index
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-a2
-2 - 01
-2 - 02
-2 - 03
-
-explain
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ref it2i2 it2i2 9 const 1 Using index condition
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-a1
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i2,it2i3 it2i4 27 NULL 5 Using index
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-a1 a2
-1 - 01 2 - 01
-1 - 02 2 - 02
-1 - 03 2 - 03
-
-/* C. Subqueries in the WHERE clause with GROUP BY. */
-explain
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i1 9 NULL 5 Using where; Using index
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 18 NULL 5 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 18 NULL 5 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 range NULL it2i4 27 NULL 6 Using index for group-by
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 range NULL it2i4 27 NULL 6 Using where; Using index for group-by
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-a1 a2 a3 a4
-
-explain
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 range it2i4,it2i1,it2i3 it2i4 27 NULL 2 Using where; Using index for group-by
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-/*
-D. Subqueries for which materialization is not possible, and the
-optimizer reverts to in-to-exists.
-*/
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i3 it2_1024i3 9 func 1 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i2,it2_1024i3 it2_1024i1 9 func 2 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-
-
-/* E. Edge cases. */
-
-/* E.1 Both materialization and in_to_exists cannot be off. */
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off,in_to_exists=off';
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-ERROR HY000: At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'.
-set @@optimizer_switch = @save_optimizer_switch;
-/* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i3 it2i1 9 const 2 Using index; Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-'1 - 03' in (select b1 from t2 where b1 > '0')
-1
-/* E.3 Subqueries without tables. */
-explain
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-Warnings:
-Note 1249 Select 2 was reduced during optimization
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-a1
-1 - 02
-1 - 03
-/* E.4 optimize_cond detects FALSE where/having clause. */
-explain
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-/* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
-TODO this test produces wrong result due to missing logic to handle the case
-when JOIN::optimize detects an empty subquery result.
-explain
-select a1 from t1 where a1 in (select max(b1) from t2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-select a1 from t1 where a1 in (select max(b1) from t2);
-a1
-1 - 03
-
-explain
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-a1
-/* E.6 make_join_select detects impossible WHERE. *
-TODO
-/* E.7 constant optimization detects "no matching row in const table". */
-TODO
-/* E.8 Impossible WHERE noticed after reading const tables. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-'1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0')
-0
-
-/* F. UPDATE/DELETE with subqueries. */
-
-TODO
-
-/* 1.2.3 indexed table access, non-nullabale columns. */
-call set_all_columns_not_null();
-
-/* A. Subqueries in the SELECT clause. */
-explain
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i1 8 NULL 5 Using where; Using index
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-a1 a1 in (select b1 from t2 where b1 > '0')
-1 - 00 0
-1 - 01 1
-1 - 02 1
-1 - 03 1
-1 - 04 0
-1 - 05 0
-1 - 06 0
-1 - 07 0
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 SUBQUERY t2 index it2i4,it2i1,it2i2,it2i3 it2i3 16 NULL 5 Using where; Using index
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-1 - 03 2 - 03 1
-1 - 04 2 - 04 0
-1 - 05 2 - 05 0
-1 - 06 2 - 06 0
-1 - 07 2 - 07 0
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 SUBQUERY t2 range it2i4,it2i1,it2i2,it2i3 it2i3 8 NULL 4 Using where; Using index
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-1 - 03 2 - 03 1
-1 - 04 2 - 04 0
-1 - 05 2 - 05 0
-1 - 06 2 - 06 0
-1 - 07 2 - 07 0
-
-/*
-B. "Natural" examples of subqueries without grouping that
-cannot be flattened into semijoin.
-*/
-explain
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 index it2i2 it2i2 8 NULL 5 Using index
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i2,it2i3 it2i3 16 NULL 5 Using where; Using index
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-a1 a2
-1 - 00 2 - 00
-1 - 01 2 - 01
-1 - 02 2 - 02
-1 - 03 2 - 03
-1 - 04 2 - 04
-1 - 05 2 - 05
-1 - 06 2 - 06
-1 - 07 2 - 07
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ref it2i2 it2i2 8 func 2 Using index
-3 DEPENDENT UNION t3 index NULL it2i4 24 NULL 5 Using where; Using index
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-a2
-2 - 01
-2 - 02
-2 - 03
-
-explain
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 ref it2i2 it2i2 8 const 1 Using index condition
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-a1
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i2,it2i3 it2i4 24 NULL 5 Using index
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-a1 a2
-1 - 01 2 - 01
-1 - 02 2 - 02
-1 - 03 2 - 03
-
-/* C. Subqueries in the WHERE clause with GROUP BY. */
-explain
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i1 8 NULL 5 Using where; Using index
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 16 NULL 5 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 16 NULL 5 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 range NULL it2i4 24 NULL 6 Using index for group-by
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 range NULL it2i4 24 NULL 6 Using where; Using index for group-by
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-a1 a2 a3 a4
-
-explain
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY t2 range it2i4,it2i1,it2i3 it2i4 24 NULL 2 Using where; Using index for group-by
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-/*
-D. Subqueries for which materialization is not possible, and the
-optimizer reverts to in-to-exists.
-*/
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i3 it2_1024i3 9 func 1 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i2,it2_1024i3 it2_1024i1 9 func 2 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-
-
-/* E. Edge cases. */
-
-/* E.1 Both materialization and in_to_exists cannot be off. */
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off,in_to_exists=off';
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-ERROR HY000: At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'.
-set @@optimizer_switch = @save_optimizer_switch;
-/* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i3 it2i1 8 const 5 Using index; Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-'1 - 03' in (select b1 from t2 where b1 > '0')
-1
-/* E.3 Subqueries without tables. */
-explain
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-Warnings:
-Note 1249 Select 2 was reduced during optimization
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-a1
-1 - 02
-1 - 03
-/* E.4 optimize_cond detects FALSE where/having clause. */
-explain
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-/* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
-TODO this test produces wrong result due to missing logic to handle the case
-when JOIN::optimize detects an empty subquery result.
-explain
-select a1 from t1 where a1 in (select max(b1) from t2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-select a1 from t1 where a1 in (select max(b1) from t2);
-a1
-1 - 03
-
-explain
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-a1
-/* E.6 make_join_select detects impossible WHERE. *
-TODO
-/* E.7 constant optimization detects "no matching row in const table". */
-TODO
-/* E.8 Impossible WHERE noticed after reading const tables. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-'1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0')
-0
-
-/* F. UPDATE/DELETE with subqueries. */
-
-TODO
-
-call set_all_columns_nullable();
-/******************************************************************************
-2. Materialization is OFF, in-to-exists is ON, materialization is cheaper.
-******************************************************************************/
-set @@optimizer_switch='materialization=off,in_to_exists=on';
-/* 2.1 non-indexed table access */
-call remove_t2_indexes();
-
-/* A. Subqueries in the SELECT clause. */
-explain
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-a1 a1 in (select b1 from t2 where b1 > '0')
-1 - 00 0
-1 - 01 1
-1 - 02 1
-1 - 03 1
-1 - 04 0
-1 - 05 0
-1 - 06 0
-1 - 07 0
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-1 - 03 2 - 03 1
-1 - 04 2 - 04 0
-1 - 05 2 - 05 0
-1 - 06 2 - 06 0
-1 - 07 2 - 07 0
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-1 - 03 2 - 03 1
-1 - 04 2 - 04 0
-1 - 05 2 - 05 0
-1 - 06 2 - 06 0
-1 - 07 2 - 07 0
-
-/*
-B. "Natural" examples of subqueries without grouping that
-cannot be flattened into semijoin.
-*/
-explain
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-a1 a2
-1 - 00 2 - 00
-1 - 01 2 - 01
-1 - 02 2 - 02
-1 - 03 2 - 03
-1 - 04 2 - 04
-1 - 05 2 - 05
-1 - 06 2 - 06
-1 - 07 2 - 07
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-3 DEPENDENT UNION t3 ALL NULL NULL NULL NULL 5 Using where
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-a2
-2 - 01
-2 - 02
-2 - 03
-
-explain
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-a1
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-a1 a2
-1 - 01 2 - 01
-1 - 02 2 - 02
-1 - 03 2 - 03
-
-/* C. Subqueries in the WHERE clause with GROUP BY. */
-explain
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-a1 a2 a3 a4
-
-explain
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-/*
-D. Subqueries for which materialization is not possible, and the
-optimizer reverts to in-to-exists.
-*/
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-
-
-/* E. Edge cases. */
-
-/* E.1 Both materialization and in_to_exists cannot be off. */
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off,in_to_exists=off';
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-ERROR HY000: At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'.
-set @@optimizer_switch = @save_optimizer_switch;
-/* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-'1 - 03' in (select b1 from t2 where b1 > '0')
-1
-/* E.3 Subqueries without tables. */
-explain
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-Warnings:
-Note 1249 Select 2 was reduced during optimization
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-a1
-1 - 02
-1 - 03
-/* E.4 optimize_cond detects FALSE where/having clause. */
-explain
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-/* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
-TODO this test produces wrong result due to missing logic to handle the case
-when JOIN::optimize detects an empty subquery result.
-explain
-select a1 from t1 where a1 in (select max(b1) from t2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5
-select a1 from t1 where a1 in (select max(b1) from t2);
-a1
-1 - 03
-
-explain
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-a1
-/* E.6 make_join_select detects impossible WHERE. *
-TODO
-/* E.7 constant optimization detects "no matching row in const table". */
-TODO
-/* E.8 Impossible WHERE noticed after reading const tables. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-'1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0')
-0
-
-/* F. UPDATE/DELETE with subqueries. */
-
-TODO
-
-/* 2.2 indexed table access, nullabale columns. */
-call make_t2_indexes();
-
-/* A. Subqueries in the SELECT clause. */
-explain
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i3 it2i1 9 func 2 Using index; Using where; Full scan on NULL key
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-a1 a1 in (select b1 from t2 where b1 > '0')
-1 - 00 0
-1 - 01 1
-1 - 02 1
-1 - 03 1
-1 - 04 0
-1 - 05 0
-1 - 06 0
-1 - 07 0
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i2,it2i3 it2i3 9 func 2 Using index; Using where; Full scan on NULL key
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-1 - 03 2 - 03 1
-1 - 04 2 - 04 0
-1 - 05 2 - 05 0
-1 - 06 2 - 06 0
-1 - 07 2 - 07 0
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i2,it2i3 it2i3 9 func 2 Using index; Using where; Full scan on NULL key
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-1 - 03 2 - 03 1
-1 - 04 2 - 04 0
-1 - 05 2 - 05 0
-1 - 06 2 - 06 0
-1 - 07 2 - 07 0
-
-/*
-B. "Natural" examples of subqueries without grouping that
-cannot be flattened into semijoin.
-*/
-explain
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index_subquery it2i2 it2i2 9 func 2 Using index
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i2,it2i3 it2i4 18 func,func 1 Using index; Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-a1 a2
-1 - 00 2 - 00
-1 - 01 2 - 01
-1 - 02 2 - 02
-1 - 03 2 - 03
-1 - 04 2 - 04
-1 - 05 2 - 05
-1 - 06 2 - 06
-1 - 07 2 - 07
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ref it2i2 it2i2 9 func 2 Using index
-3 DEPENDENT UNION t3 index NULL it2i4 27 NULL 5 Using where; Using index
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-a2
-2 - 01
-2 - 02
-2 - 03
-
-explain
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ref it2i2 it2i2 9 const 1 Using index condition
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-a1
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i2,it2i3 it2i4 18 func,func 1 Using index; Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-a1 a2
-1 - 01 2 - 01
-1 - 02 2 - 02
-1 - 03 2 - 03
-
-/* C. Subqueries in the WHERE clause with GROUP BY. */
-explain
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index it2i4,it2i1,it2i3 it2i1 9 NULL 1 Using where; Using index
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 18 NULL 1 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 18 NULL 1 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index NULL it2i4 27 NULL 1 Using index
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index NULL it2i4 27 NULL 1 Using where; Using index
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-a1 a2 a3 a4
-
-explain
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 range it2i4,it2i1,it2i3 it2i4 27 NULL 2 Using where; Using index for group-by
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-/*
-D. Subqueries for which materialization is not possible, and the
-optimizer reverts to in-to-exists.
-*/
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i3 it2_1024i3 9 func 1 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i2,it2_1024i3 it2_1024i1 9 func 2 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-
-
-/* E. Edge cases. */
-
-/* E.1 Both materialization and in_to_exists cannot be off. */
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off,in_to_exists=off';
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-ERROR HY000: At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'.
-set @@optimizer_switch = @save_optimizer_switch;
-/* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i3 it2i1 9 const 2 Using index; Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-'1 - 03' in (select b1 from t2 where b1 > '0')
-1
-/* E.3 Subqueries without tables. */
-explain
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-Warnings:
-Note 1249 Select 2 was reduced during optimization
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-a1
-1 - 02
-1 - 03
-/* E.4 optimize_cond detects FALSE where/having clause. */
-explain
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-/* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
-TODO this test produces wrong result due to missing logic to handle the case
-when JOIN::optimize detects an empty subquery result.
-explain
-select a1 from t1 where a1 in (select max(b1) from t2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-select a1 from t1 where a1 in (select max(b1) from t2);
-a1
-1 - 03
-
-explain
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-a1
-/* E.6 make_join_select detects impossible WHERE. *
-TODO
-/* E.7 constant optimization detects "no matching row in const table". */
-TODO
-/* E.8 Impossible WHERE noticed after reading const tables. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-'1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0')
-0
-
-/* F. UPDATE/DELETE with subqueries. */
-
-TODO
-
-/* 2.3 indexed table access, non-nullabale columns. */
-call set_all_columns_not_null();
-
-/* A. Subqueries in the SELECT clause. */
-explain
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i3 it2i4 8 func 1 Using index; Using where
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-a1 a1 in (select b1 from t2 where b1 > '0')
-1 - 00 0
-1 - 01 1
-1 - 02 1
-1 - 03 1
-1 - 04 0
-1 - 05 0
-1 - 06 0
-1 - 07 0
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 DEPENDENT SUBQUERY t2 ref it2i4,it2i1,it2i2,it2i3 it2i4 8 func 2 Using where; Using index
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-1 - 03 2 - 03 1
-1 - 04 2 - 04 0
-1 - 05 2 - 05 0
-1 - 06 2 - 06 0
-1 - 07 2 - 07 0
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8
-2 DEPENDENT SUBQUERY t2 ref it2i4,it2i1,it2i2,it2i3 it2i4 8 func 2 Using where; Using index
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-1 - 03 2 - 03 1
-1 - 04 2 - 04 0
-1 - 05 2 - 05 0
-1 - 06 2 - 06 0
-1 - 07 2 - 07 0
-
-/*
-B. "Natural" examples of subqueries without grouping that
-cannot be flattened into semijoin.
-*/
-explain
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index_subquery it2i2 it2i2 8 func 2 Using index
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i2,it2i3 it2i4 16 func,func 1 Using index; Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-a1 a2
-1 - 00 2 - 00
-1 - 01 2 - 01
-1 - 02 2 - 02
-1 - 03 2 - 03
-1 - 04 2 - 04
-1 - 05 2 - 05
-1 - 06 2 - 06
-1 - 07 2 - 07
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ref it2i2 it2i2 8 func 2 Using index
-3 DEPENDENT UNION t3 index NULL it2i4 24 NULL 5 Using where; Using index
+set @subselect_mat_cost=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set log_slow_time=0.1;
+TEST GROUP 1:
+Typical cases of in-to-exists and materialization subquery strategies
+=====================================================================
+drop database if exists world;
+set names utf8;
+create database world;
+use world;
+CREATE TABLE Country (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+Population int(11) NOT NULL default '0',
+Capital int(11) default NULL,
+PRIMARY KEY (Code),
+UNIQUE INDEX (Name)
+);
+CREATE TABLE City (
+ID int(11) NOT NULL auto_increment,
+Name char(35) NOT NULL default '',
+Country char(3) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID),
+INDEX (Population),
+INDEX (Country)
+);
+CREATE TABLE CountryLanguage (
+Country char(3) NOT NULL default '',
+Language char(30) NOT NULL default '',
+Percentage float(3,1) NOT NULL default '0.0',
+PRIMARY KEY (Country, Language),
+INDEX (Percentage)
+);
+Make the schema and data more diverse by adding more indexes, nullable
+columns, and NULL data.
+create index SurfaceArea on Country(SurfaceArea);
+create index Language on CountryLanguage(Language);
+create index CityName on City(Name);
+alter table City change population population int(11) null default 0;
+select max(id) from City into @max_city_id;
+insert into City values (@max_city_id + 1,'Kilifarevo','BGR',NULL);
+SELECT COUNT(*) FROM Country;
+COUNT(*)
+239
+SELECT COUNT(*) FROM City;
+COUNT(*)
+4080
+SELECT COUNT(*) FROM CountryLanguage;
+COUNT(*)
+984
+set @@optimizer_switch = 'in_to_exists=on,semijoin=on,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on';
+
+1. Subquery in a disjunctive WHERE clause of the outer query.
+
+
+Q1.1m:
+MATERIALIZATION: there are too many rows in the outer query
+to be looked up in the inner table.
+EXPLAIN
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+Name LIKE 'L%') AND
+surfacearea > 1000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country ALL Name,SurfaceArea NULL NULL NULL 239 Using where
+2 SUBQUERY City ALL Population,Country NULL NULL NULL 4080 Using where
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+Name LIKE 'L%') AND
+surfacearea > 1000000;
+Name
+Algeria
+Angola
+Argentina
+Australia
+Bolivia
+Brazil
+Egypt
+South Africa
+Ethiopia
+Indonesia
+India
+Iran
+Canada
+Kazakstan
+China
+Colombia
+Congo, The Democratic Republic of the
+Libyan Arab Jamahiriya
+Mali
+Mauritania
+Mexico
+Mongolia
+Niger
+Peru
+Saudi Arabia
+Sudan
+Chad
+Russian Federation
+United States
+Q1.1e:
+IN-EXISTS: the materialization cost is the same as above, but
+there are much fewer outer rows to be looked up, thus the
+materialization cost is too high to compensate for fast lookups.
+EXPLAIN
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+Name LIKE 'L%') AND
+surfacearea > 10*1000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country range Name,SurfaceArea SurfaceArea 4 NULL 5 Using index condition; Using where; Rowid-ordered scan
+2 DEPENDENT SUBQUERY City index_subquery Population,Country Country 3 func 18 Using where
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+Name LIKE 'L%') AND
+surfacearea > 10*1000000;
+Name
+Russian Federation
+
+Q1.2m:
+MATERIALIZATION: the IN predicate is pushed (attached) to the last table
+in the join order (Country, City), therefore there are too many row
+combinations to filter by re-executing the subquery for each combination.
+EXPLAIN
+SELECT *
+FROM Country, City
+WHERE City.Country = Country.Code AND
+Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+(City.Name IN
+(select Language from CountryLanguage where Percentage > 50) OR
+City.name LIKE '%Island%');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where
+1 PRIMARY City ref Country Country 3 world.Country.Code 18 Using where
+2 SUBQUERY CountryLanguage ALL Percentage,Language NULL NULL NULL 984 Using where
+SELECT *
+FROM Country, City
+WHERE City.Country = Country.Code AND
+Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+(City.Name IN
+(select Language from CountryLanguage where Percentage > 50) OR
+City.name LIKE '%Island%');
+Code Name SurfaceArea Population Capital ID Name Country population
+CCK Cocos (Keeling) Islands 14.00 600 2317 2317 West Island CCK 167
+Q1.2e:
+IN_EXISTS: join order is the same, but the left IN operand refers to
+only the first table in the join order (Country), so there are much
+fewer rows to filter by subquery re-execution.
+EXPLAIN
+SELECT *
+FROM Country, City
+WHERE City.Country = Country.Code AND
+Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+(Country.Name IN
+(select Language from CountryLanguage where Percentage > 50) OR
+Country.name LIKE '%Island%');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where
+1 PRIMARY City ref Country Country 3 world.Country.Code 18
+2 DEPENDENT SUBQUERY CountryLanguage index_subquery Percentage,Language Language 30 func 2 Using where
+SELECT *
+FROM Country, City
+WHERE City.Country = Country.Code AND
+Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+(Country.Name IN
+(select Language from CountryLanguage where Percentage > 50) OR
+Country.name LIKE '%Island%');
+Code Name SurfaceArea Population Capital ID Name Country population
+VGB Virgin Islands, British 151.00 21000 537 537 Road Town VGB 8000
+CYM Cayman Islands 264.00 38000 553 553 George Town CYM 19600
+COK Cook Islands 236.00 20000 583 583 Avarua COK 11900
+FRO Faroe Islands 1399.00 43000 901 901 Tórshavn FRO 14542
+CXR Christmas Island 135.00 2500 1791 1791 Flying Fish Cove CXR 700
+KIR Kiribati 726.00 83000 2256 2255 Bikenibeu KIR 5055
+KIR Kiribati 726.00 83000 2256 2256 Bairiki KIR 2226
+CCK Cocos (Keeling) Islands 14.00 600 2317 2316 Bantam CCK 503
+CCK Cocos (Keeling) Islands 14.00 600 2317 2317 West Island CCK 167
+MHL Marshall Islands 181.00 64000 2507 2507 Dalap-Uliga-Darrit MHL 28000
+NRU Nauru 21.00 12000 2728 2727 Yangor NRU 4050
+NRU Nauru 21.00 12000 2728 2728 Yaren NRU 559
+NFK Norfolk Island 36.00 2000 2806 2806 Kingston NFK 800
+PLW Palau 459.00 19000 2881 2881 Koror PLW 12000
+MNP Northern Mariana Islands 464.00 78000 2913 2913 Garapan MNP 9200
+TCA Turks and Caicos Islands 430.00 17000 3423 3423 Cockburn Town TCA 4800
+TUV Tuvalu 26.00 12000 3424 3424 Funafuti TUV 4600
+VIR Virgin Islands, U.S. 347.00 93000 4067 4067 Charlotte Amalie VIR 13000
+
+Q1.3:
+For the same reasons as in Q2 IN-EXISTS and MATERIALIZATION chosen
+for each respective subquery.
+EXPLAIN
+SELECT City.Name, Country.Name
+FROM City,Country
+WHERE City.Country = Country.Code AND
+Country.SurfaceArea < 30000 AND Country.SurfaceArea > 10 AND
+((Country.Code, Country.Name) IN
+(select Country, Language from CountryLanguage where Percentage > 50) AND
+Country.Population > 3000000
+OR
+(Country.Code, City.Name) IN
+(select Country, Language from CountryLanguage));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where
+1 PRIMARY City ref Country Country 3 world.Country.Code 18 Using where
+3 SUBQUERY CountryLanguage index PRIMARY,Language PRIMARY 33 NULL 984 Using index
+2 DEPENDENT SUBQUERY CountryLanguage unique_subquery PRIMARY,Percentage,Language PRIMARY 33 func,func 1 Using where
+SELECT City.Name, Country.Name
+FROM City,Country
+WHERE City.Country = Country.Code AND
+Country.SurfaceArea < 30000 AND Country.SurfaceArea > 10 AND
+((Country.Code, Country.Name) IN
+(select Country, Language from CountryLanguage where Percentage > 50) AND
+Country.Population > 3000000
+OR
+(Country.Code, City.Name) IN
+(select Country, Language from CountryLanguage));
+Name Name
+Kigali Rwanda
+
+2. NOT IN subqueries
+
+
+Q2.1:
+Number of cities that are not capitals in countries with small population.
+MATERIALIZATION is 50 times faster because the cost of each subquery
+re-execution is much higher than the cost of index lookups into the
+materialized subquery.
+EXPLAIN
+select count(*) from City
+where City.id not in (select capital from Country
+where capital is not null and population < 100000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY City index NULL PRIMARY 4 NULL 4080 Using where; Using index
+2 SUBQUERY Country ALL NULL NULL NULL NULL 239 Using where
+
+Q2.2e:
+Countries that speak French, but do not speak English
+IN-EXISTS because the outer query filters many rows, thus
+there are few lookups to make.
+EXPLAIN
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+AND CountryLanguage.Language = 'French'
+ AND Code = Country;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY CountryLanguage ref PRIMARY,Language Language 30 const 20 Using index condition
+1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using index condition
+2 DEPENDENT SUBQUERY CountryLanguage unique_subquery PRIMARY,Language PRIMARY 33 func,const 1 Using index; Using where
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+AND CountryLanguage.Language = 'French'
+ AND Code = Country;
+Name
+France
+Saint Pierre and Miquelon
+Belgium
+Burundi
+Guadeloupe
+Haiti
+Madagascar
+Martinique
+Mayotte
+French Polynesia
+Rwanda
+Sao Tome and Principe
+Switzerland
+New Caledonia
+Lebanon
+Mauritius
+Andorra
+Italy
+Luxembourg
+Q2.2m:
+Countries that speak French OR Spanish, but do not speak English
+MATERIALIZATION because the outer query filters less rows than Q5-a,
+so there are more lookups.
+EXPLAIN
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish')
+AND Code = Country;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY CountryLanguage range PRIMARY,Language Language 30 NULL 45 Using index condition; Using where; Rowid-ordered scan
+1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using index condition
+2 SUBQUERY CountryLanguage ref PRIMARY,Language Language 30 const 47 Using index condition
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish')
+AND Code = Country;
+Name
+Andorra
+Argentina
+Bolivia
+Chile
+Costa Rica
+Dominican Republic
+Ecuador
+El Salvador
+Spain
+Guatemala
+Honduras
+Colombia
+Cuba
+Mexico
+Nicaragua
+Panama
+Paraguay
+Peru
+France
+Saint Pierre and Miquelon
+Uruguay
+Venezuela
+Belgium
+Burundi
+Guadeloupe
+Haiti
+Madagascar
+Martinique
+Mayotte
+French Polynesia
+Rwanda
+Sao Tome and Principe
+Switzerland
+New Caledonia
+Lebanon
+Mauritius
+Andorra
+Italy
+Luxembourg
+France
+Sweden
+
+Q2.3e:
+Not a very meaningful query that tests NOT IN.
+IN-EXISTS because the outer query is cheap enough to reexecute many times.
+EXPLAIN
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+(SELECT City.Name, Country.Code
+FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000))
+AND Language IN ('English','Spanish');
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY CountryLanguage range Language Language 30 NULL 72 Using index condition; Using where; Rowid-ordered scan
+2 DEPENDENT SUBQUERY City ref CityName CityName 35 func 2 Using index condition; Using where
+2 DEPENDENT SUBQUERY Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using where; Using index
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+(SELECT City.Name, Country.Code
+FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000))
+AND Language IN ('English','Spanish');
+count(*)
+88
+Q2.3m:
+MATERIALIZATION with the PARTIAL_MATCH_MERGE strategy, because the HAVING
+clause prevents the use of the index on City(Name), and in practice reduces
+radically the size of the temp table.
+EXPLAIN
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+(SELECT City.Name, Country.Code
+FROM City LEFT JOIN Country ON (Country = Code)
+HAVING City.Name LIKE "Santa%");
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY CountryLanguage index NULL PRIMARY 33 NULL 984 Using where; Using index
+2 SUBQUERY City ALL NULL NULL NULL NULL 4080
+2 SUBQUERY Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using index
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+(SELECT City.Name, Country.Code
+FROM City LEFT JOIN Country ON (Country = Code)
+HAVING City.Name LIKE "Santa%");
+count(*)
+984
+
+3. Subqueries with GROUP BY, HAVING, and aggregate functions
+
+Q3.1:
+Languages that are spoken in countries with 10 or 11 languages
+MATERIALIZATION is about 100 times faster than IN-EXISTS.
+EXPLAIN
+select count(*)
+from CountryLanguage
+where
+(Country, 10) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+WHERE Code = Country GROUP BY Code)
+OR
+(Country, 11) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+WHERE Code = Country GROUP BY Code)
+order by Country;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY CountryLanguage index NULL PRIMARY 33 NULL 984 Using where; Using index
+3 SUBQUERY CountryLanguage index PRIMARY PRIMARY 33 NULL 984 Using index; Using temporary
+3 SUBQUERY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using index
+2 SUBQUERY CountryLanguage index PRIMARY PRIMARY 33 NULL 984 Using index; Using temporary
+2 SUBQUERY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using index
+select count(*)
+from CountryLanguage
+where
+(Country, 10) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+WHERE Code = Country GROUP BY Code)
+OR
+(Country, 11) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+WHERE Code = Country GROUP BY Code)
+order by Country;
+count(*)
+102
+
+Q3.2:
+Countries whose capital is a city name that names more than one
+cities.
+MATERIALIZATION because the cost of single subquery execution is
+close to that of materializing the subquery.
+EXPLAIN
+select * from Country, City
+where capital = id and
+(City.name in (SELECT name FROM City
+GROUP BY name HAVING Count(*) > 2) OR
+capital is null);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country ALL NULL NULL NULL NULL 239 Using where
+1 PRIMARY City eq_ref PRIMARY PRIMARY 4 world.Country.Capital 1 Using where
+2 SUBQUERY City index NULL CityName 35 NULL 4080 Using index
+select * from Country, City
+where capital = id and
+(City.name in (SELECT name FROM City
+GROUP BY name HAVING Count(*) > 2) OR
+capital is null);
+Code Name SurfaceArea Population Capital ID Name Country population
+BMU Bermuda 53.00 65000 191 191 Hamilton BMU 1200
+BOL Bolivia 1098581.00 8329000 194 194 La Paz BOL 758141
+CRI Costa Rica 51100.00 4023000 584 584 San José CRI 339131
+HKG Hong Kong 1075.00 6782000 937 937 Victoria HKG 1312637
+SYC Seychelles 455.00 77000 3206 3206 Victoria SYC 41000
+
+Q3.3: MATERIALIZATION is 25 times faster than IN-EXISTS
+EXPLAIN
+SELECT Name
+FROM Country
+WHERE Country.Code NOT IN
+(SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY Country ALL NULL NULL NULL NULL 239 Using where
+2 SUBQUERY City ALL NULL NULL NULL NULL 4080 Using temporary
+SELECT Name
+FROM Country
+WHERE Country.Code NOT IN
+(SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1);
+Name
+Antigua and Barbuda
+Costa Rica
+Montserrat
+Norfolk Island
+Seychelles
+Antarctica
+Bouvet Island
+British Indian Ocean Territory
+South Georgia and the South Sandwich Islands
+Heard Island and McDonald Islands
+French Southern territories
+United States Minor Outlying Islands
+
+4. Subqueries in the SELECT and HAVING clauses
+
+Q4.1m:
+Capital information about very big cities
+MATERIALIZATION
+EXPLAIN
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY City range Population Population 5 NULL 4 Using index condition; Rowid-ordered scan
+2 SUBQUERY Country ALL NULL NULL NULL NULL 239 Using where
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+Name is_capital
+Mumbai (Bombay) 0
+Q4.1e:
+IN-TO-EXISTS after adding an index to make the subquery re-execution
+efficient.
+create index CountryCapital on Country(capital);
+EXPLAIN
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY City range Population Population 5 NULL 4 Using index condition; Rowid-ordered scan
+2 DEPENDENT SUBQUERY Country index_subquery CountryCapital CountryCapital 5 func 2 Using index; Using where
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+Name is_capital
+Mumbai (Bombay) 0
+drop index CountryCapital on Country;
+
+Q4.2:
+MATERIALIZATION
+EXPLAIN
+SELECT City.Name, City.Population
+FROM City JOIN Country ON City.Country = Country.Code
+GROUP BY City.Name
+HAVING City.Name IN (select Name from Country where population < 1000000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY City ALL Country NULL NULL NULL 4080 Using temporary; Using filesort
+1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using index
+2 SUBQUERY Country ALL Name NULL NULL NULL 239 Using where
+SELECT City.Name, City.Population
+FROM City JOIN Country ON City.Country = Country.Code
+GROUP BY City.Name
+HAVING City.Name IN (select Name from Country where population < 1000000);
+Name Population
+Djibouti 383000
+Gibraltar 27025
+Macao 437500
+San Marino 2294
+
+5. Subqueries with UNION
+
+Q5.1:
+EXPLAIN
+SELECT * from City where (Name, 91) in
+(SELECT Name, round(Population/1000)
+FROM City
+WHERE Country = "IND" AND Population > 2500000
+UNION
+SELECT Name, round(Population/1000)
+FROM City
+WHERE Country = "IND" AND Population < 100000);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY City ALL NULL NULL NULL NULL 4080 Using where
+2 DEPENDENT SUBQUERY City ref Population,Country,CityName CityName 35 func 1 Using where
+3 DEPENDENT UNION City ref Population,Country,CityName CityName 35 func 1 Using where
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-a2
-2 - 01
-2 - 02
-2 - 03
-
-explain
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 ref it2i2 it2i2 8 const 1 Using index condition
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-a1
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i2,it2i3 it2i4 16 func,func 1 Using index; Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-a1 a2
-1 - 01 2 - 01
-1 - 02 2 - 02
-1 - 03 2 - 03
-
-/* C. Subqueries in the WHERE clause with GROUP BY. */
-explain
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index it2i4,it2i1,it2i3 it2i1 8 NULL 1 Using where; Using index
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 16 NULL 1 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 16 NULL 1 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-1 - 03 2 - 03 3 - 03 3
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index NULL it2i4 24 NULL 1 Using index
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 index NULL it2i4 24 NULL 1 Using where; Using index
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-a1 a2 a3 a4
-
-explain
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY t2 range it2i4,it2i1,it2i3 it2i4 24 NULL 2 Using where; Using index for group-by
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-/*
-D. Subqueries for which materialization is not possible, and the
-optimizer reverts to in-to-exists.
-*/
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i3 it2_1024i3 9 func 1 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i2,it2_1024i3 it2_1024i1 9 func 2 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-1 - 03x 2 - 03x
-
-
-/* E. Edge cases. */
-
-/* E.1 Both materialization and in_to_exists cannot be off. */
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off,in_to_exists=off';
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-ERROR HY000: At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'.
-set @@optimizer_switch = @save_optimizer_switch;
-/* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i3 it2i1 8 const 5 Using index; Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-'1 - 03' in (select b1 from t2 where b1 > '0')
-1
-/* E.3 Subqueries without tables. */
-explain
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-Warnings:
-Note 1249 Select 2 was reduced during optimization
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-a1
-1 - 02
-1 - 03
-/* E.4 optimize_cond detects FALSE where/having clause. */
-explain
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-1 - 03
-1 - 04
-1 - 05
-1 - 06
-1 - 07
-/* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
-TODO this test produces wrong result due to missing logic to handle the case
-when JOIN::optimize detects an empty subquery result.
-explain
-select a1 from t1 where a1 in (select max(b1) from t2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-select a1 from t1 where a1 in (select max(b1) from t2);
-a1
-1 - 03
-
-explain
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 8 Using where
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-a1
-/* E.6 make_join_select detects impossible WHERE. *
-TODO
-/* E.7 constant optimization detects "no matching row in const table". */
-TODO
-/* E.8 Impossible WHERE noticed after reading const tables. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-'1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0')
-0
-
-/* F. UPDATE/DELETE with subqueries. */
-
-TODO
-
-call set_all_columns_nullable();
-/******************************************************************************
-3. Materialization is ON, in-to-exists is OFF, in-to-exists is cheaper.
-******************************************************************************/
-set @@optimizer_switch='materialization=on,in_to_exists=off';
-call delete_materialization_data();
-call make_t1_indexes();
-/* 3.1 non-indexed table access */
-call remove_t2_indexes();
-
-/* A. Subqueries in the SELECT clause. */
-explain
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-a1 a1 in (select b1 from t2 where b1 > '0')
-1 - 00 0
-1 - 01 1
-1 - 02 1
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 18 NULL 3 Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 18 NULL 3 Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-
-/*
-B. "Natural" examples of subqueries without grouping that
-cannot be flattened into semijoin.
-*/
-explain
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 18 NULL 3 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 18 NULL 3 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-a1 a2
-1 - 00 2 - 00
-1 - 01 2 - 01
-1 - 02 2 - 02
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i2 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-3 DEPENDENT UNION t3 ALL NULL NULL NULL NULL 5 Using where
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-a2
-2 - 01
-2 - 02
-
-explain
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref it1i1,it1i3 it1i1 9 const 1 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-a1
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 18 NULL 3 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-a1 a2
-1 - 01 2 - 01
-1 - 02 2 - 02
-
-/* C. Subqueries in the WHERE clause with GROUP BY. */
-explain
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-a1 a2 a3 a4
-
-explain
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-/*
-D. Subqueries for which materialization is not possible, and the
-optimizer reverts to in-to-exists.
-*/
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 ALL NULL NULL NULL NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-
-
-/* E. Edge cases. */
-
-/* E.1 Both materialization and in_to_exists cannot be off. */
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off,in_to_exists=off';
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-ERROR HY000: At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'.
-set @@optimizer_switch = @save_optimizer_switch;
-/* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-'1 - 03' in (select b1 from t2 where b1 > '0')
-1
-/* E.3 Subqueries without tables. */
-explain
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i1,it1i2,it1i3 it1i3 18 NULL 3 Using where; Using index
-Warnings:
-Note 1249 Select 2 was reduced during optimization
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-a1
-1 - 02
-/* E.4 optimize_cond detects FALSE where/having clause. */
-explain
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 18 NULL 3 Using where; Using index
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-/* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
-TODO this test produces wrong result due to missing logic to handle the case
-when JOIN::optimize detects an empty subquery result.
-explain
-select a1 from t1 where a1 in (select max(b1) from t2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5
-select a1 from t1 where a1 in (select max(b1) from t2);
-a1
-
-explain
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-a1
-/* E.6 make_join_select detects impossible WHERE. *
-TODO
-/* E.7 constant optimization detects "no matching row in const table". */
-TODO
-/* E.8 Impossible WHERE noticed after reading const tables. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-'1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0')
-0
-
-/* F. UPDATE/DELETE with subqueries. */
-
-TODO
-
-/* 3.2 indexed table access, nullabale columns. */
-call make_t2_indexes();
-
-/* A. Subqueries in the SELECT clause. */
-explain
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using index
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i1 9 NULL 5 Using where; Using index
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-a1 a1 in (select b1 from t2 where b1 > '0')
-1 - 00 0
-1 - 01 1
-1 - 02 1
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 18 NULL 3 Using index
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 18 NULL 5 Using where; Using index
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 18 NULL 3 Using index
-2 SUBQUERY t2 range it2i4,it2i1,it2i3 it2i3 9 NULL 4 Using where; Using index
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-
-/*
-B. "Natural" examples of subqueries without grouping that
-cannot be flattened into semijoin.
-*/
-explain
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 18 NULL 3 Using where; Using index
-2 SUBQUERY t2 index NULL it2i2 9 NULL 5 Using index
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 18 NULL 3 Using where; Using index
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 18 NULL 5 Using where; Using index
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-a1 a2
-1 - 00 2 - 00
-1 - 01 2 - 01
-1 - 02 2 - 02
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i2 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ref it2i2 it2i2 9 func 2 Using index
-3 DEPENDENT UNION t3 index NULL it2i4 27 NULL 5 Using where; Using index
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-a2
-2 - 01
-2 - 02
-
-explain
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref it1i1,it1i3 it1i1 9 const 1 Using where; Using index
-2 SUBQUERY t2 ref it2i2 it2i2 9 const 1 Using index condition
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-a1
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 18 NULL 3 Using where; Using index
-2 SUBQUERY t2 index NULL it2i4 27 NULL 5 Using index
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-a1 a2
-1 - 01 2 - 01
-1 - 02 2 - 02
-
-/* C. Subqueries in the WHERE clause with GROUP BY. */
-explain
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i1 9 NULL 5 Using where; Using index
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 18 NULL 5 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 18 NULL 5 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 range NULL it2i4 27 NULL 6 Using index for group-by
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 range NULL it2i4 27 NULL 6 Using where; Using index for group-by
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-a1 a2 a3 a4
-
-explain
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 range it2i4,it2i1,it2i3 it2i4 27 NULL 2 Using where; Using index for group-by
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-/*
-D. Subqueries for which materialization is not possible, and the
-optimizer reverts to in-to-exists.
-*/
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i3 it2_1024i3 9 func 1 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i2,it2_1024i3 it2_1024i1 9 func 2 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-
-
-/* E. Edge cases. */
-
-/* E.1 Both materialization and in_to_exists cannot be off. */
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off,in_to_exists=off';
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-ERROR HY000: At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'.
-set @@optimizer_switch = @save_optimizer_switch;
-/* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i3 it2i1 9 const 2 Using index; Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-'1 - 03' in (select b1 from t2 where b1 > '0')
-1
-/* E.3 Subqueries without tables. */
-explain
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i1,it1i2,it1i3 it1i3 18 NULL 3 Using where; Using index
-Warnings:
-Note 1249 Select 2 was reduced during optimization
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-a1
-1 - 02
-/* E.4 optimize_cond detects FALSE where/having clause. */
-explain
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 18 NULL 3 Using where; Using index
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-/* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
-TODO this test produces wrong result due to missing logic to handle the case
-when JOIN::optimize detects an empty subquery result.
-explain
-select a1 from t1 where a1 in (select max(b1) from t2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-select a1 from t1 where a1 in (select max(b1) from t2);
-a1
-
-explain
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 9 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-a1
-/* E.6 make_join_select detects impossible WHERE. *
-TODO
-/* E.7 constant optimization detects "no matching row in const table". */
-TODO
-/* E.8 Impossible WHERE noticed after reading const tables. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-'1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0')
-0
-
-/* F. UPDATE/DELETE with subqueries. */
-
-TODO
-
-/* 3.3 indexed table access, non-nullabale columns. */
-call set_all_columns_not_null();
-
-/* A. Subqueries in the SELECT clause. */
-explain
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 8 NULL 3 Using index
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i1 8 NULL 5 Using where; Using index
-select a1, a1 in (select b1 from t2 where b1 > '0') from t1;
-a1 a1 in (select b1 from t2 where b1 > '0')
-1 - 00 0
-1 - 01 1
-1 - 02 1
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 16 NULL 3 Using index
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 16 NULL 5 Using where; Using index
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-
-explain
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 16 NULL 3 Using index
-2 SUBQUERY t2 range it2i4,it2i1,it2i3 it2i3 8 NULL 4 Using where; Using index
-select a1, a2, (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9') from t1;
-a1 a2 (a1, a2) in (select b1, b2 from t2 where b1 > '0' and b1 < '9')
-1 - 00 2 - 00 0
-1 - 01 2 - 01 1
-1 - 02 2 - 02 1
-
-/*
-B. "Natural" examples of subqueries without grouping that
-cannot be flattened into semijoin.
-*/
-explain
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 16 NULL 3 Using where; Using index
-2 SUBQUERY t2 index NULL it2i2 8 NULL 5 Using index
-select a1 from t1 where a1 in (select b2 from t2) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 16 NULL 3 Using where; Using index
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 16 NULL 5 Using where; Using index
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0') or a2 < '9';
-a1 a2
-1 - 00 2 - 00
-1 - 01 2 - 01
-1 - 02 2 - 02
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i2 8 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY t2 ref it2i2 it2i2 8 func 2 Using index
-3 DEPENDENT UNION t3 index NULL it2i4 24 NULL 5 Using where; Using index
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a2 from t1 where a2 in (select b2 from t2 UNION select b3 from t2 as t3);
-a2
-2 - 01
-2 - 02
-
-explain
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref it1i1,it1i3 it1i1 8 const 1 Using where; Using index
-2 SUBQUERY t2 ref it2i2 it2i2 8 const 1 Using index condition
-select a1 from t1 where a1 = '1 - 02' and a1 in (select max(b1) from t2 where b2 = '2 - 02');
-a1
-1 - 02
-
-explain
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i3 16 NULL 3 Using where; Using index
-2 SUBQUERY t2 index NULL it2i4 24 NULL 5 Using index
-select a1, a2 from t1 where (a1, a2) in (select b1, b2 from t2 order by b3);
-a1 a2
-1 - 01 2 - 01
-1 - 02 2 - 02
-
-/* C. Subqueries in the WHERE clause with GROUP BY. */
-explain
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i1 8 NULL 5 Using where; Using index
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 16 NULL 5 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 index it2i4,it2i1,it2i3 it2i3 16 NULL 5 Using where; Using index
-select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2 having b2 < '2 - 04');
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-1 - 02 2 - 02 3 - 02 2
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 range NULL it2i4 24 NULL 6 Using index for group-by
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 group by b1, b2, b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-explain
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 range NULL it2i4 24 NULL 6 Using where; Using index for group-by
-select * from t1 where (a1, a2, a3) in (select b1, b2, b3 from t2 where b3 = '3 - 02' group by b1, b2);
-a1 a2 a3 a4
-
-explain
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2 range it2i4,it2i1,it2i3 it2i4 24 NULL 2 Using where; Using index for group-by
-select * from t1 where (a1,a2,a3) in (select b1,b2,b3 from t2 where b1 = '1 - 01' group by b1,b2,b3);
-a1 a2 a3 a4
-1 - 01 2 - 01 3 - 01 1
-
-/*
-D. Subqueries for which materialization is not possible, and the
-optimizer reverts to in-to-exists.
-*/
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i3 it2_1024i3 9 func 1 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select b1 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 index_subquery it2_1024i1,it2_1024i2,it2_1024i3 it2_1024i1 9 func 2 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select b1, b2 from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-
-explain
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-explain
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_1024 ALL it1_1024i2 NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2_1024 range it2_1024i1,it2_1024i3 it2_1024i1 9 NULL 4 Using where
-select left(a1,7), left(a2,7) from t1_1024 where (a1,a2) in (select substring(b1,1,1024), substring(b2,1,1024) from t2_1024 where b1 > '0') or a2 < '9';
-left(a1,7) left(a2,7)
-1 - 00x 2 - 00x
-1 - 01x 2 - 01x
-
-
-/* E. Edge cases. */
-
-/* E.1 Both materialization and in_to_exists cannot be off. */
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off,in_to_exists=off';
-select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
-ERROR HY000: At least one of the 'in_to_exists' or 'materialization' optimizer_switch flags must be 'on'.
-set @@optimizer_switch = @save_optimizer_switch;
-/* E.2 Outer query without tables, always uses IN-TO-EXISTS. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY t2 index_subquery it2i4,it2i1,it2i3 it2i1 8 const 5 Using index; Using where
-select '1 - 03' in (select b1 from t2 where b1 > '0');
-'1 - 03' in (select b1 from t2 where b1 > '0')
-1
-/* E.3 Subqueries without tables. */
-explain
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i1,it1i2,it1i3 it1i3 16 NULL 3 Using where; Using index
-Warnings:
-Note 1249 Select 2 was reduced during optimization
-select a1 from t1 where a1 in (select '1 - 03') or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-UNION subqueries are currently limited to only use IN-TO-EXISTS.
-explain
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 8 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
-3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL No tables used
-NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
-select a1 from t1 where a1 in (select '1 - 03' UNION select '1 - 02');
-a1
-1 - 02
-/* E.4 optimize_cond detects FALSE where/having clause. */
-explain
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index it1i2 it1i3 16 NULL 3 Using where; Using index
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
-select a1 from t1 where a1 in (select b1 from t2 where b1 = b2 and b2 = '1 - 03' and b1 = '1 - 02' ) or a2 < '9';
-a1
-1 - 00
-1 - 01
-1 - 02
-/* E.5 opt_sum_query detects no matching min/max row or substitutes MIN/MAX with a const. */
-TODO this test produces wrong result due to missing logic to handle the case
-when JOIN::optimize detects an empty subquery result.
-explain
-select a1 from t1 where a1 in (select max(b1) from t2);
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 8 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
-select a1 from t1 where a1 in (select max(b1) from t2);
-a1
-
-explain
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index NULL it1i1 8 NULL 3 Using where; Using index
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No matching min/max row
-select a1 from t1 where a1 in (select max(b1) from t2 where b1 = '7 - 02');
-a1
-/* E.6 make_join_select detects impossible WHERE. *
-TODO
-/* E.7 constant optimization detects "no matching row in const table". */
-TODO
-/* E.8 Impossible WHERE noticed after reading const tables. */
-explain
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
-2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-select '1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0');
-'1 - 03' in (select b1 from t2 where b1 > '0' and b1 < '0')
-0
-
-/* F. UPDATE/DELETE with subqueries. */
-
-TODO
-
-call set_all_columns_nullable();
-drop procedure make_t1_indexes;
-drop procedure make_t2_indexes;
-drop procedure remove_t1_indexes;
-drop procedure remove_t2_indexes;
-drop procedure add_materialization_data;
-drop procedure delete_materialization_data;
-drop procedure set_all_columns_not_null;
-drop procedure set_all_columns_nullable;
-drop table t1, t2, t1_1024, t2_1024;
+SELECT * from City where (Name, 91) in
+(SELECT Name, round(Population/1000)
+FROM City
+WHERE Country = "IND" AND Population > 2500000
+UNION
+SELECT Name, round(Population/1000)
+FROM City
+WHERE Country = "IND" AND Population < 100000);
+ID Name Country population
+1359 Hassan IND 90803
+1360 Ambala Sadar IND 90712
+1361 Baidyabati IND 90601
+set @@optimizer_switch='default';
+drop database world;
+
+
+TEST GROUP 2:
+Tests of various combinations of optimizer switches, types of queries,
+available indexes, column nullability, constness of tables/predicates.
+=====================================================================
+set optimizer_switch=@subselect_mat_cost;
diff --git a/mysql-test/r/subselect_mat_cost_bugs.result b/mysql-test/r/subselect_mat_cost_bugs.result
index 919a6c6d38d..287fae523fe 100644
--- a/mysql-test/r/subselect_mat_cost_bugs.result
+++ b/mysql-test/r/subselect_mat_cost_bugs.result
@@ -64,6 +64,12 @@ KEY c3 (c3,c2));
INSERT INTO t1 VALUES (10,7,8,'v','v');
INSERT INTO t1 VALUES (11,1,9,'r','r');
INSERT INTO t1 VALUES (12,5,9,'a','a');
+INSERT INTO t1 VALUES (13,7,18,'v','v');
+INSERT INTO t1 VALUES (14,1,19,'r','r');
+INSERT INTO t1 VALUES (15,5,29,'a','a');
+INSERT INTO t1 VALUES (17,7,38,'v','v');
+INSERT INTO t1 VALUES (18,1,39,'r','r');
+INSERT INTO t1 VALUES (19,5,49,'a','a');
create table t1a like t1;
insert into t1a select * from t1;
create table t1b like t1;
@@ -88,13 +94,13 @@ FROM (t1b JOIN t2 ON t2.c3 = t1b.c4) LEFT JOIN
t1a ON (t1a.c2 = t1b.pk AND 2)
WHERE t1.pk) ;
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
-2 DEPENDENT SUBQUERY t2 index c3 c3 9 NULL 2 100.00 Using index
-2 DEPENDENT SUBQUERY t1b ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
-2 DEPENDENT SUBQUERY t1a ref c2 c2 5 test.t1b.pk 2 100.00 Using where
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 100.00 Using where
+2 DEPENDENT SUBQUERY t1b ALL NULL NULL NULL NULL 9 100.00
+2 DEPENDENT SUBQUERY t1a ref c2 c2 5 test.t1b.pk 1 100.00 Using where
+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` and (<cache>(`test`.`t1`.`c1`) = `test`.`t1a`.`c1`) and (`test`.`t1b`.`c4` = `test`.`t2`.`c3`)))))
+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`)))))
SELECT pk
FROM t1
WHERE c1 IN
@@ -156,13 +162,15 @@ WHERE (SELECT distinct SUM(distinct f3 ) FROM t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
3 SUBQUERY t1 index NULL f3 5 NULL 2 Using index
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
insert into t2 values (1),(2);
EXPLAIN
SELECT * FROM (SELECT * FROM t2) AS a2
WHERE (SELECT distinct SUM(distinct f3 ) FROM t1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
3 SUBQUERY t1 index NULL f3 5 NULL 2 Using index
+2 DERIVED t2 ALL NULL NULL NULL NULL 2
drop table t1,t2;
#
# LP BUG#715027 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed
@@ -181,10 +189,11 @@ WHERE t1.f1 AND alias2.f10
)
ORDER BY field1 ;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using filesort
-1 PRIMARY alias1 eq_ref PRIMARY PRIMARY 4 test.t2.f3 1 Using index
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 Using where; Using filesort
+1 PRIMARY alias1 eq_ref PRIMARY PRIMARY 4 alias2.f3 1 Using index
3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2
-3 DEPENDENT SUBQUERY t1 index NULL PRIMARY 4 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
+3 DEPENDENT SUBQUERY t1 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
+2 DERIVED t2 ALL NULL NULL NULL NULL 2
SELECT alias2.f2 AS field1
FROM t1 AS alias1 JOIN ( SELECT * FROM t2 ) AS alias2 ON alias2.f3 = alias1.f1
WHERE (
@@ -295,3 +304,83 @@ id select_type table type possible_keys key key_len ref rows Extra
select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or c1 > 7;
c1
drop table t1, t2;
+#
+# LP BUG#800679: Assertion `outer_join->table_count > 0' failed in
+# JOIN::choose_subquery_plan() with materialization=on,semijoin=off
+#
+CREATE TABLE t1 ( f1 int);
+insert into t1 values (1),(2);
+CREATE TABLE t2 ( f1 int);
+insert into t2 values (1),(2);
+SET @@optimizer_switch='materialization=on,semijoin=off';
+EXPLAIN
+SELECT * FROM t1
+WHERE (f1) IN (SELECT f1 FROM t2)
+LIMIT 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1
+WHERE (f1) IN (SELECT f1 FROM t2)
+LIMIT 0;
+f1
+set @@optimizer_switch='default';
+drop table t1, t2;
+#
+# LP BUG#834492: Crash in fix_semijoin_strategies_for_picked_join_order
+# with nested subqueries and LooseScan=ON
+#
+CREATE TABLE t3 (b int) ;
+INSERT INTO t3 VALUES (0),(0);
+CREATE TABLE t4 (a int, b int, c int, d int, PRIMARY KEY (a)) ;
+INSERT INTO t4 VALUES (28,0,0,0),(29,3,0,0);
+CREATE TABLE t5 (a int, b int, c int, d int, KEY (c,b)) ;
+INSERT INTO t5 VALUES (28,0,0,0),(29,3,0,0);
+SET @@optimizer_switch='semijoin=ON,loosescan=ON,firstmatch=OFF,materialization=OFF';
+EXPLAIN SELECT *
+FROM t3
+WHERE t3.b > ALL (
+SELECT c
+FROM t4
+WHERE t4.a >= t3.b
+AND a = SOME (SELECT b FROM t5));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t5 index c c 10 NULL 2 Using where; Using index; LooseScan
+2 DEPENDENT SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t5.b 1 Using where
+SELECT *
+FROM t3
+WHERE t3.b > ALL (
+SELECT c
+FROM t4
+WHERE t4.a >= t3.b
+AND a = SOME (SELECT b FROM t5));
+b
+0
+0
+set @@optimizer_switch='default';
+drop table t3, t4, t5;
+#
+# LP BUG#858038 The result of a query with NOT IN subquery depends on the state of the optimizer switch
+#
+create table t1 (c1 char(2) not null, c2 char(2));
+create table t2 (c3 char(2), c4 char(2));
+insert into t1 values ('a1', 'b1');
+insert into t1 values ('a2', 'b2');
+insert into t2 values ('x1', 'y1');
+insert into t2 values ('a2', null);
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=off,partial_match_table_scan=on';
+explain select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+c1 c2
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+explain select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+c1 c2
+drop table t1, t2;
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
index f9a4a4373c2..b480b274c48 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -2,10 +2,13 @@ select @@optimizer_switch like '%materialization=on%';
@@optimizer_switch like '%materialization=on%'
0
set optimizer_switch='materialization=off';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
drop view if exists v2;
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+set @subselect_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
+"semijoin=on,firstmatch=on,loosescan=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
select (select 2);
(select 2)
2
@@ -206,10 +209,11 @@ select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
(select * from t2 where a>1) as tt;
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 <derived3> ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
Warnings:
-Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a` > 1)
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
a
2
@@ -230,7 +234,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t4.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t4`.`b` AS `b`,(select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+Note 1003 select `test`.`t4`.`b` AS `b`,<expr_cache><`test`.`t4`.`a`>((select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`)) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
select * from t3 where exists (select * from t2 where t2.b=t3.a);
a
7
@@ -276,7 +280,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2);
a
7
@@ -368,12 +372,12 @@ INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where; Using index
4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
-2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where
3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
Warnings:
-Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
+Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
ERROR 21000: Operand should contain 1 column(s)
@@ -544,18 +548,24 @@ SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT
numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY t1 ref PRIMARY PRIMARY 3 const 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select 1 from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
ERROR 21000: Subquery returns more than 1 row
EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where multiple equal(1, `test`.`t1`.`numeropost`)
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using index
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select 3 AS `numreponse` from `test`.`t1` where ((3 = 3))
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
drop table t1;
CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1);
@@ -917,6 +927,131 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
drop table t1,t2,t3;
+# check correct NULL Processing for normal IN/ALL/ANY
+# and 2 ways of max/min optimization
+create table t1 (a int);
+insert into t1 values (1), (100), (NULL), (1000);
+create table t2 (a int not null);
+# subselect returns empty set (for NULL and non-NULL left part)
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 1
+100 1
+NULL 1
+1000 1
+select a from t1 where a in (select * from t2);
+a
+select a from t1 where a > any (select * from t2);
+a
+select a from t1 where a > all (select * from t2);
+a
+1
+100
+NULL
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+select a from t1 where a > any (select * from t2 group by a);
+a
+select a from t1 where a > all (select * from t2 group by a);
+a
+1
+100
+NULL
+1000
+insert into t2 values (1),(200);
+# sebselect returns non-empty set without NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 0
+NULL NULL
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 1
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+1000
+drop table t2;
+create table t2 (a int);
+insert into t2 values (1),(NULL),(200);
+# sebselect returns non-empty set with NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 NULL
+NULL NULL
+1000 NULL
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 NULL
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 NULL
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+drop table t1, t2;
create table t1 (a float);
select 10.5 IN (SELECT * from t1 LIMIT 1);
ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
@@ -1240,7 +1375,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using index condition
+1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using index condition
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
@@ -1346,7 +1481,7 @@ a
explain extended select * from t2 where t2.a in (select a from t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
-1 PRIMARY t1 ref a a 5 test.t2.a 100 100.00 Using index; FirstMatch(t2)
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using index; FirstMatch(t2)
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where (`test`.`t1`.`a` = `test`.`t2`.`a`)
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
@@ -1356,7 +1491,7 @@ a
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
-1 PRIMARY t1 ref a a 5 test.t2.a 100 100.00 Using where; Using index; FirstMatch(t2)
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
@@ -1367,7 +1502,7 @@ explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
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 11 100.00 Using index; FirstMatch(t2)
+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`))
insert into t1 values (3,31);
@@ -1383,7 +1518,7 @@ a
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
-1 PRIMARY t1 ref a a 5 test.t2.a 100 100.00 Using where; Using index; FirstMatch(t2)
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
Warnings:
Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
drop table t0, t1, t2, t3;
@@ -1420,7 +1555,7 @@ INSERT INTO t1 VALUES ('z','?');
select * from t1 where s1 > (select max(s2) from t1);
ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
select * from t1 where s1 > any (select max(s2) from t1);
-ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+ERROR HY000: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '<'
drop table t1;
create table t1(toid int,rd int);
create table t2(userid int,pmnew int,pmtotal int);
@@ -1496,7 +1631,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < 'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`)))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
drop table t1,t2;
-create table t2 (a int, b int);
+create table t2 (a int, b int not null);
create table t3 (a int);
insert into t3 values (6),(7),(3);
select * from t3 where a >= all (select b from t2);
@@ -1509,7 +1644,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2);
a
explain extended select * from t3 where a >= some (select b from t2);
@@ -1517,7 +1652,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
@@ -1528,7 +1663,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < <max>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select NULL from `test`.`t2` group by 1) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2 group by 1);
a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
@@ -1536,7 +1671,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= <min>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(<min>(select NULL from `test`.`t2` group by 1) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
@@ -1544,7 +1679,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
@@ -1552,7 +1687,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
select * from t3 where NULL >= some (select b from t2);
a
explain extended select * from t3 where NULL >= some (select b from t2);
@@ -1560,7 +1695,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
@@ -1568,7 +1703,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
a
@@ -1579,7 +1714,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= <cache>(`test`.`t3`.`a`))))
drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
@@ -1630,7 +1765,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION t1 system NULL NULL NULL NULL 1 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',('f' > <min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`))))
+Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',(<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`) < 'f')))
drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
@@ -2833,7 +2968,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
2 DEPENDENT SUBQUERY 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`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
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
@@ -2845,7 +2980,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
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; Using temporary
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
DROP TABLE t1,t2;
CREATE TABLE t1 (a char(5), b char(5));
INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
@@ -2961,7 +3096,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -2973,7 +3108,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -4034,7 +4169,7 @@ CREATE TABLE t1 (a int, b int, KEY (a));
INSERT INTO t1 VALUES (1,1),(2,1);
EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
+1 PRIMARY t1 ref a a 5 const 0 Using where; Using index
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
DROP TABLE t1;
CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
@@ -4807,7 +4942,6 @@ SELECT 1 FROM t1 GROUP BY
1
1
DROP TABLE t1;
-set @@optimizer_switch=@save_optimizer_switch;
#
# Bug #49512 : subquery with aggregate function crash
# subselect_single_select_engine::exec()
@@ -5109,6 +5243,167 @@ SELECT 1 as foo FROM t1 WHERE a < SOME
);
foo
DROP TABLE t1;
+CREATE TABLE t1 (a int(11), b varchar(1));
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+delete from t1;
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+drop table t1;
+#
+# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ;
+INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0);
+DROP TABLE IF EXISTS t3;
+Warnings:
+Note 1051 Unknown table 't3'
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ;
+r
+NULL
+5
+NULL
+5
+DROP TABLE t1, t2, t3;
+End of 5.2 tests
#
# BUG#779885: Crash in eliminate_item_equal with materialization=on in
# maria-5.3
@@ -5130,7 +5425,249 @@ ON t2.f10 = t3.f10
);
f1
DROP TABLE t1,t2,t3;
+#
+# BUG LP:813473: Wrong result with outer join + NOT IN subquery
+# This bug is a duplicate of Bug#11764086 whose test case is added below
+#
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
+create table t3 (d int, e int);
+insert into t3 values (2, 9), (3,10);
+EXPLAIN
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b , t1.c) NOT IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b, t1.c) NOT IN (SELECT * from t3);
+b c
+9 NULL
+9 NULL
+drop table t1, t2, t3;
End of 5.3 tests
+End of 5.5 tests.
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+#
+# Bug#11764086: Null left operand to NOT IN in WHERE clause
+# behaves differently than real NULL
+#
+CREATE TABLE parent (id int);
+INSERT INTO parent VALUES (1), (2);
+CREATE TABLE child (parent_id int, other int);
+INSERT INTO child VALUES (1,NULL);
+# Offending query (c.parent_id is NULL for null-complemented rows only)
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id NOT IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+);
+id parent_id
+1 1
+2 NULL
+# Some syntactic variations with IS FALSE and IS NOT TRUE
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS NOT TRUE;
+id parent_id
+1 1
+2 NULL
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS FALSE;
+id parent_id
+1 1
+2 NULL
+DROP TABLE parent, child;
+# End of test for bug#11764086.
+#
+# BUG#50257: Missing info in REF column of the EXPLAIN
+# lines for subselects
+#
+CREATE TABLE t1 (a INT, b INT, INDEX (a));
+INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+
+EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ref a a 5 const 1
+
+EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 SUBQUERY t1 ref a a 5 const 1 Using index
+
+DROP TABLE t1;
+#
+# Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET ||
+# BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0), (1);
+CREATE TABLE t2(
+b TEXT,
+c INT,
+PRIMARY KEY (b(1))
+);
+INSERT INTO t2 VALUES ('a', 2), ('b', 3);
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ORDER BY b
+);
+1
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+GROUP BY b
+);
+1
+DROP TABLE t1, t2;
+#
+# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS)
+#
+CREATE TABLE t1 (f1 varchar(1));
+INSERT INTO t1 VALUES ('v'),('s');
+CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key));
+INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'),
+('d'),('y'),('t'),('d'),('s');
+SELECT table1.f1, table2.f1_key
+FROM t1 AS table1, t2 AS table2
+WHERE EXISTS
+(
+SELECT DISTINCT f1_key
+FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
+f1 f1_key
+v j
+s j
+v v
+s v
+v c
+s c
+v m
+s m
+v d
+s d
+v d
+s d
+v y
+s y
+v t
+s t
+v d
+s d
+v s
+s s
+explain SELECT table1.f1, table2.f1_key
+FROM t1 AS table1, t2 AS table2
+WHERE EXISTS
+(
+SELECT DISTINCT f1_key
+FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY table1 ALL NULL NULL NULL NULL 2
+1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
+DROP TABLE t1,t2;
+#
+# LP bug #826279: assertion failure with GROUP BY a result of subquery
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0), (0);
+CREATE TABLE t2 (a int, b int, c int);
+INSERT INTO t2 VALUES (10,7,0), (0,7,0);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,7), (0,7);
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+7 NULL
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+7 NULL
+7 10
+DROP TABLE t1,t2,t3;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+set optimizer_switch=@subselect_tmp;
set optimizer_switch=default;
select @@optimizer_switch like '%materialization=on%';
@@optimizer_switch like '%materialization=on%'
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
index 493ab9dba59..ceb9ee40db8 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -1,8 +1,10 @@
-set optimizer_switch='materialization=off,semijoin=off';
+set @optimizer_switch_for_subselect_test='materialization=off,semijoin=off,subquery_cache=off,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
drop view if exists v2;
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+set @subselect_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
+"semijoin=on,firstmatch=on,loosescan=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
select (select 2);
(select 2)
2
@@ -54,7 +56,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having (<expr_cache><1>((select 1)) = 1)
+Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having ((select 1) = 1)
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
1
1
@@ -203,10 +205,11 @@ select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
(select * from t2 where a>1) as tt;
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 <derived3> ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
Warnings:
-Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a` > 1)
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
a
2
@@ -273,7 +276,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2);
a
7
@@ -317,7 +320,7 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
Note 1276 Field or reference 'test.t2.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select <expr_cache><`test`.`t2`.`a`>((select 2 from `test`.`t1` where (2 = `test`.`t2`.`a`) union select `test`.`t5`.`a` from `test`.`t5` where (`test`.`t5`.`a` = `test`.`t2`.`a`))) AS `(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a)`,`test`.`t2`.`a` AS `a` from `test`.`t2`
+Note 1003 select (select 2 from `test`.`t1` where (2 = `test`.`t2`.`a`) union select `test`.`t5`.`a` from `test`.`t5` where (`test`.`t5`.`a` = `test`.`t2`.`a`)) AS `(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a)`,`test`.`t2`.`a` AS `a` from `test`.`t2`
select (select a from t1 where t1.a=t2.a union all select a from t5 where t5.a=t2.a), a from t2;
ERROR 21000: Subquery returns more than 1 row
create table t6 (patient_uq int, clinic_uq int, index i1 (clinic_uq));
@@ -335,7 +338,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
Warnings:
Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where <expr_cache><`test`.`t6`.`clinic_uq`>(exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`)))
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`))
select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
ERROR 23000: Column 'a' in field list is ambiguous
drop table t1,t2,t3;
@@ -365,12 +368,12 @@ INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where; Using index
4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
-2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where
3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
Warnings:
-Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
+Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
ERROR 21000: Operand should contain 1 column(s)
@@ -541,18 +544,24 @@ SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT
numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY t1 ref PRIMARY PRIMARY 3 const 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select 1 from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
ERROR 21000: Subquery returns more than 1 row
EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where multiple equal(1, `test`.`t1`.`numeropost`)
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using index
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select 3 AS `numreponse` from `test`.`t1` where ((3 = 3))
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
drop table t1;
CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1);
@@ -749,7 +758,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <expr_cache><`test`.`t2`.`id`>(<in_optimizer>(`test`.`t2`.`id`,<exists>(select 1 having (<cache>(`test`.`t2`.`id`) = <ref_null_helper>(1)) union select 3 having (<cache>(`test`.`t2`.`id`) = <ref_null_helper>(3)))))
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`id`,<exists>(select 1 having (<cache>(`test`.`t2`.`id`) = <ref_null_helper>(1)) union select 3 having (<cache>(`test`.`t2`.`id`) = <ref_null_helper>(3))))
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
id
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
@@ -897,7 +906,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
2 DEPENDENT SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL having <is_not_null_test>(`test`.`t2`.`a`))))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
+Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL having <is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
CREATE TABLE t3 (a int(11) default '0');
INSERT INTO t3 VALUES (1),(2),(3);
SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
@@ -912,8 +921,133 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using where; Using index
2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
+Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
drop table t1,t2,t3;
+# check correct NULL Processing for normal IN/ALL/ANY
+# and 2 ways of max/min optimization
+create table t1 (a int);
+insert into t1 values (1), (100), (NULL), (1000);
+create table t2 (a int not null);
+# subselect returns empty set (for NULL and non-NULL left part)
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 1
+100 1
+NULL 1
+1000 1
+select a from t1 where a in (select * from t2);
+a
+select a from t1 where a > any (select * from t2);
+a
+select a from t1 where a > all (select * from t2);
+a
+1
+100
+NULL
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+select a from t1 where a > any (select * from t2 group by a);
+a
+select a from t1 where a > all (select * from t2 group by a);
+a
+1
+100
+NULL
+1000
+insert into t2 values (1),(200);
+# sebselect returns non-empty set without NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 0
+NULL NULL
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 1
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+1000
+drop table t2;
+create table t2 (a int);
+insert into t2 values (1),(NULL),(200);
+# sebselect returns non-empty set with NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 NULL
+NULL NULL
+1000 NULL
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 NULL
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 NULL
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+drop table t1, t2;
create table t1 (a float);
select 10.5 IN (SELECT * from t1 LIMIT 1);
ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
@@ -1237,7 +1371,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using index condition
+1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using index condition
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
@@ -1302,7 +1436,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY))))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY)))
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
2
@@ -1312,7 +1446,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using where
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<primary_index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on PRIMARY where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))))
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
a
2
@@ -1323,7 +1457,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where
2 DEPENDENT SUBQUERY 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`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`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));
@@ -1345,7 +1479,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a))))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a)))
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
2
@@ -1355,7 +1489,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index; Using where
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))))
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
a
2
@@ -1366,7 +1500,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 ref a a 5 func 1001 100.00 Using index
2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join)
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))
insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
@@ -1382,7 +1516,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1001 100.00 Using index; Using where
Warnings:
-Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a where ((`test`.`t1`.`b` <> 30) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))))
drop table t0, t1, t2, t3;
create table t1 (a int, b int);
create table t2 (a int, b int);
@@ -1417,7 +1551,7 @@ INSERT INTO t1 VALUES ('z','?');
select * from t1 where s1 > (select max(s2) from t1);
ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
select * from t1 where s1 > any (select max(s2) from t1);
-ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+ERROR HY000: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '<'
drop table t1;
create table t1(toid int,rd int);
create table t2(userid int,pmnew int,pmtotal int);
@@ -1473,27 +1607,27 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
Warnings:
-Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`)))))))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
explain extended select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
Warnings:
-Note 1003 select `test`.`t1`.`s1` AS `s1`,<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`)))))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
+Note 1003 select `test`.`t1`.`s1` AS `s1`,<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
explain extended select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
Warnings:
-Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`)))))))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
Warnings:
-Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < 'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`)))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < 'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
drop table t1,t2;
-create table t2 (a int, b int);
+create table t2 (a int, b int not null);
create table t3 (a int);
insert into t3 values (6),(7),(3);
select * from t3 where a >= all (select b from t2);
@@ -1506,7 +1640,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2);
a
explain extended select * from t3 where a >= some (select b from t2);
@@ -1514,7 +1648,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
@@ -1525,7 +1659,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < <max>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select NULL from `test`.`t2` group by 1) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2 group by 1);
a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
@@ -1533,7 +1667,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= <min>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(<min>(select NULL from `test`.`t2` group by 1) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
@@ -1541,7 +1675,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
@@ -1549,7 +1683,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
select * from t3 where NULL >= some (select b from t2);
a
explain extended select * from t3 where NULL >= some (select b from t2);
@@ -1557,7 +1691,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
@@ -1565,7 +1699,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
a
@@ -1576,7 +1710,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= <cache>(`test`.`t3`.`a`))))
drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
@@ -1627,7 +1761,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION t1 system NULL NULL NULL NULL 1 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',('f' > <min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`))))
+Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',(<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`) < 'f')))
drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
@@ -1746,14 +1880,14 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 Using where
2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where
Warnings:
-Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<expr_cache><`test`.`t1`.`id`>(<in_optimizer>(`test`.`t1`.`id`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`id`) in t1 on PRIMARY where ((`test`.`t1`.`id` < 8) and (<cache>(`test`.`t1`.`id`) = `test`.`t1`.`id`))))))))
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<in_optimizer>(`test`.`t1`.`id`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`id`) in t1 on PRIMARY where ((`test`.`t1`.`id` < 8) and (<cache>(`test`.`t1`.`id`) = `test`.`t1`.`id`)))))))
explain extended select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY tt ALL NULL NULL NULL NULL 12 100.00 Using where
2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 100.00 Using where; Using index
Warnings:
Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(<expr_cache><`test`.`tt`.`id`>(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null)))))
+Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null))))
insert into t1 (id, text) values (1000, 'text1000'), (1001, 'text1001');
create table t2 (id int not null, text varchar(20) not null default '', primary key (id));
insert into t2 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text1'), (12, 'text2'), (13, 'text3'), (14, 'text4'), (15, 'text5'), (16, 'text6'), (17, 'text7'), (18, 'text8'), (19, 'text9'), (20, 'text10'),(21, 'text1'), (22, 'text2'), (23, 'text3'), (24, 'text4'), (25, 'text5'), (26, 'text6'), (27, 'text7'), (28, 'text8'), (29, 'text9'), (30, 'text10'), (31, 'text1'), (32, 'text2'), (33, 'text3'), (34, 'text4'), (35, 'text5'), (36, 'text6'), (37, 'text7'), (38, 'text8'), (39, 'text9'), (40, 'text10'), (41, 'text1'), (42, 'text2'), (43, 'text3'), (44, 'text4'), (45, 'text5'), (46, 'text6'), (47, 'text7'), (48, 'text8'), (49, 'text9'), (50, 'text10');
@@ -2289,7 +2423,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where <expr_cache><`test`.`up`.`a`>(exists(select 1 from `test`.`t1` where (`test`.`t1`.`a` = `test`.`up`.`a`)))
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where exists(select 1 from `test`.`t1` where (`test`.`t1`.`a` = `test`.`up`.`a`))
drop table t1;
CREATE TABLE t1 (t1_a int);
INSERT INTO t1 VALUES (1);
@@ -2830,19 +2964,19 @@ 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
2 DEPENDENT SUBQUERY 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`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
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 Using where
2 DEPENDENT SUBQUERY 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` where <expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = 'N') and (<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) and (<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`)))))
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = 'N') and (<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) and (<cache>(`test`.`t1`.`two`) = `test`.`t2`.`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
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; Using temporary
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
DROP TABLE t1,t2;
CREATE TABLE t1 (a char(5), b char(5));
INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
@@ -2958,7 +3092,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -2970,7 +3104,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -4031,7 +4165,7 @@ CREATE TABLE t1 (a int, b int, KEY (a));
INSERT INTO t1 VALUES (1,1),(2,1);
EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
+1 PRIMARY t1 ref a a 5 const 0 Using where; Using index
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
DROP TABLE t1;
CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
@@ -4325,13 +4459,13 @@ 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
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,<exists>(select 1 from `test`.`t1` group by `test`.`t1`.`a` having (1 = <ref_null_helper>(1)))))
+Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,<exists>(select 1 from `test`.`t1` group by `test`.`t1`.`a` having (1 = <ref_null_helper>(1))))
EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
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
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,<exists>(select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having (1 = <ref_null_helper>(1)))))
+Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,<exists>(select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having (1 = <ref_null_helper>(1))))
DROP TABLE t1;
#
# Bug#45061: Incorrectly market field caused wrong result.
@@ -4804,7 +4938,6 @@ SELECT 1 FROM t1 GROUP BY
1
1
DROP TABLE t1;
-set @@optimizer_switch=@save_optimizer_switch;
#
# Bug #49512 : subquery with aggregate function crash
# subselect_single_select_engine::exec()
@@ -5106,6 +5239,167 @@ SELECT 1 as foo FROM t1 WHERE a < SOME
);
foo
DROP TABLE t1;
+CREATE TABLE t1 (a int(11), b varchar(1));
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+delete from t1;
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+drop table t1;
+#
+# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ;
+INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0);
+DROP TABLE IF EXISTS t3;
+Warnings:
+Note 1051 Unknown table 't3'
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ;
+r
+NULL
+5
+NULL
+5
+DROP TABLE t1, t2, t3;
+End of 5.2 tests
#
# BUG#779885: Crash in eliminate_item_equal with materialization=on in
# maria-5.3
@@ -5127,5 +5421,247 @@ ON t2.f10 = t3.f10
);
f1
DROP TABLE t1,t2,t3;
+#
+# BUG LP:813473: Wrong result with outer join + NOT IN subquery
+# This bug is a duplicate of Bug#11764086 whose test case is added below
+#
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
+create table t3 (d int, e int);
+insert into t3 values (2, 9), (3,10);
+EXPLAIN
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b , t1.c) NOT IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b, t1.c) NOT IN (SELECT * from t3);
+b c
+9 NULL
+9 NULL
+drop table t1, t2, t3;
End of 5.3 tests
-set optimizer_switch=default;
+End of 5.5 tests.
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+#
+# Bug#11764086: Null left operand to NOT IN in WHERE clause
+# behaves differently than real NULL
+#
+CREATE TABLE parent (id int);
+INSERT INTO parent VALUES (1), (2);
+CREATE TABLE child (parent_id int, other int);
+INSERT INTO child VALUES (1,NULL);
+# Offending query (c.parent_id is NULL for null-complemented rows only)
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id NOT IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+);
+id parent_id
+1 1
+2 NULL
+# Some syntactic variations with IS FALSE and IS NOT TRUE
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS NOT TRUE;
+id parent_id
+1 1
+2 NULL
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS FALSE;
+id parent_id
+1 1
+2 NULL
+DROP TABLE parent, child;
+# End of test for bug#11764086.
+#
+# BUG#50257: Missing info in REF column of the EXPLAIN
+# lines for subselects
+#
+CREATE TABLE t1 (a INT, b INT, INDEX (a));
+INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+
+EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ref a a 5 const 1
+
+EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 SUBQUERY t1 ref a a 5 const 1 Using index
+
+DROP TABLE t1;
+#
+# Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET ||
+# BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0), (1);
+CREATE TABLE t2(
+b TEXT,
+c INT,
+PRIMARY KEY (b(1))
+);
+INSERT INTO t2 VALUES ('a', 2), ('b', 3);
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ORDER BY b
+);
+1
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+GROUP BY b
+);
+1
+DROP TABLE t1, t2;
+#
+# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS)
+#
+CREATE TABLE t1 (f1 varchar(1));
+INSERT INTO t1 VALUES ('v'),('s');
+CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key));
+INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'),
+('d'),('y'),('t'),('d'),('s');
+SELECT table1.f1, table2.f1_key
+FROM t1 AS table1, t2 AS table2
+WHERE EXISTS
+(
+SELECT DISTINCT f1_key
+FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
+f1 f1_key
+v j
+s j
+v v
+s v
+v c
+s c
+v m
+s m
+v d
+s d
+v d
+s d
+v y
+s y
+v t
+s t
+v d
+s d
+v s
+s s
+explain SELECT table1.f1, table2.f1_key
+FROM t1 AS table1, t2 AS table2
+WHERE EXISTS
+(
+SELECT DISTINCT f1_key
+FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY table1 ALL NULL NULL NULL NULL 2
+1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
+DROP TABLE t1,t2;
+#
+# LP bug #826279: assertion failure with GROUP BY a result of subquery
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0), (0);
+CREATE TABLE t2 (a int, b int, c int);
+INSERT INTO t2 VALUES (10,7,0), (0,7,0);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,7), (0,7);
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+7 NULL
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+7 NULL
+7 10
+DROP TABLE t1,t2,t3;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+set optimizer_switch=@subselect_tmp;
+set @optimizer_switch_for_subselect_test=null;
diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
new file mode 100644
index 00000000000..43d8e4e7ad3
--- /dev/null
+++ b/mysql-test/r/subselect_no_scache.result
@@ -0,0 +1,5673 @@
+select @@optimizer_switch like '%subquery_cache=on%';
+@@optimizer_switch like '%subquery_cache=on%'
+1
+set optimizer_switch='subquery_cache=off';
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
+drop view if exists v2;
+set @subselect_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
+"semijoin=on,firstmatch=on,loosescan=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+select (select 2);
+(select 2)
+2
+explain extended select (select 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select 2 AS `(select 2)`
+SELECT (SELECT 1) UNION SELECT (SELECT 2);
+(SELECT 1)
+1
+2
+explain extended SELECT (SELECT 1) UNION SELECT (SELECT 2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1249 Select 4 was reduced during optimization
+Note 1003 select 1 AS `(SELECT 1)` union select 2 AS `(SELECT 2)`
+SELECT (SELECT (SELECT 0 UNION SELECT 0));
+(SELECT (SELECT 0 UNION SELECT 0))
+0
+explain extended SELECT (SELECT (SELECT 0 UNION SELECT 0));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+4 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union3,4> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (select 0 union select 0) AS `(SELECT (SELECT 0 UNION SELECT 0))`
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b;
+ERROR 42S22: Reference 'b' not supported (forward reference in item list)
+SELECT (SELECT 1),MAX(1) FROM (SELECT 1) as a;
+(SELECT 1) MAX(1)
+1 1
+SELECT (SELECT a) as a;
+ERROR 42S22: Reference 'a' not supported (forward reference in item list)
+EXPLAIN EXTENDED SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1276 Field or reference 'b.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select 1 AS `1` from (select 1 AS `a`) `b` having ((select 1) = 1)
+SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
+1
+1
+SELECT (SELECT 1), a;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT 1 as a FROM (SELECT 1) as b HAVING (SELECT a)=1;
+a
+1
+SELECT 1 FROM (SELECT (SELECT a) b) c;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c ORDER BY id);
+id
+1
+SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT 1 IN (SELECT 1);
+1 IN (SELECT 1)
+1
+SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a));
+1
+1
+select (SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE(1));
+ERROR HY000: Incorrect usage of PROCEDURE and subquery
+SELECT 1 FROM (SELECT 1) a PROCEDURE ANALYSE((SELECT 1));
+ERROR HY000: Incorrect parameters to procedure 'ANALYSE'
+SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NULL;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT (SELECT 1) as a FROM (SELECT 1) b WHERE (SELECT a) IS NOT NULL;
+ERROR 42S22: Unknown column 'a' in 'field list'
+SELECT (SELECT 1,2,3) = ROW(1,2,3);
+(SELECT 1,2,3) = ROW(1,2,3)
+1
+SELECT (SELECT 1,2,3) = ROW(1,2,1);
+(SELECT 1,2,3) = ROW(1,2,1)
+0
+SELECT (SELECT 1,2,3) < ROW(1,2,1);
+(SELECT 1,2,3) < ROW(1,2,1)
+0
+SELECT (SELECT 1,2,3) > ROW(1,2,1);
+(SELECT 1,2,3) > ROW(1,2,1)
+1
+SELECT (SELECT 1,2,3) = ROW(1,2,NULL);
+(SELECT 1,2,3) = ROW(1,2,NULL)
+NULL
+SELECT ROW(1,2,3) = (SELECT 1,2,3);
+ROW(1,2,3) = (SELECT 1,2,3)
+1
+SELECT ROW(1,2,3) = (SELECT 1,2,1);
+ROW(1,2,3) = (SELECT 1,2,1)
+0
+SELECT ROW(1,2,3) < (SELECT 1,2,1);
+ROW(1,2,3) < (SELECT 1,2,1)
+0
+SELECT ROW(1,2,3) > (SELECT 1,2,1);
+ROW(1,2,3) > (SELECT 1,2,1)
+1
+SELECT ROW(1,2,3) = (SELECT 1,2,NULL);
+ROW(1,2,3) = (SELECT 1,2,NULL)
+NULL
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'a');
+(SELECT 1.5,2,'a') = ROW(1.5,2,'a')
+1
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,2,'b');
+(SELECT 1.5,2,'a') = ROW(1.5,2,'b')
+0
+SELECT (SELECT 1.5,2,'a') = ROW('1.5b',2,'b');
+(SELECT 1.5,2,'a') = ROW('1.5b',2,'b')
+0
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: '1.5b'
+SELECT (SELECT 'b',2,'a') = ROW(1.5,2,'a');
+(SELECT 'b',2,'a') = ROW(1.5,2,'a')
+0
+SELECT (SELECT 1.5,2,'a') = ROW(1.5,'2','a');
+(SELECT 1.5,2,'a') = ROW(1.5,'2','a')
+1
+SELECT (SELECT 1.5,'c','a') = ROW(1.5,2,'a');
+(SELECT 1.5,'c','a') = ROW(1.5,2,'a')
+0
+SELECT (SELECT * FROM (SELECT 'test' a,'test' b) a);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT 1 as a,(SELECT a+a) b,(SELECT b);
+a b (SELECT b)
+1 2 2
+create table t1 (a int);
+create table t2 (a int, b int);
+create table t3 (a int);
+create table t4 (a int not null, b int not null);
+insert into t1 values (2);
+insert into t2 values (1,7),(2,7);
+insert into t4 values (4,8),(3,8),(5,9);
+select (select a from t1 where t1.a = a1) as a2, (select b from t2 where t2.b=a2) as a1;
+ERROR 42S22: Reference 'a1' not supported (forward reference in item list)
+select (select a from t1 where t1.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a) a
+NULL 1
+2 2
+select (select a from t1 where t1.a=t2.b), a from t2;
+(select a from t1 where t1.a=t2.b) a
+NULL 1
+NULL 2
+select (select a from t1), a, (select 1 union select 2 limit 1) from t2;
+(select a from t1) a (select 1 union select 2 limit 1)
+2 1 1
+2 2 1
+select (select a from t3), a from t2;
+(select a from t3) a
+NULL 1
+NULL 2
+select * from t2 where t2.a=(select a from t1);
+a b
+2 7
+insert into t3 values (6),(7),(3);
+select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1);
+a b
+1 7
+2 7
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 order by a limit 2) limit 3;
+a b
+1 7
+2 7
+3 8
+(select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
+a b
+1 7
+2 7
+4 8
+3 8
+explain extended (select * from t2 where t2.b=(select a from t3 order by 1 desc limit 1)) union (select * from t4 where t4.b=(select max(t2.a)*4 from t2) order by a);
+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
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+3 UNION t4 ALL NULL NULL NULL NULL 3 100.00 Using where
+4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`)
+select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
+(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
+3 1
+7 2
+select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+(select t3.a from t3 where a<8 order by 1 desc limit 1) a
+7 2
+explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
+(select * from t2 where a>1) as tt;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
+Warnings:
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
+a
+2
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a > t1.a) order by 1 desc limit 1);
+a
+2
+select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3 where t3.a < t1.a) order by 1 desc limit 1);
+a
+select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
+b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
+8 7.5000
+8 4.5000
+9 7.5000
+explain extended select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t4 ALL NULL NULL NULL NULL 3 100.00
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t4.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select `test`.`t4`.`b` AS `b`,(select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+select * from t3 where exists (select * from t2 where t2.b=t3.a);
+a
+7
+select * from t3 where not exists (select * from t2 where t2.b=t3.a);
+a
+6
+3
+select * from t3 where a in (select b from t2);
+a
+7
+select * from t3 where a not in (select b from t2);
+a
+6
+3
+select * from t3 where a = some (select b from t2);
+a
+7
+select * from t3 where a <> any (select b from t2);
+a
+6
+3
+select * from t3 where a = all (select b from t2);
+a
+7
+select * from t3 where a <> all (select b from t2);
+a
+6
+3
+insert into t2 values (100, 5);
+select * from t3 where a < any (select b from t2);
+a
+6
+3
+select * from t3 where a < all (select b from t2);
+a
+3
+select * from t3 where a >= any (select b from t2);
+a
+6
+7
+explain extended select * from t3 where a >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= all (select b from t2);
+a
+7
+delete from t2 where a=100;
+select * from t3 where a in (select a,b from t2);
+ERROR 21000: Operand should contain 1 column(s)
+select * from t3 where a in (select * from t2);
+ERROR 21000: Operand should contain 1 column(s)
+insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9),(1,10);
+select b,max(a) as ma from t4 group by b having b < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+insert into t2 values (2,10);
+select b,max(a) as ma from t4 group by b having ma < (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+10 1
+delete from t2 where a=2 and b=10;
+select b,max(a) as ma from t4 group by b having b >= (select max(t2.a) from t2 where t2.b=t4.b);
+b ma
+7 12
+create table t5 (a int);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (5);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+insert into t5 values (2);
+select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) a
+NULL 1
+2 2
+explain extended select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2;
+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
+2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 DEPENDENT UNION t5 ALL NULL NULL NULL NULL 2 100.00 Using where
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1276 Field or reference 'test.t2.a' of SELECT #2 was resolved in SELECT #1
+Note 1276 Field or reference 'test.t2.a' of SELECT #3 was resolved in SELECT #1
+Note 1003 select (select 2 from `test`.`t1` where (2 = `test`.`t2`.`a`) union select `test`.`t5`.`a` from `test`.`t5` where (`test`.`t5`.`a` = `test`.`t2`.`a`)) AS `(select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a)`,`test`.`t2`.`a` AS `a` from `test`.`t2`
+select (select a from t1 where t1.a=t2.a union all select a from t5 where t5.a=t2.a), a from t2;
+ERROR 21000: Subquery returns more than 1 row
+create table t6 (patient_uq int, clinic_uq int, index i1 (clinic_uq));
+create table t7( uq int primary key, name char(25));
+insert into t7 values(1,"Oblastnaia bolnitsa"),(2,"Bolnitsa Krasnogo Kresta");
+insert into t6 values (1,1),(1,2),(2,2),(1,3);
+select * from t6 where exists (select * from t7 where uq = clinic_uq);
+patient_uq clinic_uq
+1 1
+1 2
+2 2
+explain extended select * from t6 where exists (select * from t7 where uq = clinic_uq);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t6 ALL NULL NULL NULL NULL 4 100.00 Using where
+2 DEPENDENT SUBQUERY t7 eq_ref PRIMARY PRIMARY 4 test.t6.clinic_uq 1 100.00 Using index
+Warnings:
+Note 1276 Field or reference 'test.t6.clinic_uq' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t6`.`patient_uq` AS `patient_uq`,`test`.`t6`.`clinic_uq` AS `clinic_uq` from `test`.`t6` where exists(select 1 from `test`.`t7` where (`test`.`t7`.`uq` = `test`.`t6`.`clinic_uq`))
+select * from t1 where a= (select a from t2,t4 where t2.b=t4.b);
+ERROR 23000: Column 'a' in field list is ambiguous
+drop table t1,t2,t3;
+CREATE TABLE t3 (a varchar(20),b char(1) NOT NULL default '0');
+INSERT INTO t3 VALUES ('W','a'),('A','c'),('J','b');
+CREATE TABLE t2 (a varchar(20),b int NOT NULL default '0');
+INSERT INTO t2 VALUES ('W','1'),('A','3'),('J','2');
+CREATE TABLE t1 (a varchar(20),b date NOT NULL default '0000-00-00');
+INSERT INTO t1 VALUES ('W','1732-02-22'),('A','1735-10-30'),('J','1743-04-13');
+SELECT * FROM t1 WHERE b = (SELECT MIN(b) FROM t1);
+a b
+W 1732-02-22
+SELECT * FROM t2 WHERE b = (SELECT MIN(b) FROM t2);
+a b
+W 1
+SELECT * FROM t3 WHERE b = (SELECT MIN(b) FROM t3);
+a b
+W a
+CREATE TABLE `t8` (
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+`email` varchar(60) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`),
+UNIQUE KEY `email` (`email`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t8 (pseudo,email) VALUES ('joce','test');
+INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
+INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
+EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where; Using index
+4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where
+3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
+t8 WHERE pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE
+pseudo='joce');
+ERROR 21000: Operand should contain 1 column(s)
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
+pseudo
+joce
+SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo LIKE '%joce%');
+ERROR 21000: Subquery returns more than 1 row
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8;
+CREATE TABLE `t1` (
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (topic,date,pseudo) VALUES
+('43506','2002-10-02','joce'),('40143','2002-08-03','joce');
+EXPLAIN EXTENDED SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select distinct `test`.`t1`.`date` AS `date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')
+EXPLAIN EXTENDED SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 SUBQUERY t1 index NULL PRIMARY 43 NULL 2 100.00 Using where; Using index
+Warnings:
+Note 1003 select (select distinct `test`.`t1`.`date` from `test`.`t1` where (`test`.`t1`.`date` = '2002-08-03')) AS `(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')`
+SELECT DISTINCT date FROM t1 WHERE date='2002-08-03';
+date
+2002-08-03
+SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03');
+(SELECT DISTINCT date FROM t1 WHERE date='2002-08-03')
+2002-08-03
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL SELECT 1;
+1
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1;
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL topic 3 NULL 2 100.00 Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where (1 = (select 1 union select 1))
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (40143,1),(43506,2);
+CREATE TABLE `t2` (
+`mot` varchar(30) NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`)
+) ENGINE=MyISAM ROW_FORMAT=DYNAMIC;
+INSERT INTO t2 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce'), ('joce','43506','2002-10-22','joce');
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+a
+40143
+SELECT numeropost,maxnumrep FROM t1 WHERE exists (SELECT 1 FROM t2 WHERE (mot='joce') AND date >= '2002-10-21' AND t1.numeropost = t2.topic) ORDER BY maxnumrep DESC LIMIT 0, 20;
+numeropost maxnumrep
+43506 2
+40143 1
+SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) b;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT 1 IN (SELECT 1 FROM t2 HAVING a);
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic IN (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+SELECT * from t2 where topic = any (SELECT SUM(topic) FROM t1);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic);
+mot topic date pseudo
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 4100)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 1
+SELECT * from t2 where topic = all (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+SELECT * from t2 where topic <> any (SELECT SUM(topic) FROM t2);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+joce 43506 2002-10-22 joce
+SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = any (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT * from t2 where topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000);
+mot topic date pseudo
+joce 40143 2002-10-22 joce
+SELECT *, topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000) from t2;
+mot topic date pseudo topic = all (SELECT topic FROM t2 GROUP BY topic HAVING topic < 41000)
+joce 40143 2002-10-22 joce 1
+joce 43506 2002-10-22 joce 0
+drop table t1,t2;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM ROW_FORMAT=FIXED;
+INSERT INTO t1 (numeropost,maxnumrep) VALUES (1,0),(2,1);
+select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1);
+ERROR 21000: Subquery returns more than 1 row
+show warnings;
+Level Code Message
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+(select * from t1) union (select * from t1) order by (select a from t1 limit 1);
+a
+1
+2
+3
+drop table t1;
+CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b');
+INSERT INTO t1 VALUES ();
+SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) a HAVING field='b');
+ERROR 21000: Subquery returns more than 1 row
+drop table t1;
+CREATE TABLE `t1` (
+`numeropost` mediumint(8) unsigned NOT NULL default '0',
+`numreponse` int(10) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) NOT NULL default '',
+PRIMARY KEY (`numeropost`,`numreponse`),
+UNIQUE KEY `numreponse` (`numreponse`),
+KEY `pseudo` (`pseudo`,`numeropost`)
+) ENGINE=MyISAM;
+SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Reference 'numreponse' not supported (forward reference in item list)
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a;
+ERROR 42S22: Unknown column 'a' in 'having clause'
+SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a;
+numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
+INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY t1 ref PRIMARY PRIMARY 3 const 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select 1 from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+ERROR 21000: Subquery returns more than 1 row
+EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
+EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+drop table t1;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1);
+SELECT 1 FROM (SELECT a FROM t1) b HAVING (SELECT b.a)=1;
+1
+1
+drop table t1;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 22),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+update t1 set b= (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+update t1 set b= (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+update t1 set b= (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 NULL
+1 21
+2 22
+drop table t1, t2;
+create table t1 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t1 values (0, 10),(1, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t1;
+a b
+0 10
+1 11
+2 12
+select * from t1 where b = (select b from t2 where t1.a = t2.a);
+a b
+2 12
+delete from t1 where b in (select b from t1);
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+delete from t1 where b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete from t1 where b = (select b from t2 where t1.a = t2.a);
+select * from t1;
+a b
+0 10
+1 11
+drop table t1, t2;
+create table t11 (a int NOT NULL, b int, primary key (a));
+create table t12 (a int NOT NULL, b int, primary key (a));
+create table t2 (a int NOT NULL, b int, primary key (a));
+insert into t11 values (0, 10),(1, 11),(2, 12);
+insert into t12 values (33, 10),(22, 11),(2, 12);
+insert into t2 values (1, 21),(2, 12),(3, 23);
+select * from t11;
+a b
+0 10
+1 11
+2 12
+select * from t12;
+a b
+33 10
+22 11
+2 12
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a);
+ERROR HY000: You can't specify target table 't12' for update in FROM clause
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2);
+ERROR 21000: Subquery returns more than 1 row
+delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a);
+select * from t11;
+a b
+0 10
+1 11
+select * from t12;
+a b
+33 10
+22 11
+drop table t11, t12, t2;
+CREATE TABLE t1 (x int) ENGINE=MyISAM;
+create table t2 (a int) ENGINE=MyISAM;
+create table t3 (b int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
+ERROR 21000: Subquery returns more than 1 row
+INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
+select * from t1;
+x
+1
+insert into t2 values (1);
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
+ERROR 42S22: Unknown column 'x' in 'field list'
+INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
+select * from t1;
+x
+1
+2
+3
+3
+11
+11
+2
+drop table t1, t2, t3;
+CREATE TABLE t1 (x int not null, y int, primary key (x)) ENGINE=MyISAM;
+create table t2 (a int);
+create table t3 (a int);
+insert into t2 values (1);
+insert into t3 values (1),(2);
+select * from t1;
+x y
+replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
+ERROR HY000: You can't specify target table 't1' for update in FROM clause
+replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
+ERROR 21000: Subquery returns more than 1 row
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 2
+replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2));
+select * from t1;
+x y
+1 3
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 1
+replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a+1 FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+replace LOW_PRIORITY into t1 (x, y) VALUES ((SELECT a+1 FROM t2), (SELECT a FROM t2));
+select * from t1;
+x y
+1 3
+4 2
+2 1
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1) b WHERE 1 IN (SELECT *);
+ERROR HY000: No tables used
+CREATE TABLE t2 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (1),(2);
+SELECT * FROM t2 WHERE id IN (SELECT 1);
+id
+1
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = 1)
+SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id
+1
+SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id
+2
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 ref id id 5 const 1 100.00 Using index
+Warnings:
+Note 1249 Select 3 was reduced during optimization
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where (`test`.`t2`.`id` = (1 + 1))
+EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index NULL id 5 NULL 2 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select `test`.`t2`.`id` AS `id` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`id`,<exists>(select 1 having (<cache>(`test`.`t2`.`id`) = <ref_null_helper>(1)) union select 3 having (<cache>(`test`.`t2`.`id`) = <ref_null_helper>(3))))
+SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
+id
+SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
+id
+2
+INSERT INTO t2 VALUES ((SELECT * FROM t2));
+ERROR HY000: You can't specify target table 't2' for update in FROM clause
+INSERT INTO t2 VALUES ((SELECT id FROM t2));
+ERROR HY000: You can't specify target table 't2' for update in FROM clause
+SELECT * FROM t2;
+id
+1
+2
+CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 values (1),(1);
+UPDATE t2 SET id=(SELECT * FROM t1);
+ERROR 21000: Subquery returns more than 1 row
+drop table t2, t1;
+create table t1 (a int);
+insert into t1 values (1),(2),(3);
+select 1 IN (SELECT * from t1);
+1 IN (SELECT * from t1)
+1
+select 10 IN (SELECT * from t1);
+10 IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a=2;
+select 1 IN (SELECT * from t1);
+1 IN (SELECT * from t1)
+1
+select 3 IN (SELECT * from t1);
+3 IN (SELECT * from t1)
+1
+select 10 IN (SELECT * from t1);
+10 IN (SELECT * from t1)
+NULL
+select 1 > ALL (SELECT * from t1);
+1 > ALL (SELECT * from t1)
+0
+select 10 > ALL (SELECT * from t1);
+10 > ALL (SELECT * from t1)
+NULL
+select 1 > ANY (SELECT * from t1);
+1 > ANY (SELECT * from t1)
+NULL
+select 10 > ANY (SELECT * from t1);
+10 > ANY (SELECT * from t1)
+1
+drop table t1;
+create table t1 (a varchar(20));
+insert into t1 values ('A'),('BC'),('DEF');
+select 'A' IN (SELECT * from t1);
+'A' IN (SELECT * from t1)
+1
+select 'XYZS' IN (SELECT * from t1);
+'XYZS' IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a='BC';
+select 'A' IN (SELECT * from t1);
+'A' IN (SELECT * from t1)
+1
+select 'DEF' IN (SELECT * from t1);
+'DEF' IN (SELECT * from t1)
+1
+select 'XYZS' IN (SELECT * from t1);
+'XYZS' IN (SELECT * from t1)
+NULL
+select 'A' > ALL (SELECT * from t1);
+'A' > ALL (SELECT * from t1)
+0
+select 'XYZS' > ALL (SELECT * from t1);
+'XYZS' > ALL (SELECT * from t1)
+NULL
+select 'A' > ANY (SELECT * from t1);
+'A' > ANY (SELECT * from t1)
+NULL
+select 'XYZS' > ANY (SELECT * from t1);
+'XYZS' > ANY (SELECT * from t1)
+1
+drop table t1;
+create table t1 (a float);
+insert into t1 values (1.5),(2.5),(3.5);
+select 1.5 IN (SELECT * from t1);
+1.5 IN (SELECT * from t1)
+1
+select 10.5 IN (SELECT * from t1);
+10.5 IN (SELECT * from t1)
+0
+select NULL IN (SELECT * from t1);
+NULL IN (SELECT * from t1)
+NULL
+update t1 set a=NULL where a=2.5;
+select 1.5 IN (SELECT * from t1);
+1.5 IN (SELECT * from t1)
+1
+select 3.5 IN (SELECT * from t1);
+3.5 IN (SELECT * from t1)
+1
+select 10.5 IN (SELECT * from t1);
+10.5 IN (SELECT * from t1)
+NULL
+select 1.5 > ALL (SELECT * from t1);
+1.5 > ALL (SELECT * from t1)
+0
+select 10.5 > ALL (SELECT * from t1);
+10.5 > ALL (SELECT * from t1)
+NULL
+select 1.5 > ANY (SELECT * from t1);
+1.5 > ANY (SELECT * from t1)
+NULL
+select 10.5 > ANY (SELECT * from t1);
+10.5 > ANY (SELECT * from t1)
+1
+explain extended select (select a+1) from t1;
+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
+Warnings:
+Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
+Note 1249 Select 2 was reduced during optimization
+Note 1003 select (`test`.`t1`.`a` + 1) AS `(select a+1)` from `test`.`t1`
+select (select a+1) from t1;
+(select a+1)
+2.5
+NULL
+4.5
+drop table t1;
+CREATE TABLE t1 (a int(11) NOT NULL default '0', PRIMARY KEY (a));
+CREATE TABLE t2 (a int(11) default '0', INDEX (a));
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
+a t1.a in (select t2.a from t2)
+1 1
+2 1
+3 1
+4 0
+explain extended SELECT t1.a, t1.a in (select t2.a from t2) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery a a 5 func 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`a`) in t2 on a checking NULL having <is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2)` from `test`.`t1`
+CREATE TABLE t3 (a int(11) default '0');
+INSERT INTO t3 VALUES (1),(2),(3);
+SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
+a t1.a in (select t2.a from t2,t3 where t3.a=t2.a)
+1 1
+2 1
+3 1
+4 0
+explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+2 DEPENDENT SUBQUERY t2 ref_or_null a a 5 func 2 100.00 Using where; Using index
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
+drop table t1,t2,t3;
+# check correct NULL Processing for normal IN/ALL/ANY
+# and 2 ways of max/min optimization
+create table t1 (a int);
+insert into t1 values (1), (100), (NULL), (1000);
+create table t2 (a int not null);
+# subselect returns empty set (for NULL and non-NULL left part)
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 1
+100 1
+NULL 1
+1000 1
+select a from t1 where a in (select * from t2);
+a
+select a from t1 where a > any (select * from t2);
+a
+select a from t1 where a > all (select * from t2);
+a
+1
+100
+NULL
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+select a from t1 where a > any (select * from t2 group by a);
+a
+select a from t1 where a > all (select * from t2 group by a);
+a
+1
+100
+NULL
+1000
+insert into t2 values (1),(200);
+# sebselect returns non-empty set without NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 0
+NULL NULL
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 1
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+1000
+drop table t2;
+create table t2 (a int);
+insert into t2 values (1),(NULL),(200);
+# sebselect returns non-empty set with NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 NULL
+NULL NULL
+1000 NULL
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 NULL
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 NULL
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+drop table t1, t2;
+create table t1 (a float);
+select 10.5 IN (SELECT * from t1 LIMIT 1);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+select 10.5 IN (SELECT * from t1 LIMIT 1 UNION SELECT 1.5);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int, b int, c varchar(10));
+create table t2 (a int);
+insert into t1 values (1,2,'a'),(2,3,'b'),(3,4,'c');
+insert into t2 values (1),(2),(NULL);
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,2,'a') (select c from t1 where a=t2.a)
+1 1 a
+2 0 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,3,'b') (select c from t1 where a=t2.a)
+1 0 a
+2 1 b
+NULL NULL NULL
+select a, (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c'),(select c from t1 where a=t2.a) from t2;
+a (select a,b,c from t1 where t1.a=t2.a) = ROW(a,4,'c') (select c from t1 where a=t2.a)
+1 0 a
+2 0 b
+NULL NULL NULL
+drop table t1,t2;
+create table t1 (a int, b real, c varchar(10));
+insert into t1 values (1, 1, 'a'), (2,2,'b'), (NULL, 2, 'b');
+select ROW(1, 1, 'a') IN (select a,b,c from t1);
+ROW(1, 1, 'a') IN (select a,b,c from t1)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1);
+ROW(1, 2, 'a') IN (select a,b,c from t1)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1);
+ROW(1, 1, 'a') IN (select b,a,c from t1)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select a,b,c from t1 where a is not null)
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null);
+ROW(1, 2, 'a') IN (select a,b,c from t1 where a is not null)
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null);
+ROW(1, 1, 'a') IN (select b,a,c from t1 where a is not null)
+1
+select ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+1
+select ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a');
+ROW(1, 2, 'a') IN (select a,b,c from t1 where c='b' or c='a')
+0
+select ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a');
+ROW(1, 1, 'a') IN (select b,a,c from t1 where c='b' or c='a')
+1
+select ROW(1, 1, 'a') IN (select b,a,c from t1 limit 2);
+ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1);
+do @a:=(SELECT a from t1);
+select @a;
+@a
+1
+set @a:=2;
+set @a:=(SELECT a from t1);
+select @a;
+@a
+1
+drop table t1;
+do (SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+set @a:=(SELECT a from t1);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (a int, KEY(a));
+HANDLER t1 OPEN;
+HANDLER t1 READ a=((SELECT 1));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT 1))' at line 1
+HANDLER t1 CLOSE;
+drop table t1;
+create table t1 (a int);
+create table t2 (b int);
+insert into t1 values (1),(2);
+insert into t2 values (1);
+select a from t1 where a in (select a from t1 where a in (select b from t2));
+a
+1
+drop table t1, t2;
+create table t1 (a int, b int);
+create table t2 like t1;
+insert into t1 values (1,2),(1,3),(1,4),(1,5);
+insert into t2 values (1,2),(1,3);
+select * from t1 where row(a,b) in (select a,b from t2);
+a b
+1 2
+1 3
+drop table t1, t2;
+CREATE TABLE `t1` (`i` int(11) NOT NULL default '0',PRIMARY KEY (`i`)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+select * from t1;
+i
+2
+drop table t1;
+CREATE TABLE t1 (a int(1));
+EXPLAIN EXTENDED SELECT (SELECT RAND() FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select rand() from `test`.`t1`) AS `(SELECT RAND() FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT ENCRYPT('test') FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select encrypt('test') from `test`.`t1`) AS `(SELECT ENCRYPT('test') FROM t1)` from `test`.`t1`
+EXPLAIN EXTENDED SELECT (SELECT BENCHMARK(1,1) FROM t1) FROM t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select (select benchmark(1,1) from `test`.`t1`) AS `(SELECT BENCHMARK(1,1) FROM t1)` from `test`.`t1`
+drop table t1;
+CREATE TABLE `t1` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t2` (
+`mot` varchar(30) character set latin1 NOT NULL default '',
+`topic` mediumint(8) unsigned NOT NULL default '0',
+`date` date NOT NULL default '0000-00-00',
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`mot`,`pseudo`,`date`,`topic`),
+KEY `pseudo` (`pseudo`,`date`,`topic`),
+KEY `topic` (`topic`)
+) ENGINE=MyISAM CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+CREATE TABLE `t3` (
+`numeropost` mediumint(8) unsigned NOT NULL auto_increment,
+`maxnumrep` int(10) unsigned NOT NULL default '0',
+PRIMARY KEY (`numeropost`),
+UNIQUE KEY `maxnumrep` (`maxnumrep`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t2 VALUES ('joce','1','','joce'),('test','2','','test');
+Warnings:
+Warning 1265 Data truncated for column 'date' at row 1
+Warning 1265 Data truncated for column 'date' at row 2
+INSERT INTO t3 VALUES (1,1);
+SELECT DISTINCT topic FROM t2 WHERE NOT EXISTS(SELECT * FROM t3 WHERE
+numeropost=topic);
+topic
+2
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+test 2 0000-00-00 test
+DELETE FROM t1 WHERE topic IN (SELECT DISTINCT topic FROM t2 WHERE NOT
+EXISTS(SELECT * FROM t3 WHERE numeropost=topic));
+select * from t1;
+mot topic date pseudo
+joce 1 0000-00-00 joce
+drop table t1, t2, t3;
+SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+a (SELECT a)
+1 1
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT 1)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT 1)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a)` int(1) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(1) NOT NULL DEFAULT '0',
+ `(SELECT a+0)` int(3) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
+select * from t1;
+a
+2
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` bigint(20) NOT NULL DEFAULT '0'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+explain extended select a,(select (select rand() from t1 limit 1) from t1 limit 1)
+from t1;
+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
+2 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+3 UNCACHEABLE SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,(select (select rand() from `test`.`t1` limit 1) from `test`.`t1` limit 1) AS `(select (select rand() from t1 limit 1) from t1 limit 1)` from `test`.`t1`
+drop table t1;
+select t1.Continent, t2.Name, t2.Population from t1 LEFT JOIN t2 ON t1.Code = t2.Country where t2.Population IN (select max(t2.Population) AS Population from t2, t1 where t2.Country = t1.Code group by Continent);
+ERROR 42S02: Table 'test.t1' doesn't exist
+CREATE TABLE t1 (
+ID int(11) NOT NULL auto_increment,
+name char(35) NOT NULL default '',
+t2 char(3) NOT NULL default '',
+District char(20) NOT NULL default '',
+Population int(11) NOT NULL default '0',
+PRIMARY KEY (ID)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (130,'Sydney','AUS','New South Wales',3276207);
+INSERT INTO t1 VALUES (131,'Melbourne','AUS','Victoria',2865329);
+INSERT INTO t1 VALUES (132,'Brisbane','AUS','Queensland',1291117);
+CREATE TABLE t2 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default '',
+PRIMARY KEY (Code)
+) ENGINE=MyISAM;
+INSERT INTO t2 VALUES ('AUS','Australia','Oceania','Australia and New Zealand',7741220.00,1901,18886000,79.8,351182.00,392911.00,'Australia','Constitutional Monarchy, Federation','Elisabeth II',135,'AU');
+INSERT INTO t2 VALUES ('AZE','Azerbaijan','Asia','Middle East',86600.00,1991,7734000,62.9,4127.00,4100.00,'Azärbaycan','Federal Republic','Heydär Äliyev',144,'AZ');
+select t2.Continent, t1.Name, t1.Population from t2 LEFT JOIN t1 ON t2.Code = t1.t2 where t1.Population IN (select max(t1.Population) AS Population from t1, t2 where t1.t2 = t2.Code group by Continent);
+Continent Name Population
+Oceania Sydney 3276207
+drop table t1, t2;
+CREATE TABLE `t1` (
+`id` mediumint(8) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) character set latin1 NOT NULL default '',
+PRIMARY KEY (`id`),
+UNIQUE KEY `pseudo` (`pseudo`)
+) ENGINE=MyISAM PACK_KEYS=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (pseudo) VALUES ('test');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
+INSERT INTO t1 (pseudo) VALUES ('test1');
+SELECT 0 IN (SELECT 1 FROM t1 a);
+0 IN (SELECT 1 FROM t1 a)
+0
+EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+Warnings:
+Note 1003 select <in_optimizer>(0,<exists>(select 1 from `test`.`t1` `a` where (0 = 1))) AS `0 IN (SELECT 1 FROM t1 a)`
+drop table t1;
+CREATE TABLE `t1` (
+`i` int(11) NOT NULL default '0',
+PRIMARY KEY (`i`)
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1);
+UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i));
+UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i));
+UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t);
+ERROR 42S22: Unknown column 't.i' in 'field list'
+select * from t1;
+i
+3
+drop table t1;
+CREATE TABLE t1 (
+id int(11) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(1),(2),(2),(1),(3);
+CREATE TABLE t2 (
+id int(11) default NULL,
+name varchar(15) default NULL
+) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (4,'vita'), (1,'vita'), (2,'vita'), (1,'vita');
+update t1, t2 set t2.name='lenka' where t2.id in (select id from t1);
+select * from t2;
+id name
+4 vita
+1 lenka
+2 lenka
+1 lenka
+drop table t1,t2;
+create table t1 (a int, unique index indexa (a));
+insert into t1 values (-1), (-4), (-2), (NULL);
+select -10 IN (select a from t1 FORCE INDEX (indexa));
+-10 IN (select a from t1 FORCE INDEX (indexa))
+NULL
+drop table t1;
+create table t1 (id int not null auto_increment primary key, salary int, key(salary));
+insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
+explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using index condition
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
+drop table t1;
+CREATE TABLE t1 (
+ID int(10) unsigned NOT NULL auto_increment,
+SUB_ID int(3) unsigned NOT NULL default '0',
+REF_ID int(10) unsigned default NULL,
+REF_SUB int(3) unsigned default '0',
+PRIMARY KEY (ID,SUB_ID),
+UNIQUE KEY t1_PK (ID,SUB_ID),
+KEY t1_FK (REF_ID,REF_SUB),
+KEY t1_REFID (REF_ID)
+) ENGINE=MyISAM CHARSET=cp1251;
+INSERT INTO t1 VALUES (1,0,NULL,NULL),(2,0,NULL,NULL);
+SELECT DISTINCT REF_ID FROM t1 WHERE ID= (SELECT DISTINCT REF_ID FROM t1 WHERE ID=2);
+REF_ID
+DROP TABLE t1;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,0), (2,0), (3,0);
+insert into t2 values (1,1), (2,1), (3,1), (2,2);
+update ignore t1 set b=(select b from t2 where t1.a=t2.a);
+Warnings:
+Error 1242 Subquery returns more than 1 row
+select * from t1;
+a b
+1 1
+2 NULL
+3 1
+drop table t1, t2;
+CREATE TABLE `t1` (
+`id` mediumint(8) unsigned NOT NULL auto_increment,
+`pseudo` varchar(35) NOT NULL default '',
+`email` varchar(60) NOT NULL default '',
+PRIMARY KEY (`id`),
+UNIQUE KEY `email` (`email`),
+UNIQUE KEY `pseudo` (`pseudo`)
+) ENGINE=MyISAM CHARSET=latin1 PACK_KEYS=1 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 (id,pseudo,email) VALUES (1,'test','test'),(2,'test1','test1');
+SELECT pseudo as a, pseudo as b FROM t1 GROUP BY (SELECT a) ORDER BY (SELECT id*1);
+a b
+test test
+test1 test1
+drop table if exists t1;
+(SELECT 1 as a) UNION (SELECT 1) ORDER BY (SELECT a+0);
+a
+1
+create table t1 (a int not null, b int, primary key (a));
+create table t2 (a int not null, primary key (a));
+create table t3 (a int not null, b int, primary key (a));
+insert into t1 values (1,10), (2,20), (3,30), (4,40);
+insert into t2 values (2), (3), (4), (5);
+insert into t3 values (10,3), (20,4), (30,5);
+select * from t2 where t2.a in (select a from t1);
+a
+2
+3
+4
+explain extended select * from t2 where t2.a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 4 75.00 Using where; Using index; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+a
+2
+4
+explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
+1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 4 75.00 Using where; Using join buffer (flat, BNL join)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
+select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
+a
+2
+3
+explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index
+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`))
+drop table t1, t2, t3;
+create table t1 (a int, b int, index a (a,b));
+create table t2 (a int, index a (a));
+create table t3 (a int, b int, index a (a));
+insert into t1 values (1,10), (2,20), (3,30), (4,40);
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1
+select rand()*100000+200,rand()*100000 from t0 A, t0 B, t0 C, t0 D;
+insert into t2 values (2), (3), (4), (5);
+insert into t3 values (10,3), (20,4), (30,5);
+select * from t2 where t2.a in (select a from t1);
+a
+2
+3
+4
+explain extended select * from t2 where t2.a in (select a from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where (`test`.`t1`.`a` = `test`.`t2`.`a`)
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+a
+2
+4
+explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
+select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
+a
+2
+3
+explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+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`))
+insert into t1 values (3,31);
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+a
+2
+3
+4
+select * from t2 where t2.a in (select a from t1 where t1.b <> 30 and t1.b <> 31);
+a
+2
+4
+explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index
+1 PRIMARY t1 ref a a 5 test.t2.a 101 100.00 Using where; Using index; FirstMatch(t2)
+Warnings:
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t1`.`b` <> 30))
+drop table t0, t1, t2, t3;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+create table t3 (a int, b int);
+insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), (2,-1), (3,10);
+insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1);
+insert into t3 values (3,3), (2,2), (1,1);
+select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3;
+a (select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1)
+3 1
+2 2
+1 2
+drop table t1,t2,t3;
+create table t1 (s1 int);
+create table t2 (s1 int);
+insert into t1 values (1);
+insert into t2 values (1);
+select * from t1 where exists (select s1 from t2 having max(t2.s1)=t1.s1);
+s1
+1
+drop table t1,t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+insert into t1 values (1);
+insert into t2 values (1);
+update t1 set s1 = s1 + 1 where 1 = (select x.s1 as A from t2 WHERE t2.s1 > t1.s1 order by A);
+ERROR 42S22: Unknown column 'x.s1' in 'field list'
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 CHAR(5) COLLATE latin1_german1_ci,
+s2 CHAR(5) COLLATE latin1_swedish_ci);
+INSERT INTO t1 VALUES ('z','?');
+select * from t1 where s1 > (select max(s2) from t1);
+ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+select * from t1 where s1 > any (select max(s2) from t1);
+ERROR HY000: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '<'
+drop table t1;
+create table t1(toid int,rd int);
+create table t2(userid int,pmnew int,pmtotal int);
+insert into t2 values(1,0,0),(2,0,0);
+insert into t1 values(1,0),(1,0),(1,0),(1,12),(1,15),(1,123),(1,12312),(1,12312),(1,123),(2,0),(2,0),(2,1),(2,2);
+select userid,pmtotal,pmnew, (select count(rd) from t1 where toid=t2.userid) calc_total, (select count(rd) from t1 where rd=0 and toid=t2.userid) calc_new from t2 where userid in (select distinct toid from t1);
+userid pmtotal pmnew calc_total calc_new
+1 0 0 9 3
+2 0 0 4 2
+drop table t1, t2;
+create table t1 (s1 char(5));
+select (select 'a','b' from t1 union select 'a','b' from t1) from t1;
+ERROR 21000: Operand should contain 1 column(s)
+insert into t1 values ('tttt');
+select * from t1 where ('a','b')=(select 'a','b' from t1 union select 'a','b' from t1);
+s1
+tttt
+explain extended (select * from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 (select 'tttt' AS `s1` from `test`.`t1`)
+(select * from t1);
+s1
+tttt
+drop table t1;
+create table t1 (s1 char(5), index s1(s1));
+create table t2 (s1 char(5), index s1(s1));
+insert into t1 values ('a1'),('a2'),('a3');
+insert into t2 values ('a1'),('a2');
+select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
+s1 s1 = ANY (SELECT s1 FROM t2)
+a1 1
+a2 1
+a3 0
+select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
+s1 s1 <> ALL (SELECT s1 FROM t2)
+a1 0
+a2 0
+a3 1
+select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
+s1 s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')
+a1 0
+a2 1
+a3 1
+explain extended select s1, s1 NOT IN (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2)` from `test`.`t1`
+explain extended select s1, s1 = ANY (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))) AS `s1 = ANY (SELECT s1 FROM t2)` from `test`.`t1`
+explain extended select s1, s1 <> ALL (SELECT s1 FROM t2) from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 <> ALL (SELECT s1 FROM t2)` from `test`.`t1`
+explain extended select s1, s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2') from t1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL s1 6 NULL 3 100.00 Using index
+2 DEPENDENT SUBQUERY t2 index_subquery s1 s1 6 func 2 100.00 Using index; Using where; Full scan on NULL key
+Warnings:
+Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < 'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
+drop table t1,t2;
+create table t2 (a int, b int not null);
+create table t3 (a int);
+insert into t3 values (6),(7),(3);
+select * from t3 where a >= all (select b from t2);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= some (select b from t2);
+a
+explain extended select * from t3 where a >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= all (select b from t2 group by 1);
+a
+6
+7
+3
+explain extended select * from t3 where a >= all (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select NULL from `test`.`t2` group by 1) > <cache>(`test`.`t3`.`a`))))
+select * from t3 where a >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where a >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(<min>(select NULL from `test`.`t2` group by 1) <= <cache>(`test`.`t3`.`a`))))
+select * from t3 where NULL >= any (select b from t2);
+a
+explain extended select * from t3 where NULL >= any (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= any (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
+select * from t3 where NULL >= some (select b from t2);
+a
+explain extended select * from t3 where NULL >= some (select b from t2);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
+select * from t3 where NULL >= some (select b from t2 group by 1);
+a
+explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
+2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
+insert into t2 values (2,2), (2,1), (3,3), (3,1);
+select * from t3 where a > all (select max(b) from t2 group by a);
+a
+6
+7
+explain extended select * from t3 where a > all (select max(b) from t2 group by a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary
+Warnings:
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= <cache>(`test`.`t3`.`a`))))
+drop table t2, t3;
+CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
+INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
+CREATE TABLE `t2` (`db_id` int(11) NOT NULL auto_increment,`name` varchar(200) NOT NULL default '',`primary_uid` smallint(6) NOT NULL default '0',`secondary_uid` smallint(6) NOT NULL default '0',PRIMARY KEY (`db_id`),UNIQUE KEY `name_2` (`name`),FULLTEXT KEY `name` (`name`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2147483647;
+INSERT INTO `t2` (`db_id`, `name`, `primary_uid`, `secondary_uid`) VALUES (18, 'Not Set 1', 0, 0),(19, 'Valid', 1, 2),(20, 'Valid 2', 1, 2),(21, 'Should Not Return', 1, 2),(26, 'Not Set 2', 0, 0),(-1, 'ALL DB\'S', 0, 0);
+CREATE TABLE `t3` (`taskgenid` mediumint(9) NOT NULL auto_increment,`dbid` int(11) NOT NULL default '0',`taskid` int(11) NOT NULL default '0',`mon` tinyint(4) NOT NULL default '1',`tues` tinyint(4) NOT NULL default '1',`wed` tinyint(4) NOT NULL default '1',`thur` tinyint(4) NOT NULL default '1',`fri` tinyint(4) NOT NULL default '1',`sat` tinyint(4) NOT NULL default '0',`sun` tinyint(4) NOT NULL default '0',`how_often` smallint(6) NOT NULL default '1',`userid` smallint(6) NOT NULL default '0',`active` tinyint(4) NOT NULL default '1',PRIMARY KEY (`taskgenid`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=2 ;
+INSERT INTO `t3` (`taskgenid`, `dbid`, `taskid`, `mon`, `tues`,`wed`, `thur`, `fri`, `sat`, `sun`, `how_often`, `userid`, `active`) VALUES (1,-1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1);
+CREATE TABLE `t4` (`task_id` smallint(6) NOT NULL default '0',`description` varchar(200) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO `t4` (`task_id`, `description`) VALUES (1, 'Daily Check List'),(2, 'Weekly Status');
+select dbid, name, (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01') from t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND t4.task_id = taskid;
+dbid name (date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')
+-1 Valid 1
+-1 Valid 2 1
+-1 Should Not Return 0
+SELECT dbid, name FROM t3 a, t2 b, t4 WHERE dbid = - 1 AND primary_uid = '1' AND ((date_format(now() , '%Y-%m-%d') - INTERVAL how_often DAY) >= ifnull((SELECT date_format(max(create_date),'%Y-%m-%d') FROM t1 WHERE dbid = b.db_id AND taskid = a.taskgenid), '1950-01-01')) AND t4.task_id = taskid;
+dbid name
+-1 Valid
+-1 Valid 2
+drop table t1,t2,t3,t4;
+CREATE TABLE t1 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 (id int(11) default NULL) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES (2),(6);
+select * from t1 where (1,2,6) in (select * from t2);
+ERROR 21000: Operand should contain 3 column(s)
+DROP TABLE t1,t2;
+create table t1 (s1 int);
+insert into t1 values (1);
+insert into t1 values (2);
+set sort_buffer_size = (select s1 from t1);
+ERROR 21000: Subquery returns more than 1 row
+do (select * from t1);
+Warnings:
+Error 1242 Subquery returns more than 1 row
+drop table t1;
+create table t1 (s1 char);
+insert into t1 values ('e');
+select * from t1 where 'f' > any (select s1 from t1);
+s1
+e
+select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+s1
+e
+explain extended select * from t1 where 'f' > any (select s1 from t1 union select s1 from t1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00
+2 SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+3 UNION t1 system NULL NULL NULL NULL 1 100.00
+NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',(<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`) < 'f')))
+drop table t1;
+CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
+CREATE TABLE t2 (code char(5) NOT NULL default '',UNIQUE KEY code (code)) ENGINE=MyISAM CHARSET=latin1;
+INSERT INTO t2 VALUES ('1'),('1226'),('1245'),('1862'),('18623'),('1874'),('1967'),('6');
+select c.number as phone,(select p.code from t2 p where c.number like concat(p.code, '%') order by length(p.code) desc limit 1) as code from t1 c;
+phone code
+69294728265 6
+18621828126 1862
+89356874041 NULL
+95895001874 NULL
+drop table t1, t2;
+create table t1 (s1 int);
+create table t2 (s1 int);
+select * from t1 where (select count(*) from t2 where t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'where clause'
+select * from t1 where (select count(*) from t2 group by t1.s2) = 1;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+select count(*) from t2 group by t1.s2;
+ERROR 42S22: Unknown column 't1.s2' in 'group statement'
+drop table t1, t2;
+CREATE TABLE t1(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC VARCHAR(20) DEFAULT NULL,PRIMARY KEY (COLA, COLB));
+CREATE TABLE t2(COLA FLOAT NOT NULL,COLB FLOAT NOT NULL,COLC CHAR(1) NOT NULL,PRIMARY KEY (COLA));
+INSERT INTO t1 VALUES (1,1,'1A3240'), (1,2,'4W2365');
+INSERT INTO t2 VALUES (100, 200, 'C');
+SELECT DISTINCT COLC FROM t1 WHERE COLA = (SELECT COLA FROM t2 WHERE COLB = 200 AND COLC ='C' LIMIT 1);
+COLC
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a int(1));
+INSERT INTO t1 VALUES (1),(1),(1),(1),(1),(2),(3),(4),(5);
+SELECT DISTINCT (SELECT a) FROM t1 LIMIT 100;
+(SELECT a)
+1
+2
+3
+4
+5
+DROP TABLE t1;
+create table t1 (a int, b decimal(13, 3));
+insert into t1 values (1, 0.123);
+select a, (select max(b) from t1) into outfile "../../tmp/subselect.out.file.1" from t1;
+delete from t1;
+load data infile "../../tmp/subselect.out.file.1" into table t1;
+select * from t1;
+a b
+1 0.123
+drop table t1;
+CREATE TABLE `t1` (
+`id` int(11) NOT NULL auto_increment,
+`id_cns` tinyint(3) unsigned NOT NULL default '0',
+`tipo` enum('','UNO','DUE') NOT NULL default '',
+`anno_dep` smallint(4) unsigned zerofill NOT NULL default '0000',
+`particolare` mediumint(8) unsigned NOT NULL default '0',
+`generale` mediumint(8) unsigned NOT NULL default '0',
+`bis` tinyint(3) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`),
+UNIQUE KEY `idx_cns_gen_anno` (`anno_dep`,`id_cns`,`generale`,`particolare`),
+UNIQUE KEY `idx_cns_par_anno` (`id_cns`,`anno_dep`,`tipo`,`particolare`,`bis`)
+);
+INSERT INTO `t1` VALUES (1,16,'UNO',1987,2048,9681,0),(2,50,'UNO',1987,1536,13987,0),(3,16,'UNO',1987,2432,14594,0),(4,16,'UNO',1987,1792,13422,0),(5,16,'UNO',1987,1025,10240,0),(6,16,'UNO',1987,1026,7089,0);
+CREATE TABLE `t2` (
+`id` tinyint(3) unsigned NOT NULL auto_increment,
+`max_anno_dep` smallint(6) unsigned NOT NULL default '0',
+PRIMARY KEY (`id`)
+);
+INSERT INTO `t2` VALUES (16,1987),(50,1990),(51,1990);
+SELECT cns.id, cns.max_anno_dep, cns.max_anno_dep = (SELECT s.anno_dep FROM t1 AS s WHERE s.id_cns = cns.id ORDER BY s.anno_dep DESC LIMIT 1) AS PIPPO FROM t2 AS cns;
+id max_anno_dep PIPPO
+16 1987 1
+50 1990 0
+51 1990 NULL
+DROP TABLE t1, t2;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SET SQL_SELECT_LIMIT=1;
+select sum(a) from (select * from t1) as a;
+sum(a)
+6
+select 2 in (select * from t1);
+2 in (select * from t1)
+1
+SET SQL_SELECT_LIMIT=default;
+drop table t1;
+CREATE TABLE t1 (a int, b int, INDEX (a));
+INSERT INTO t1 VALUES (1, 1), (1, 2), (1, 3);
+SELECT * FROM t1 WHERE a = (SELECT MAX(a) FROM t1 WHERE a = 1) ORDER BY b;
+a b
+1 1
+1 2
+1 3
+DROP TABLE t1;
+create table t1(val varchar(10));
+insert into t1 values ('aaa'), ('bbb'),('eee'),('mmm'),('ppp');
+select count(*) from t1 as w1 where w1.val in (select w2.val from t1 as w2 where w2.val like 'm%') and w1.val in (select w3.val from t1 as w3 where w3.val like 'e%');
+count(*)
+0
+drop table t1;
+create table t1 (id int not null, text varchar(20) not null default '', primary key (id));
+insert into t1 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text11'), (12, 'text12');
+select * from t1 where id not in (select id from t1 where id < 8);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
+id text
+8 text8
+9 text9
+10 text10
+11 text11
+12 text12
+explain extended select * from t1 where id not in (select id from t1 where id < 8);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 12 100.00 Using where
+2 DEPENDENT SUBQUERY t1 unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where
+Warnings:
+Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`text` AS `text` from `test`.`t1` where (not(<in_optimizer>(`test`.`t1`.`id`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`id`) in t1 on PRIMARY where ((`test`.`t1`.`id` < 8) and (<cache>(`test`.`t1`.`id`) = `test`.`t1`.`id`)))))))
+explain extended select * from t1 as tt where not exists (select id from t1 where id < 8 and (id = tt.id or id is null) having id is not null);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY tt ALL NULL NULL NULL NULL 12 100.00 Using where
+2 DEPENDENT SUBQUERY t1 eq_ref PRIMARY PRIMARY 4 test.tt.id 1 100.00 Using where; Using index
+Warnings:
+Note 1276 Field or reference 'test.tt.id' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`tt`.`id` AS `id`,`test`.`tt`.`text` AS `text` from `test`.`t1` `tt` where (not(exists(select `test`.`t1`.`id` from `test`.`t1` where ((`test`.`t1`.`id` < 8) and (`test`.`t1`.`id` = `test`.`tt`.`id`)) having (`test`.`t1`.`id` is not null))))
+insert into t1 (id, text) values (1000, 'text1000'), (1001, 'text1001');
+create table t2 (id int not null, text varchar(20) not null default '', primary key (id));
+insert into t2 (id, text) values (1, 'text1'), (2, 'text2'), (3, 'text3'), (4, 'text4'), (5, 'text5'), (6, 'text6'), (7, 'text7'), (8, 'text8'), (9, 'text9'), (10, 'text10'), (11, 'text1'), (12, 'text2'), (13, 'text3'), (14, 'text4'), (15, 'text5'), (16, 'text6'), (17, 'text7'), (18, 'text8'), (19, 'text9'), (20, 'text10'),(21, 'text1'), (22, 'text2'), (23, 'text3'), (24, 'text4'), (25, 'text5'), (26, 'text6'), (27, 'text7'), (28, 'text8'), (29, 'text9'), (30, 'text10'), (31, 'text1'), (32, 'text2'), (33, 'text3'), (34, 'text4'), (35, 'text5'), (36, 'text6'), (37, 'text7'), (38, 'text8'), (39, 'text9'), (40, 'text10'), (41, 'text1'), (42, 'text2'), (43, 'text3'), (44, 'text4'), (45, 'text5'), (46, 'text6'), (47, 'text7'), (48, 'text8'), (49, 'text9'), (50, 'text10');
+select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
+id text id text id text
+1 text1 1 text1 1 text1
+2 text2 2 text2 2 text2
+3 text3 3 text3 3 text3
+4 text4 4 text4 4 text4
+5 text5 5 text5 5 text5
+6 text6 6 text6 6 text6
+7 text7 7 text7 7 text7
+8 text8 8 text8 8 text8
+9 text9 9 text9 9 text9
+10 text10 10 text10 10 text10
+11 text11 11 text1 11 text11
+12 text12 12 text2 12 text12
+1000 text1000 NULL NULL 1000 text1000
+1001 text1001 NULL NULL 1000 text1000
+explain extended select * from t1 a left join t2 b on (a.id=b.id or b.id is null) join t1 c on (if(isnull(b.id), 1000, b.id)=c.id);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE a ALL NULL NULL NULL NULL 14 100.00
+1 SIMPLE b eq_ref PRIMARY PRIMARY 4 test.a.id 2 100.00
+1 SIMPLE c eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using index condition
+Warnings:
+Note 1003 select `test`.`a`.`id` AS `id`,`test`.`a`.`text` AS `text`,`test`.`b`.`id` AS `id`,`test`.`b`.`text` AS `text`,`test`.`c`.`id` AS `id`,`test`.`c`.`text` AS `text` from `test`.`t1` `a` left join `test`.`t2` `b` on(((`test`.`b`.`id` = `test`.`a`.`id`) or isnull(`test`.`b`.`id`))) join `test`.`t1` `c` where (if(isnull(`test`.`b`.`id`),1000,`test`.`b`.`id`) = `test`.`c`.`id`)
+drop table t1,t2;
+create table t1 (a int);
+insert into t1 values (1);
+explain select benchmark(1000, (select a from t1 where a=sha(rand())));
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
+2 UNCACHEABLE SUBQUERY t1 system NULL NULL NULL NULL 1
+drop table t1;
+create table t1(id int);
+create table t2(id int);
+create table t3(flag int);
+select (select * from t3 where id not null) from t1, t2;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'null) from t1, t2' at line 1
+drop table t1,t2,t3;
+CREATE TABLE t1 (id INT);
+CREATE TABLE t2 (id INT);
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES (1);
+SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
+id c
+1 1
+2 0
+SELECT id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id);
+id c
+1 1
+2 0
+SELECT t1.id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY t1.id;
+id c
+1 1
+2 0
+SELECT id, ( SELECT COUNT(t.id) FROM t2 AS t WHERE t.id = t1.id ) AS c FROM t1 LEFT JOIN t2 USING (id) ORDER BY id;
+id c
+1 1
+2 0
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+ALTER TABLE t1 ADD INDEX (a);
+SELECT a FROM t1 WHERE a > ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+3
+SELECT a FROM t1 WHERE a < ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+SELECT a FROM t1 WHERE a = ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+SELECT a FROM t1 WHERE a >= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL ( SELECT a FROM t1 WHERE b = 2 );
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 UNION SELECT a FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 HAVING a = 2 UNION SELECT a FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE a > ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE a > ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) > ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) <> ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT a FROM t1 WHERE a = ANY (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) = ANY (SELECT a,2 FROM t1 WHERE b = 2);
+a
+SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 2 column(s)
+SELECT a FROM t1 WHERE a <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
+ERROR 21000: Operand should contain 1 column(s)
+SELECT a FROM t1 WHERE (1,2) <> ALL (SELECT a,2 FROM t1 WHERE b = 2);
+a
+1
+2
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 WHERE b = 2 UNION SELECT a,1 FROM t1 WHERE b = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE (a,1) = ANY (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE (a,1) <> ALL (SELECT a,1 FROM t1 HAVING a = 2 UNION SELECT a,1 FROM t1 HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2 group by a);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 group by a HAVING a = 2);
+a
+1
+3
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a > t1.a), '-')
+0-
+0-
+1-
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a < t1.a), '-')
+1-
+0-
+0-
+SELECT concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-') from t1 a;
+concat(EXISTS(SELECT a FROM t1 WHERE b = 2 and a.a = t1.a), '-')
+0-
+1-
+0-
+DROP TABLE t1;
+CREATE TABLE t1 ( a double, b double );
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3);
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = 2e0);
+a
+1
+3
+DROP TABLE t1;
+CREATE TABLE t1 ( a char(1), b char(1));
+INSERT INTO t1 VALUES ('1','1'),('2','2'),('3','3');
+SELECT a FROM t1 WHERE a > ANY (SELECT a FROM t1 WHERE b = '2');
+a
+3
+SELECT a FROM t1 WHERE a < ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+SELECT a FROM t1 WHERE a = ANY (SELECT a FROM t1 WHERE b = '2');
+a
+2
+SELECT a FROM t1 WHERE a >= ANY (SELECT a FROM t1 WHERE b = '2');
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ANY (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+SELECT a FROM t1 WHERE a > ALL (SELECT a FROM t1 WHERE b = '2');
+a
+3
+SELECT a FROM t1 WHERE a < ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+SELECT a FROM t1 WHERE a = ALL (SELECT a FROM t1 WHERE b = '2');
+a
+2
+SELECT a FROM t1 WHERE a >= ALL (SELECT a FROM t1 WHERE b = '2');
+a
+2
+3
+SELECT a FROM t1 WHERE a <= ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+2
+SELECT a FROM t1 WHERE a <> ALL (SELECT a FROM t1 WHERE b = '2');
+a
+1
+3
+DROP TABLE t1;
+create table t1 (a int, b int);
+insert into t1 values (1,2),(3,4);
+select * from t1 up where exists (select * from t1 where t1.a=up.a);
+a b
+1 2
+3 4
+explain extended select * from t1 up where exists (select * from t1 where t1.a=up.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY up ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.up.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`up`.`a` AS `a`,`test`.`up`.`b` AS `b` from `test`.`t1` `up` where exists(select 1 from `test`.`t1` where (`test`.`t1`.`a` = `test`.`up`.`a`))
+drop table t1;
+CREATE TABLE t1 (t1_a int);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (t2_a int, t2_b int, PRIMARY KEY (t2_a, t2_b));
+INSERT INTO t2 VALUES (1, 1), (1, 2);
+SELECT * FROM t1, t2 table2 WHERE t1_a = 1 AND table2.t2_a = 1
+HAVING table2.t2_b = (SELECT MAX(t2_b) FROM t2 WHERE t2_a = table2.t2_a);
+t1_a t2_a t2_b
+1 1 2
+DROP TABLE t1, t2;
+CREATE TABLE t1 (id int(11) default NULL,name varchar(10) default NULL);
+INSERT INTO t1 VALUES (1,'Tim'),(2,'Rebecca'),(3,NULL);
+CREATE TABLE t2 (id int(11) default NULL, pet varchar(10) default NULL);
+INSERT INTO t2 VALUES (1,'Fido'),(2,'Spot'),(3,'Felix');
+SELECT a.*, b.* FROM (SELECT * FROM t1) AS a JOIN t2 as b on a.id=b.id;
+id name id pet
+1 Tim 1 Fido
+2 Rebecca 2 Spot
+3 NULL 3 Felix
+drop table t1,t2;
+CREATE TABLE t1 ( a int, b int );
+CREATE TABLE t2 ( c int, d int );
+INSERT INTO t1 VALUES (1,2), (2,3), (3,4);
+SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+abc b
+1 2
+2 3
+3 4
+INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+select * from t2;
+c d
+1 2
+2 3
+3 4
+CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b =
+(SELECT MIN(b) FROM t1 WHERE a=outr.a);
+select * from t3;
+abc b
+1 2
+2 3
+3 4
+prepare stmt1 from "INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
+execute stmt1;
+deallocate prepare stmt1;
+select * from t2;
+c d
+1 2
+2 3
+3 4
+1 2
+2 3
+3 4
+drop table t3;
+prepare stmt1 from "CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = (SELECT MIN(b) FROM t1 WHERE a=outr.a);";
+execute stmt1;
+select * from t3;
+abc b
+1 2
+2 3
+3 4
+deallocate prepare stmt1;
+DROP TABLE t1, t2, t3;
+CREATE TABLE `t1` ( `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t1 values (1);
+CREATE TABLE `t2` ( `b` int(11) default NULL, `a` int(11) default NULL) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+insert into t2 values (1,2);
+select t000.a, count(*) `C` FROM t1 t000 GROUP BY t000.a HAVING count(*) > ALL (SELECT count(*) FROM t2 t001 WHERE t001.a=1);
+a C
+1 1
+drop table t1,t2;
+create table t1 (a int not null auto_increment primary key, b varchar(40), fulltext(b));
+insert into t1 (b) values ('ball'),('ball games'), ('games'), ('foo'), ('foobar'), ('Serg'), ('Sergei'),('Georg'), ('Patrik'),('Hakan');
+create table t2 (a int);
+insert into t2 values (1),(3),(2),(7);
+select a,b from t1 where match(b) against ('Ball') > 0;
+a b
+1 ball
+2 ball games
+select a from t2 where a in (select a from t1 where match(b) against ('Ball') > 0);
+a
+1
+2
+drop table t1,t2;
+CREATE TABLE t1(`IZAVORGANG_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`KUERZEL` VARCHAR(10) CHARACTER SET latin1 COLLATE latin1_bin,`IZAANALYSEART_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin,`IZAPMKZ_ID` VARCHAR(11) CHARACTER SET latin1 COLLATE latin1_bin);
+CREATE INDEX AK01IZAVORGANG ON t1(izaAnalyseart_id,Kuerzel);
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000001','601','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000002','602','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000003','603','D0000000001','I0000000001');
+INSERT INTO t1(`IZAVORGANG_ID`,`KUERZEL`,`IZAANALYSEART_ID`,`IZAPMKZ_ID`)VALUES('D0000000004','101','D0000000001','I0000000001');
+SELECT `IZAVORGANG_ID` FROM t1 WHERE `KUERZEL` IN(SELECT MIN(`KUERZEL`)`Feld1` FROM t1 WHERE `KUERZEL` LIKE'601%'And`IZAANALYSEART_ID`='D0000000001');
+IZAVORGANG_ID
+D0000000001
+drop table t1;
+CREATE TABLE `t1` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
+CREATE TABLE `t2` ( `aid` int(11) NOT NULL default '0', `bid` int(11) NOT NULL default '0', PRIMARY KEY (`aid`,`bid`));
+insert into t1 values (1,1),(1,2),(2,1),(2,2);
+insert into t2 values (1,2),(2,2);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+alter table t2 drop primary key;
+alter table t2 add key KEY1 (aid, bid);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+alter table t2 drop key KEY1;
+alter table t2 add primary key (bid, aid);
+select * from t1 where t1.aid not in (select aid from t2 where bid=t1.bid);
+aid bid
+1 1
+2 1
+drop table t1,t2;
+CREATE TABLE t1 (howmanyvalues bigint, avalue int);
+INSERT INTO t1 VALUES (1, 1),(2, 1),(2, 2),(3, 1),(3, 2),(3, 3),(4, 1),(4, 2),(4, 3),(4, 4);
+SELECT howmanyvalues, count(*) from t1 group by howmanyvalues;
+howmanyvalues count(*)
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+CREATE INDEX t1_howmanyvalues_idx ON t1 (howmanyvalues);
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues+1 = a.howmanyvalues+1) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.howmanyvalues) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 2
+3 3
+4 4
+SELECT a.howmanyvalues, (SELECT count(*) from t1 b where b.howmanyvalues = a.avalue) as mycount from t1 a group by a.howmanyvalues;
+howmanyvalues mycount
+1 1
+2 1
+3 1
+4 1
+drop table t1;
+create table t1 (x int);
+select (select b.x from t1 as b where b.x=a.x) from t1 as a where a.x=2 group by a.x;
+(select b.x from t1 as b where b.x=a.x)
+drop table t1;
+CREATE TABLE `t1` ( `master` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `slave` int(10) unsigned NOT NULL default '0', `access` int(10) unsigned NOT NULL default '0', UNIQUE KEY `access_u` (`master`,`map`,`slave`));
+INSERT INTO `t1` VALUES (1,0,0,700),(1,1,1,400),(1,5,5,400),(1,12,12,400),(1,12,32,400),(4,12,32,400);
+CREATE TABLE `t2` ( `id` int(10) unsigned NOT NULL default '0', `pid` int(10) unsigned NOT NULL default '0', `map` smallint(6) unsigned NOT NULL default '0', `level` tinyint(4) unsigned NOT NULL default '0', `title` varchar(255) default NULL, PRIMARY KEY (`id`,`pid`,`map`), KEY `level` (`level`), KEY `id` (`id`,`map`)) ;
+INSERT INTO `t2` VALUES (6,5,12,7,'a'),(12,0,0,7,'a'),(12,1,0,7,'a'),(12,5,5,7,'a'),(12,5,12,7,'a');
+SELECT b.sc FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
+ERROR 42S22: Unknown column 'b.sc' in 'field list'
+SELECT b.ac FROM (SELECT (SELECT a.access FROM t1 a WHERE a.map = op.map AND a.slave = op.pid AND a.master = 1) ac FROM t2 op WHERE op.id = 12 AND op.map = 0) b;
+ac
+700
+NULL
+drop tables t1,t2;
+create table t1 (a int not null, b int not null, c int, primary key (a,b));
+insert into t1 values (1,1,1), (2,2,2), (3,3,3);
+set @b:= 0;
+explain select sum(a) from t1 where b > @b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index NULL PRIMARY 8 NULL 3 Using where; Using index
+set @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+do @a:= (select sum(a) from t1 where b > @b);
+explain select a from t1 where c=2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
+drop table t1;
+set @got_val= (SELECT 1 FROM (SELECT 'A' as my_col) as T1 ) ;
+create table t1 (a int, b int);
+create table t2 (a int, b int);
+insert into t1 values (1,1),(1,2),(1,3),(2,4),(2,5);
+insert into t2 values (1,3),(2,1);
+select distinct a,b, (select max(b) from t2 where t1.b=t2.a) from t1 order by t1.b;
+a b (select max(b) from t2 where t1.b=t2.a)
+1 1 3
+1 2 1
+1 3 NULL
+2 4 NULL
+2 5 NULL
+drop table t1, t2;
+create table t1 (id int);
+create table t2 (id int, body text, fulltext (body));
+insert into t1 values(1),(2),(3);
+insert into t2 values (1,'test'), (2,'mysql'), (3,'test'), (4,'test');
+select count(distinct id) from t1 where id in (select id from t2 where match(body) against ('mysql' in boolean mode));
+count(distinct id)
+1
+drop table t2,t1;
+create table t1 (s1 int,s2 int);
+insert into t1 values (20,15);
+select * from t1 where (('a',null) <=> (select 'a',s2 from t1 where s1 = 0));
+s1 s2
+drop table t1;
+create table t1 (s1 int);
+insert into t1 values (1),(null);
+select * from t1 where s1 < all (select s1 from t1);
+s1
+select s1, s1 < all (select s1 from t1) from t1;
+s1 s1 < all (select s1 from t1)
+1 0
+NULL NULL
+drop table t1;
+CREATE TABLE t1 (
+Code char(3) NOT NULL default '',
+Name char(52) NOT NULL default '',
+Continent enum('Asia','Europe','North America','Africa','Oceania','Antarctica','South America') NOT NULL default 'Asia',
+Region char(26) NOT NULL default '',
+SurfaceArea float(10,2) NOT NULL default '0.00',
+IndepYear smallint(6) default NULL,
+Population int(11) NOT NULL default '0',
+LifeExpectancy float(3,1) default NULL,
+GNP float(10,2) default NULL,
+GNPOld float(10,2) default NULL,
+LocalName char(45) NOT NULL default '',
+GovernmentForm char(45) NOT NULL default '',
+HeadOfState char(60) default NULL,
+Capital int(11) default NULL,
+Code2 char(2) NOT NULL default ''
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('XXX','Xxxxx','Oceania','Xxxxxx',26.00,0,0,0,0,0,'Xxxxx','Xxxxx','Xxxxx',NULL,'XX');
+INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,68000,75.1,334.00,NULL,'Amerika Samoa','US Territory','George W. Bush',54,'AS');
+INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
+INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
+/*!40000 ALTER TABLE t1 ENABLE KEYS */;
+SELECT DISTINCT Continent AS c FROM t1 outr WHERE
+Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND
+Population < 200);
+c
+Oceania
+drop table t1;
+create table t1 (a1 int);
+create table t2 (b1 int);
+select * from t1 where a2 > any(select b1 from t2);
+ERROR 42S22: Unknown column 'a2' in 'IN/ALL/ANY subquery'
+select * from t1 where a1 > any(select b1 from t2);
+a1
+drop table t1,t2;
+create table t1 (a integer, b integer);
+select (select * from t1) = (select 1,2);
+(select * from t1) = (select 1,2)
+NULL
+select (select 1,2) = (select * from t1);
+(select 1,2) = (select * from t1)
+NULL
+select row(1,2) = ANY (select * from t1);
+row(1,2) = ANY (select * from t1)
+0
+select row(1,2) != ALL (select * from t1);
+row(1,2) != ALL (select * from t1)
+1
+drop table t1;
+create table t1 (a integer, b integer);
+select row(1,(2,2)) in (select * from t1 );
+ERROR 21000: Operand should contain 2 column(s)
+select row(1,(2,2)) = (select * from t1 );
+ERROR 21000: Operand should contain 2 column(s)
+select (select * from t1) = row(1,(2,2));
+ERROR 21000: Operand should contain 1 column(s)
+drop table t1;
+create table t1 (a integer);
+insert into t1 values (1);
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx ;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 as xx, 1 = ALL ( select 1 from t1 where 1 = xx );
+xx 1 = ALL ( select 1 from t1 where 1 = xx )
+1 1
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+select 1 = ALL (select 1 from t1 where 1 = xx ), 1 as xx from DUAL;
+ERROR 42S22: Reference 'xx' not supported (forward reference in item list)
+drop table t1;
+CREATE TABLE t1 (
+categoryId int(11) NOT NULL,
+courseId int(11) NOT NULL,
+startDate datetime NOT NULL,
+endDate datetime NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL,
+attributes text NOT NULL
+);
+INSERT INTO t1 VALUES (1,41,'2004-02-09','2010-01-01','2004-02-09','2004-02-09',''),
+(1,86,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(1,87,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(2,52,'2004-03-15','2004-10-01','2004-03-15','2004-09-17',''),
+(2,53,'2004-03-16','2004-10-01','2004-03-16','2004-09-17',''),
+(2,88,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(2,89,'2004-08-16','2004-08-16','2004-08-16','2004-08-16',''),
+(3,51,'2004-02-09','2010-01-01','2004-02-09','2004-02-09',''),
+(5,12,'2004-02-18','2010-01-01','2004-02-18','2004-02-18','');
+CREATE TABLE t2 (
+userId int(11) NOT NULL,
+courseId int(11) NOT NULL,
+date datetime NOT NULL
+);
+INSERT INTO t2 VALUES (5141,71,'2003-11-18'),
+(5141,72,'2003-11-25'),(5141,41,'2004-08-06'),
+(5141,52,'2004-08-06'),(5141,53,'2004-08-06'),
+(5141,12,'2004-08-06'),(5141,86,'2004-10-21'),
+(5141,87,'2004-10-21'),(5141,88,'2004-10-21'),
+(5141,89,'2004-10-22'),(5141,51,'2004-10-26');
+CREATE TABLE t3 (
+groupId int(11) NOT NULL,
+parentId int(11) NOT NULL,
+startDate datetime NOT NULL,
+endDate datetime NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL,
+ordering int(11)
+);
+INSERT INTO t3 VALUES (12,9,'1000-01-01','3999-12-31','2004-01-29','2004-01-29',NULL);
+CREATE TABLE t4 (
+id int(11) NOT NULL,
+groupTypeId int(11) NOT NULL,
+groupKey varchar(50) NOT NULL,
+name text,
+ordering int(11),
+description text,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL
+);
+INSERT INTO t4 VALUES (9,5,'stationer','stationer',0,'Stationer','2004-01-29','2004-01-29'),
+(12,5,'group2','group2',0,'group2','2004-01-29','2004-01-29');
+CREATE TABLE t5 (
+userId int(11) NOT NULL,
+groupId int(11) NOT NULL,
+createDate datetime NOT NULL,
+modifyDate timestamp NOT NULL
+);
+INSERT INTO t5 VALUES (5141,12,'2004-08-06','2004-08-06');
+select
+count(distinct t2.userid) pass,
+groupstuff.*,
+count(t2.courseid) crse,
+t1.categoryid,
+t2.courseid,
+date_format(date, '%b%y') as colhead
+from t2
+join t1 on t2.courseid=t1.courseid
+join
+(
+select
+t5.userid,
+parentid,
+parentgroup,
+childid,
+groupname,
+grouptypeid
+from t5
+join
+(
+select t4.id as parentid,
+t4.name as parentgroup,
+t4.id as childid,
+t4.name as groupname,
+t4.grouptypeid
+from t4
+) as gin on t5.groupid=gin.childid
+) as groupstuff on t2.userid = groupstuff.userid
+group by
+groupstuff.groupname, colhead , t2.courseid;
+pass userid parentid parentgroup childid groupname grouptypeid crse categoryid courseid colhead
+1 5141 12 group2 12 group2 5 1 5 12 Aug04
+1 5141 12 group2 12 group2 5 1 1 41 Aug04
+1 5141 12 group2 12 group2 5 1 2 52 Aug04
+1 5141 12 group2 12 group2 5 1 2 53 Aug04
+1 5141 12 group2 12 group2 5 1 3 51 Oct04
+1 5141 12 group2 12 group2 5 1 1 86 Oct04
+1 5141 12 group2 12 group2 5 1 1 87 Oct04
+1 5141 12 group2 12 group2 5 1 2 88 Oct04
+1 5141 12 group2 12 group2 5 1 2 89 Oct04
+drop table t1, t2, t3, t4, t5;
+create table t1 (a int);
+insert into t1 values (1), (2), (3);
+SELECT 1 FROM t1 WHERE (SELECT 1) in (SELECT 1);
+1
+1
+1
+1
+drop table t1;
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(2);
+insert into t2 values (0),(1),(2),(3);
+select a from t2 where a in (select a from t1);
+a
+1
+2
+select a from t2 having a in (select a from t1);
+a
+1
+2
+prepare stmt1 from "select a from t2 where a in (select a from t1)";
+execute stmt1;
+a
+1
+2
+execute stmt1;
+a
+1
+2
+deallocate prepare stmt1;
+prepare stmt1 from "select a from t2 having a in (select a from t1)";
+execute stmt1;
+a
+1
+2
+execute stmt1;
+a
+1
+2
+deallocate prepare stmt1;
+drop table t1, t2;
+create table t1 (a int, b int);
+insert into t1 values (1,2);
+select 1 = (select * from t1);
+ERROR 21000: Operand should contain 1 column(s)
+select (select * from t1) = 1;
+ERROR 21000: Operand should contain 2 column(s)
+select (1,2) = (select a from t1);
+ERROR 21000: Operand should contain 2 column(s)
+select (select a from t1) = (1,2);
+ERROR 21000: Operand should contain 1 column(s)
+select (1,2,3) = (select * from t1);
+ERROR 21000: Operand should contain 3 column(s)
+select (select * from t1) = (1,2,3);
+ERROR 21000: Operand should contain 2 column(s)
+drop table t1;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+CREATE TABLE t1 (one int, two int, flag char(1));
+CREATE TABLE t2 (one int, two int, flag char(1));
+INSERT INTO t1 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+INSERT INTO t2 VALUES(1,2,'Y'),(2,3,'Y'),(3,4,'Y'),(5,6,'N'),(7,8,'N');
+SELECT * FROM t1
+WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t2 WHERE flag = 'N');
+one two flag
+5 6 N
+7 8 N
+SELECT * FROM t1
+WHERE ROW(one,two) IN (SELECT DISTINCT one,two FROM t1 WHERE flag = 'N');
+one two flag
+5 6 N
+7 8 N
+insert into t2 values (null,null,'N');
+insert into t2 values (null,3,'0');
+insert into t2 values (null,5,'0');
+insert into t2 values (10,null,'0');
+insert into t1 values (10,3,'0');
+insert into t1 values (10,5,'0');
+insert into t1 values (10,10,'0');
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N') as 'test' from t1;
+one two test
+1 2 NULL
+2 3 NULL
+3 4 NULL
+5 6 1
+7 8 1
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
+one two
+5 6
+7 8
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N' group by one,two) as 'test' from t1;
+one two test
+1 2 NULL
+2 3 NULL
+3 4 NULL
+5 6 1
+7 8 1
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0') as 'test' from t1;
+one two test
+1 2 0
+2 3 NULL
+3 4 0
+5 6 0
+7 8 0
+10 3 NULL
+10 5 NULL
+10 10 NULL
+SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0' group by one,two) as 'test' from t1;
+one two test
+1 2 0
+2 3 NULL
+3 4 0
+5 6 0
+7 8 0
+10 3 NULL
+10 5 NULL
+10 10 NULL
+explain extended SELECT one,two,ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = '0') 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
+2 DEPENDENT SUBQUERY 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`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
+explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
+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'))
+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
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; Using temporary
+Warnings:
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`))))) AS `test` from `test`.`t1`
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a char(5), b char(5));
+INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
+SELECT * FROM t1 WHERE (a,b) IN (('aaa','aaa'), ('aaa','bbb'));
+a b
+aaa aaa
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int, b int);
+CREATE TABLE t3 (b int NOT NULL);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (1,10), (3,30);
+SELECT * FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10;
+a b b
+SELECT * FROM t1
+WHERE t1.a NOT IN (SELECT a FROM t2 LEFT JOIN t3 ON t2.b=t3.b
+WHERE t3.b IS NOT NULL OR t2.a > 10);
+a
+1
+2
+3
+4
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (f1 INT);
+CREATE TABLE t2 (f2 INT);
+INSERT INTO t1 VALUES (1);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2);
+f1
+1
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE 1=0);
+f1
+1
+INSERT INTO t2 VALUES (1);
+INSERT INTO t2 VALUES (2);
+SELECT * FROM t1 WHERE f1 > ALL (SELECT f2 FROM t2 WHERE f2=0);
+f1
+1
+DROP TABLE t1, t2;
+select 1 from dual where 1 < any (select 2);
+1
+1
+select 1 from dual where 1 < all (select 2);
+1
+1
+select 1 from dual where 2 > any (select 1);
+1
+1
+select 1 from dual where 2 > all (select 1);
+1
+1
+select 1 from dual where 1 < any (select 2 from dual);
+1
+1
+select 1 from dual where 1 < all (select 2 from dual where 1!=1);
+1
+1
+create table t1 (s1 char);
+insert into t1 values (1),(2);
+select * from t1 where (s1 < any (select s1 from t1));
+s1
+1
+select * from t1 where not (s1 < any (select s1 from t1));
+s1
+2
+select * from t1 where (s1 < ALL (select s1+1 from t1));
+s1
+1
+select * from t1 where not(s1 < ALL (select s1+1 from t1));
+s1
+2
+select * from t1 where (s1+1 = ANY (select s1 from t1));
+s1
+1
+select * from t1 where NOT(s1+1 = ANY (select s1 from t1));
+s1
+2
+select * from t1 where (s1 = ALL (select s1/s1 from t1));
+s1
+1
+select * from t1 where NOT(s1 = ALL (select s1/s1 from t1));
+s1
+2
+drop table t1;
+create table t1 (
+retailerID varchar(8) NOT NULL,
+statusID int(10) unsigned NOT NULL,
+changed datetime NOT NULL,
+UNIQUE KEY retailerID (retailerID, statusID, changed)
+);
+INSERT INTO t1 VALUES("0026", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0026", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0037", "1", "2005-12-06 12:18:56");
+INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53");
+INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50");
+INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50");
+select * from t1 r1
+where (r1.retailerID,(r1.changed)) in
+(SELECT r2.retailerId,(max(changed)) from t1 r2
+group by r2.retailerId);
+retailerID statusID changed
+0026 2 2006-01-06 12:25:53
+0037 2 2006-01-06 12:25:53
+0048 1 2006-01-06 12:37:50
+0059 1 2006-01-06 12:37:50
+drop table t1;
+create table t1(a int, primary key (a));
+insert into t1 values (10);
+create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b));
+insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989');
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
+a a b
+10 3 35989
+explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
+2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
+SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
+ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
+ ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
+a a b
+10 1 359
+drop table t1,t2;
+CREATE TABLE t1 (
+field1 int NOT NULL,
+field2 int NOT NULL,
+field3 int NOT NULL,
+PRIMARY KEY (field1,field2,field3)
+);
+CREATE TABLE t2 (
+fieldA int NOT NULL,
+fieldB int NOT NULL,
+PRIMARY KEY (fieldA,fieldB)
+);
+INSERT INTO t1 VALUES
+(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
+INSERT INTO t2 VALUES (1,1), (1,2), (1,3);
+SELECT field1, field2, COUNT(*)
+FROM t1 GROUP BY field1, field2;
+field1 field2 COUNT(*)
+1 1 2
+1 2 3
+1 3 1
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) >= ALL (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 2
+SELECT field1, field2
+FROM t1
+GROUP BY field1, field2
+HAVING COUNT(*) < ANY (SELECT fieldB
+FROM t2 WHERE fieldA = field1);
+field1 field2
+1 1
+1 3
+DROP TABLE t1, t2;
+CREATE TABLE t1(a int, INDEX (a));
+INSERT INTO t1 VALUES (1), (3), (5), (7);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES (1),(2),(3);
+EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 3
+2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 2 Using index; Full scan on NULL key
+SELECT a, a IN (SELECT a FROM t1) FROM t2;
+a a IN (SELECT a FROM t1)
+1 1
+2 NULL
+3 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a DATETIME);
+INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
+CREATE TABLE t2 AS SELECT
+(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a
+FROM t1 WHERE a > '2000-01-01';
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `sub_a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) > 0;
+a
+SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+a
+1
+2
+EXPLAIN SELECT a FROM t1 WHERE (SELECT 1 FROM DUAL WHERE 1=0) IS NULL;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
+DROP TABLE t1;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (2), (4), (1), (3);
+CREATE TABLE t2 (b int, c int);
+INSERT INTO t2 VALUES
+(2,1), (1,3), (2,1), (4,4), (2,2), (1,4);
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2 );
+a
+2
+4
+1
+3
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 2), a;
+a
+1
+2
+3
+4
+SELECT a FROM t1 ORDER BY (SELECT c FROM t2 WHERE b > 1), a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 2);
+b MAX(c)
+1 4
+2 2
+4 4
+SELECT b, MAX(c) FROM t2 GROUP BY b, (SELECT c FROM t2 WHERE b > 1);
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+1
+2
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b)) > 3;
+a
+4
+SELECT a FROM t1 GROUP BY a
+HAVING IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b)) > 3;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 2),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+1
+2
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 1),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 2 ORDER BY b));
+a
+1
+2
+3
+4
+SELECT a FROM t1
+ORDER BY IFNULL((SELECT b FROM t2 WHERE b > 4),
+(SELECT c FROM t2 WHERE c=a AND b > 1 ORDER BY b));
+ERROR 21000: Subquery returns more than 1 row
+DROP TABLE t1,t2;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+insert into t1 values(2.2);
+select * from t1 where df <= all (select avg(df) from t1 group by df);
+df
+1.1
+select * from t1 where df >= all (select avg(df) from t1 group by df);
+df
+2.2
+drop table t1;
+create table t1 (df decimal(5,1));
+insert into t1 values(1.1);
+select 1.1 * exists(select * from t1);
+1.1 * exists(select * from t1)
+1.1
+drop table t1;
+CREATE TABLE t1 (
+grp int(11) default NULL,
+a decimal(10,2) default NULL);
+insert into t1 values (1, 1), (2, 2), (2, 3), (3, 4), (3, 5), (3, 6), (NULL, NULL);
+select * from t1;
+grp a
+1 1.00
+2 2.00
+2 3.00
+3 4.00
+3 5.00
+3 6.00
+NULL NULL
+select min(a) from t1 group by grp;
+min(a)
+NULL
+1.00
+2.00
+4.00
+drop table t1;
+CREATE table t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2 WHERE c2 IN (1);
+c1 c2
+1 1
+SELECT * FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE c2 IN ( SELECT c2 FROM t2 WHERE c2 IN ( 1 ) );
+c1 c2
+1 1
+DROP TABLE t1,t2;
+CREATE TABLE t1 ( c1 integer );
+INSERT INTO t1 VALUES ( 1 );
+INSERT INTO t1 VALUES ( 2 );
+INSERT INTO t1 VALUES ( 3 );
+INSERT INTO t1 VALUES ( 6 );
+CREATE TABLE t2 ( c2 integer );
+INSERT INTO t2 VALUES ( 1 );
+INSERT INTO t2 VALUES ( 4 );
+INSERT INTO t2 VALUES ( 5 );
+INSERT INTO t2 VALUES ( 6 );
+CREATE TABLE t3 ( c3 integer );
+INSERT INTO t3 VALUES ( 7 );
+INSERT INTO t3 VALUES ( 8 );
+SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2
+WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL );
+c1 c2
+2 NULL
+3 NULL
+DROP TABLE t1,t2,t3;
+CREATE TABLE `t1` (
+`itemid` bigint(20) unsigned NOT NULL auto_increment,
+`sessionid` bigint(20) unsigned default NULL,
+`time` int(10) unsigned NOT NULL default '0',
+`type` set('A','D','E','F','G','I','L','N','U') collate latin1_general_ci NOT
+NULL default '',
+`data` text collate latin1_general_ci NOT NULL,
+PRIMARY KEY (`itemid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t1` VALUES (1, 1, 1, 'D', '');
+CREATE TABLE `t2` (
+`sessionid` bigint(20) unsigned NOT NULL auto_increment,
+`pid` int(10) unsigned NOT NULL default '0',
+`date` int(10) unsigned NOT NULL default '0',
+`ip` varchar(15) collate latin1_general_ci NOT NULL default '',
+PRIMARY KEY (`sessionid`)
+) DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO `t2` VALUES (1, 1, 1, '10.10.10.1');
+SELECT s.ip, count( e.itemid ) FROM `t1` e JOIN t2 s ON s.sessionid = e.sessionid WHERE e.sessionid = ( SELECT sessionid FROM t2 ORDER BY sessionid DESC LIMIT 1 ) GROUP BY s.ip HAVING count( e.itemid ) >0 LIMIT 0 , 30;
+ip count( e.itemid )
+10.10.10.1 1
+drop tables t1,t2;
+CREATE TABLE t1 (EMPNUM CHAR(3));
+CREATE TABLE t2 (EMPNUM CHAR(3) );
+INSERT INTO t1 VALUES ('E1'),('E2');
+INSERT INTO t2 VALUES ('E1');
+DELETE FROM t1
+WHERE t1.EMPNUM NOT IN
+(SELECT t2.EMPNUM
+FROM t2
+WHERE t1.EMPNUM = t2.EMPNUM);
+select * from t1;
+EMPNUM
+E1
+DROP TABLE t1,t2;
+CREATE TABLE t1(select_id BIGINT, values_id BIGINT);
+INSERT INTO t1 VALUES (1, 1);
+CREATE TABLE t2 (select_id BIGINT, values_id BIGINT,
+PRIMARY KEY(select_id,values_id));
+INSERT INTO t2 VALUES (0, 1), (0, 2), (0, 3), (1, 5);
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id IN (1, 0));
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id BETWEEN 0 AND 1);
+values_id
+1
+SELECT values_id FROM t1
+WHERE values_id IN (SELECT values_id FROM t2
+WHERE select_id = 0 OR select_id = 1);
+values_id
+1
+DROP TABLE t1, t2;
+create table t1 (fld enum('0','1'));
+insert into t1 values ('1');
+select * from (select max(fld) from t1) as foo;
+max(fld)
+1
+drop table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (c int, d int);
+CREATE TABLE t3 (e int);
+INSERT INTO t1 VALUES
+(1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40);
+INSERT INTO t2 VALUES
+(2,10), (2,20), (4,10), (5,10), (3,20), (2,40);
+INSERT INTO t3 VALUES (10), (30), (10), (20) ;
+SELECT a, MAX(b), MIN(b) FROM t1 GROUP BY a;
+a MAX(b) MIN(b)
+1 20 10
+2 30 10
+3 20 20
+4 40 40
+SELECT * FROM t2;
+c d
+2 10
+2 20
+4 10
+5 10
+3 20
+2 40
+SELECT * FROM t3;
+e
+10
+30
+10
+20
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>20);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)<d);
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2 WHERE MAX(b)>d);
+a
+2
+4
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d >= SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+3
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE d > SOME(SELECT e FROM t3 WHERE MAX(b)=e));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e < d));
+a
+2
+SELECT a FROM t1 GROUP BY a
+HAVING a IN (SELECT c FROM t2
+WHERE MIN(b) < d AND
+EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
+a
+2
+SELECT a, SUM(a) FROM t1 GROUP BY a;
+a SUM(a)
+1 2
+2 6
+3 3
+4 4
+SELECT a FROM t1
+WHERE EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c) GROUP BY a;
+a
+3
+4
+SELECT a FROM t1 GROUP BY a
+HAVING EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) = c);
+a
+1
+3
+4
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c) GROUP BY a;
+a
+1
+2
+SELECT a FROM t1
+WHERE a < 3 AND
+EXISTS(SELECT c FROM t2 GROUP BY c HAVING SUM(a) != c);
+a
+1
+2
+1
+2
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a < ALL(SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+1
+2
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3 GROUP BY t3.e
+HAVING SUM(t1.a+t2.c) < t3.e/4));
+a
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a > ALL(SELECT t2.c FROM t2
+WHERE EXISTS(SELECT t3.e FROM t3
+WHERE SUM(t1.a+t2.c) < t3.e/4));
+ERROR HY000: Invalid use of group function
+SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20;
+ERROR HY000: Invalid use of group function
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(t2.c+SUM(t1.b)) > 20);
+a
+2
+3
+4
+SELECT t1.a FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING AVG(SUM(t1.b)) > 20);
+a
+2
+4
+SELECT t1.a, SUM(b) AS sum FROM t1 GROUP BY t1.a
+HAVING t1.a IN (SELECT t2.c FROM t2 GROUP BY t2.c
+HAVING t2.c+sum > 20);
+a sum
+2 60
+3 20
+4 40
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a varchar(5), b varchar(10));
+INSERT INTO t1 VALUES
+('AAA', 5), ('BBB', 4), ('BBB', 1), ('CCC', 2),
+('CCC', 7), ('AAA', 2), ('AAA', 4), ('BBB', 3), ('AAA', 8);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary
+ALTER TABLE t1 ADD INDEX(a);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a b
+BBB 4
+CCC 7
+AAA 8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
+2 DEPENDENT SUBQUERY t1 index NULL a 8 NULL 1
+DROP TABLE t1;
+create table t1( f1 int,f2 int);
+insert into t1 values (1,1),(2,2);
+select tt.t from (select 'crash1' as t, f2 from t1) as tt left join t1 on tt.t = 'crash2' and tt.f2 = t1.f2 where tt.t = 'crash1';
+t
+crash1
+crash1
+drop table t1;
+create table t1 (c int, key(c));
+insert into t1 values (1142477582), (1142455969);
+create table t2 (a int, b int);
+insert into t2 values (2, 1), (1, 0);
+delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery'
+DROP TABLE t1;
+create table t1 (i int, j bigint);
+insert into t1 values (1, 2), (2, 2), (3, 2);
+select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
+min(i)
+1
+drop table t1;
+CREATE TABLE t1 (i BIGINT UNSIGNED);
+INSERT INTO t1 VALUES (10000000000000000000);
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 (i BIGINT UNSIGNED);
+INSERT INTO t2 VALUES (10000000000000000000);
+INSERT INTO t2 VALUES (1);
+/* simple test */
+SELECT t1.i FROM t1 JOIN t2 ON t1.i = t2.i;
+i
+10000000000000000000
+1
+/* subquery test */
+SELECT t1.i FROM t1 WHERE t1.i = (SELECT MAX(i) FROM t2);
+i
+10000000000000000000
+/* subquery test with cast*/
+SELECT t1.i FROM t1 WHERE t1.i = CAST((SELECT MAX(i) FROM t2) AS UNSIGNED);
+i
+10000000000000000000
+DROP TABLE t1;
+DROP TABLE t2;
+CREATE TABLE t1 (
+id bigint(20) unsigned NOT NULL auto_increment,
+name varchar(255) NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t1 VALUES
+(1, 'Balazs'), (2, 'Joe'), (3, 'Frank');
+CREATE TABLE t2 (
+id bigint(20) unsigned NOT NULL auto_increment,
+mid bigint(20) unsigned NOT NULL,
+date date NOT NULL,
+PRIMARY KEY (id)
+);
+INSERT INTO t2 VALUES
+(1, 1, '2006-03-30'), (2, 2, '2006-04-06'), (3, 3, '2006-04-13'),
+(4, 2, '2006-04-20'), (5, 1, '2006-05-01');
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 3, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 NULL
+2 Joe 2006-04-20 NULL
+3 Frank 2006-04-13 NULL
+SELECT *,
+(SELECT COUNT(*) FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_count
+FROM t1;
+id name date_count
+1 Balazs NULL
+2 Joe NULL
+3 Frank NULL
+SELECT *,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 0, 1) AS date_last,
+(SELECT date FROM t2 WHERE mid = t1.id
+ORDER BY date DESC LIMIT 1, 1) AS date_next_to_last
+FROM t1;
+id name date_last date_next_to_last
+1 Balazs 2006-05-01 2006-03-30
+2 Joe 2006-04-20 2006-04-06
+3 Frank 2006-04-13 NULL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime NOT NULL default '0000-00-00 00:00:00',
+PRIMARY KEY (i1,i2,t)
+);
+INSERT INTO t1 VALUES
+(24,1,'2005-03-03 16:31:31'),(24,1,'2005-05-27 12:40:07'),
+(24,1,'2005-05-27 12:40:08'),(24,1,'2005-05-27 12:40:10'),
+(24,1,'2005-05-27 12:40:25'),(24,1,'2005-05-27 12:40:30'),
+(24,2,'2005-03-03 13:43:05'),(24,2,'2005-03-03 16:23:31'),
+(24,2,'2005-03-03 16:31:30'),(24,2,'2005-05-27 12:37:02'),
+(24,2,'2005-05-27 12:40:06');
+CREATE TABLE t2 (
+i1 int(11) NOT NULL default '0',
+i2 int(11) NOT NULL default '0',
+t datetime default NULL,
+PRIMARY KEY (i1)
+);
+INSERT INTO t2 VALUES (24,1,'2006-06-20 12:29:40');
+EXPLAIN
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index
+2 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 16 NULL 5 Using where; Using index
+SELECT * FROM t1,t2
+WHERE t1.t = (SELECT t1.t FROM t1
+WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
+ORDER BY t1.t DESC LIMIT 1);
+i1 i2 t i1 i2 t
+24 1 2005-05-27 12:40:30 24 1 2006-06-20 12:29:40
+DROP TABLE t1, t2;
+CREATE TABLE t1 (a VARCHAR(250), b INT auto_increment, PRIMARY KEY (b));
+insert into t1 (a) values (FLOOR(rand() * 100));
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+insert into t1 (a) select FLOOR(rand() * 100) from t1;
+SELECT a,
+(SELECT REPEAT(' ',250) FROM t1 i1
+WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a
+FROM t1 ORDER BY a LIMIT 5;
+a a
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+0 NULL
+DROP TABLE t1;
+CREATE TABLE t1 (a INT, b INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t2 values (1);
+INSERT INTO t1 VALUES (1,1),(1,2),(2,3),(3,4);
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2) FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2)
+2
+1
+1
+SELECT (SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+FROM t1 GROUP BY t1.a;
+(SELECT COUNT(DISTINCT t1.b) from t2 union select 1 from t2 where 12 < 3)
+2
+1
+1
+SELECT COUNT(DISTINCT t1.b), (SELECT COUNT(DISTINCT t1.b)) FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b))
+2 2
+1 1
+1 1
+SELECT COUNT(DISTINCT t1.b),
+(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+FROM t1 GROUP BY t1.a;
+COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
+2 2
+1 1
+1 1
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a;
+(
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+2
+1
+1
+SELECT (
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+FROM t1 t2
+GROUP BY t2.a;
+(
+SELECT (
+SELECT (
+SELECT COUNT(DISTINCT t1.b)
+)
+)
+FROM t1 GROUP BY t1.a LIMIT 1)
+2
+2
+2
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (b));
+CREATE TABLE t2 (x int auto_increment, y int, z int,
+PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
+create table t3 (a int);
+insert into t3 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+insert into t1 select RAND()*1000, A.a + 10*(B.a+10*(C.a+10*D.a))
+from t3 A, t3 B, t3 C, t3 D where D.a<3;
+insert into t2(y,z) select t1.b, RAND()*1000 from t1, t3;
+SET SESSION sort_buffer_size = 32 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+SET SESSION sort_buffer_size = 8 * 1024 * 1024;
+SELECT SQL_NO_CACHE COUNT(*)
+FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
+FROM t1) t;
+COUNT(*)
+3000
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id char(4) PRIMARY KEY, c int);
+CREATE TABLE t2 (c int);
+INSERT INTO t1 VALUES ('aa', 1);
+INSERT INTO t2 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+INSERT INTO t1 VALUES ('bb', 2), ('cc', 3), ('dd',1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT c FROM t2 WHERE c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+INSERT INTO t2 VALUES (2);
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (1);
+SELECT * FROM t1
+WHERE EXISTS (SELECT t2.c FROM t2 JOIN t3 ON t2.c=t3.c WHERE t2.c=1
+UNION
+SELECT c from t2 WHERE c=t1.c);
+id c
+aa 1
+bb 2
+cc 3
+dd 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1(f1 int);
+CREATE TABLE t2(f2 int, f21 int, f3 timestamp);
+INSERT INTO t1 VALUES (1),(1),(2),(2);
+INSERT INTO t2 VALUES (1,1,"2004-02-29 11:11:11"), (2,2,"2004-02-29 11:11:11");
+SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1;
+sq
+2
+4
+SELECT (SELECT SUM(1) FROM t2 ttt GROUP BY t2.f3 LIMIT 1) AS tt FROM t2;
+tt
+2
+2
+PREPARE stmt1 FROM 'SELECT ((SELECT f2 FROM t2 WHERE f21=f1 LIMIT 1) * COUNT(f1)) AS sq FROM t1 GROUP BY f1';
+EXECUTE stmt1;
+sq
+2
+4
+EXECUTE stmt1;
+sq
+2
+4
+DEALLOCATE PREPARE stmt1;
+SELECT f2, AVG(f21),
+(SELECT t.f3 FROM t2 AS t WHERE t2.f2=t.f2 AND t.f3=MAX(t2.f3)) AS test
+FROM t2 GROUP BY f2;
+f2 AVG(f21) test
+1 1.0000 2004-02-29 11:11:11
+2 2.0000 2004-02-29 11:11:11
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL);
+INSERT INTO t1 VALUES
+(1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
+(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'),
+(3,2,'k'), (3,1,'l'), (1,9,'m');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t1xt2;
+CREATE TABLE t1 (
+id_1 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t2 (
+id_2 int(5) NOT NULL,
+t varchar(4) DEFAULT NULL
+);
+CREATE TABLE t1xt2 (
+id_1 int(5) NOT NULL,
+id_2 int(5) NOT NULL
+);
+INSERT INTO t1 VALUES (1, 'a'), (2, 'b'), (3, 'c'), (4, 'd');
+INSERT INTO t2 VALUES (2, 'bb'), (3, 'cc'), (4, 'dd'), (12, 'aa');
+INSERT INTO t1xt2 VALUES (2, 2), (3, 3), (4, 4);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 where t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+3
+4
+insert INTO t1xt2 VALUES (1, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+2
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+2
+3
+4
+insert INTO t1xt2 VALUES (2, 12);
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+1
+2
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN ((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1)));
+id_1
+3
+4
+SELECT DISTINCT t1.id_1 FROM t1 WHERE
+(12 NOT IN (((SELECT t1xt2.id_2 FROM t1xt2 WHERE t1.id_1 = t1xt2.id_1))));
+id_1
+3
+4
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t1xt2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (3), (1), (2);
+SELECT 'this is ' 'a test.' AS col1, a AS col2 FROM t1;
+col1 col2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+SELECT * FROM (SELECT 'this is ' 'a test.' AS col1, a AS t2 FROM t1) t;
+col1 t2
+this is a test. 3
+this is a test. 1
+this is a test. 2
+DROP table t1;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*), a,
+(SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT m FROM t2 WHERE m = count(*) LIMIT 1)
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a,
+(SELECT MIN(m) FROM t2 WHERE m = count(*))
+FROM t1 GROUP BY a;
+COUNT(*) a (SELECT MIN(m) FROM t2 WHERE m = count(*))
+2 2 2
+3 3 3
+1 4 1
+SELECT COUNT(*), a
+FROM t1 GROUP BY a
+HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1;
+COUNT(*) a
+2 2
+3 3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int);
+CREATE TABLE t2 (m int, n int);
+INSERT INTO t1 VALUES (2,2), (2,2), (3,3), (3,3), (3,3), (4,4);
+INSERT INTO t2 VALUES (1,11), (2,22), (3,32), (4,44), (4,44);
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)) FROM t2 WHERE m = a)
+2 2 2
+3 3 3
+1 4 1,1
+SELECT COUNT(*) c, a,
+(SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+FROM t1 GROUP BY a;
+c a (SELECT GROUP_CONCAT(COUNT(a)+1) FROM t2 WHERE m = a)
+2 2 3
+3 3 4
+1 4 2,2
+DROP table t1,t2;
+CREATE TABLE t1 (a int, b INT, d INT, c CHAR(10) NOT NULL, PRIMARY KEY (a, b));
+INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
+(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
+(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');
+SELECT a, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+a MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a x, MAX(b),
+(SELECT t.c FROM t1 AS t WHERE x=t.a AND t.b=MAX(t1.b + 0)) as test
+FROM t1 GROUP BY a;
+x MAX(b) test
+1 9 m
+2 3 h
+3 4 i
+SELECT a, AVG(b),
+(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=AVG(t1.b)) AS test
+FROM t1 WHERE t1.d=0 GROUP BY a;
+a AVG(b) test
+1 4.0000 d
+2 2.0000 g
+3 2.5000 NULL
+SELECT tt.a,
+(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt;
+a test
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+1 n
+2 o
+2 o
+2 o
+2 o
+3 p
+3 p
+3 p
+3 p
+3 p
+SELECT tt.a,
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+SELECT tt.a, MAX(
+(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
+LIMIT 1)
+FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test
+FROM t1 as tt GROUP BY tt.a;
+a test
+1 n
+2 o
+3 p
+DROP TABLE t1;
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+a
+1
+2
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+a
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+a
+1
+2
+SET @@sql_mode='ansi';
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+ERROR HY000: Invalid use of group function
+SET @@sql_mode=default;
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 values (1),(1),(1),(1);
+CREATE TABLE t2 (x INT);
+INSERT INTO t1 values (1000),(1001),(1002);
+SELECT SUM( (SELECT COUNT(a) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT SUM( (SELECT SUM(COUNT(a)) FROM t2) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT COUNT(1) FROM DUAL;
+COUNT(1)
+1
+SELECT SUM( (SELECT AVG( (SELECT t1.a FROM t2) ) FROM DUAL) ) FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING t1.a < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+SELECT t1.a as XXA,
+SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) )
+FROM t1;
+ERROR HY000: Invalid use of group function
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int, b int, KEY (a));
+INSERT INTO t1 VALUES (1,1),(2,1);
+EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ref a a 5 const 0 Using where; Using index
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+DROP TABLE t1;
+CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
+INSERT INTO t1 VALUES
+(3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY');
+CREATE TABLE t2 (id int NOT NULL, INDEX idx(id));
+INSERT INTO t2 VALUES (7), (5), (1), (3);
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+3 FL
+1 GA
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+1 GA
+3 FL
+7 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
+id st
+2 GA
+4 FL
+SELECT id, st FROM t1
+WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
+GROUP BY id;
+id st
+2 GA
+4 FL
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1), (2);
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT count(*) FROM t1 GROUP BY a) as res;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+Warnings:
+Note 1003 select `res`.`count(*)` AS `count(*)` from (select count(0) AS `count(*)` from `test`.`t1` group by `test`.`t1`.`a`) `res`
+DROP TABLE t1;
+CREATE TABLE t1 (
+a varchar(255) default NULL,
+b timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+INDEX idx(a,b)
+);
+CREATE TABLE t2 (
+a varchar(255) default NULL
+);
+INSERT INTO t1 VALUES ('abcdefghijk','2007-05-07 06:00:24');
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO t1 SELECT * FROM t1;
+INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26');
+INSERT INTO `t2` VALUES ('abcdefghijk');
+INSERT INTO `t2` VALUES ('asdf');
+SET session sort_buffer_size=8192;
+SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
+d1
+1
+1
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INTEGER, b INTEGER);
+CREATE TABLE t2 (x INTEGER);
+INSERT INTO t1 VALUES (1,11), (2,22), (2,22);
+INSERT INTO t2 VALUES (1), (2);
+SELECT a, COUNT(b), (SELECT COUNT(b) FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT a, COUNT(b), (SELECT COUNT(b)+0 FROM t2) FROM t1 GROUP BY a;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a)/AVG(t2.x) FROM t2) FROM t1;
+(SELECT SUM(t1.a)/AVG(t2.x) FROM t2)
+3.3333
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1, 2), (1,3), (1,4), (2,1), (2,2);
+SELECT a1.a, COUNT(*) FROM t1 a1 WHERE a1.a = 1
+AND EXISTS( SELECT a2.a FROM t1 a2 WHERE a2.a = a1.a)
+GROUP BY a1.a;
+a COUNT(*)
+1 3
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+INSERT INTO t2 VALUES (1),(2);
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=0) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=0)
+NULL
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a!=0) FROM t1;
+ERROR 21000: Subquery returns more than 1 row
+SELECT (SELECT SUM(t1.a) FROM t2 WHERE a=1) FROM t1;
+(SELECT SUM(t1.a) FROM t2 WHERE a=1)
+3
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a1 INT, a2 INT);
+CREATE TABLE t2 (b1 INT, b2 INT);
+INSERT INTO t1 VALUES (100, 200);
+INSERT INTO t1 VALUES (101, 201);
+INSERT INTO t2 VALUES (101, 201);
+INSERT INTO t2 VALUES (103, 203);
+SELECT ((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL FROM t1;
+((a1,a2) IN (SELECT * FROM t2 WHERE b2 > 0)) IS NULL
+0
+0
+DROP TABLE t1, t2;
+CREATE TABLE t1 (s1 BINARY(5), s2 VARBINARY(5));
+INSERT INTO t1 VALUES (0x41,0x41), (0x42,0x42), (0x43,0x43);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+CREATE INDEX I1 ON t1 (s1);
+CREATE INDEX I2 ON t1 (s2);
+SELECT s1, s2 FROM t1 WHERE s2 IN (SELECT s1 FROM t1);
+s1 s2
+SELECT s1, s2 FROM t1 WHERE (s2, 10) IN (SELECT s1, 10 FROM t1);
+s1 s2
+TRUNCATE t1;
+INSERT INTO t1 VALUES (0x41,0x41);
+SELECT * FROM t1 WHERE s1 = (SELECT s2 FROM t1);
+s1 s2
+DROP TABLE t1;
+CREATE TABLE t1 (a1 VARBINARY(2) NOT NULL DEFAULT '0', PRIMARY KEY (a1));
+CREATE TABLE t2 (a2 BINARY(2) default '0', INDEX (a2));
+CREATE TABLE t3 (a3 BINARY(2) default '0');
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+INSERT INTO t2 VALUES (1),(2),(3);
+INSERT INTO t3 VALUES (1),(2),(3);
+SELECT LEFT(t2.a2, 1) FROM t2,t3 WHERE t3.a3=t2.a2;
+LEFT(t2.a2, 1)
+1
+2
+3
+SELECT t1.a1, t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2) FROM t1;
+a1 t1.a1 in (SELECT t2.a2 FROM t2,t3 WHERE t3.a3=t2.a2)
+1 0
+2 0
+3 0
+4 0
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a1 BINARY(3) PRIMARY KEY, b1 VARBINARY(3));
+CREATE TABLE t2 (a2 VARBINARY(3) PRIMARY KEY);
+CREATE TABLE t3 (a3 VARBINARY(3) PRIMARY KEY);
+INSERT INTO t1 VALUES (1,10), (2,20), (3,30), (4,40);
+INSERT INTO t2 VALUES (2), (3), (4), (5);
+INSERT INTO t3 VALUES (10), (20), (30);
+SELECT LEFT(t1.a1,1) FROM t1,t3 WHERE t1.b1=t3.a3;
+LEFT(t1.a1,1)
+1
+2
+3
+SELECT a2 FROM t2 WHERE t2.a2 IN (SELECT t1.a1 FROM t1,t3 WHERE t1.b1=t3.a3);
+a2
+DROP TABLE t1, t2, t3;
+CREATE TABLE t1 (a CHAR(1), b VARCHAR(10));
+INSERT INTO t1 VALUES ('a', 'aa');
+INSERT INTO t1 VALUES ('a', 'aaa');
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+a b
+CREATE INDEX I1 ON t1 (a);
+CREATE INDEX I2 ON t1 (b);
+EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where
+1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1)
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
+a b
+CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
+INSERT INTO t2 SELECT * FROM t1;
+CREATE INDEX I1 ON t2 (a);
+CREATE INDEX I2 ON t2 (b);
+EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL I2 NULL NULL NULL 2 Using where
+1 PRIMARY t2 ref I1 I1 4 test.t2.b 2 Using where; Using index; FirstMatch(t2)
+SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
+a b
+EXPLAIN
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where
+1 PRIMARY t1 ref I1 I1 2 test.t1.b 2 Using where; Using index; FirstMatch(t1)
+SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
+a b
+DROP TABLE t1,t2;
+CREATE TABLE t1(a INT, b INT);
+INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4);
+EXPLAIN
+SELECT a AS out_a, MIN(b) FROM t1
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
+GROUP BY a;
+ERROR 42S22: Unknown column 'out_a' in 'where clause'
+SELECT a AS out_a, MIN(b) FROM t1
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
+GROUP BY a;
+ERROR 42S22: Unknown column 'out_a' in 'where clause'
+EXPLAIN
+SELECT a AS out_a, MIN(b) FROM t1 t1_outer
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
+GROUP BY a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1_outer ALL NULL NULL NULL NULL 4 Using where; Using temporary; Using filesort
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 4 Using where
+SELECT a AS out_a, MIN(b) FROM t1 t1_outer
+WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
+GROUP BY a;
+out_a MIN(b)
+1 2
+2 4
+DROP TABLE t1;
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1(f11 int, f12 int);
+create table t2(f21 int unsigned not null, f22 int, f23 varchar(10));
+insert into t1 values(1,1),(2,2), (3, 3);
+insert into t2
+select -1 , (@a:=(A.a + 10 * (B.a + 10 * (C.a+10*D.a))))/5000 + 1, @a
+from t0 A, t0 B, t0 C, t0 D;
+set session sort_buffer_size= 33*1024;
+select count(*) from t1 where f12 =
+(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1);
+count(*)
+3
+drop table t0,t1,t2;
+CREATE TABLE t4 (
+f7 varchar(32) collate utf8_bin NOT NULL default '',
+f10 varchar(32) collate utf8_bin default NULL,
+PRIMARY KEY (f7)
+);
+INSERT INTO t4 VALUES(1,1), (2,null);
+CREATE TABLE t2 (
+f4 varchar(32) collate utf8_bin NOT NULL default '',
+f2 varchar(50) collate utf8_bin default NULL,
+f3 varchar(10) collate utf8_bin default NULL,
+PRIMARY KEY (f4),
+UNIQUE KEY uk1 (f2)
+);
+INSERT INTO t2 VALUES(1,1,null), (2,2,null);
+CREATE TABLE t1 (
+f8 varchar(32) collate utf8_bin NOT NULL default '',
+f1 varchar(10) collate utf8_bin default NULL,
+f9 varchar(32) collate utf8_bin default NULL,
+PRIMARY KEY (f8)
+);
+INSERT INTO t1 VALUES (1,'P',1), (2,'P',1), (3,'R',2);
+CREATE TABLE t3 (
+f6 varchar(32) collate utf8_bin NOT NULL default '',
+f5 varchar(50) collate utf8_bin default NULL,
+PRIMARY KEY (f6)
+);
+INSERT INTO t3 VALUES (1,null), (2,null);
+SELECT
+IF(t1.f1 = 'R', a1.f2, t2.f2) AS a4,
+IF(t1.f1 = 'R', a1.f3, t2.f3) AS f3,
+SUM(
+IF(
+(SELECT VPC.f2
+FROM t2 VPC, t4 a2, t2 a3
+WHERE
+VPC.f4 = a2.f10 AND a3.f2 = a4
+LIMIT 1) IS NULL,
+0,
+t3.f5
+)
+) AS a6
+FROM
+t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4
+GROUP BY a4;
+a4 f3 a6
+1 NULL NULL
+2 NULL NULL
+DROP TABLE t1, t2, t3, t4;
+create table t1 (a float(5,4) zerofill);
+create table t2 (a float(5,4),b float(2,0));
+select t1.a from t1 where
+t1.a= (select b from t2 limit 1) and not
+t1.a= (select a from t2 limit 1) ;
+a
+drop table t1, t2;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a);
+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
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,<exists>(select 1 from `test`.`t1` group by `test`.`t1`.`a` having (1 = <ref_null_helper>(1))))
+EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
+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
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
+Warnings:
+Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,<exists>(select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having (1 = <ref_null_helper>(1))))
+DROP TABLE t1;
+#
+# Bug#45061: Incorrectly market field caused wrong result.
+#
+CREATE TABLE `C` (
+`int_nokey` int(11) NOT NULL,
+`int_key` int(11) NOT NULL,
+KEY `int_key` (`int_key`)
+);
+INSERT INTO `C` VALUES (9,9), (0,0), (8,6), (3,6), (7,6), (0,4),
+(1,7), (9,4), (0,8), (9,4), (0,7), (5,5), (0,0), (8,5), (8,7),
+(5,2), (1,8), (7,0), (0,9), (9,5);
+SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`);
+int_nokey int_key
+9 9
+0 0
+5 5
+0 0
+EXPLAIN EXTENDED SELECT * FROM C WHERE `int_key` IN (SELECT `int_nokey`);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY C ALL NULL NULL NULL NULL 20 100.00 Using where
+DROP TABLE C;
+# End of test for bug#45061.
+#
+# Bug #46749: Segfault in add_key_fields() with outer subquery level
+# field references
+#
+CREATE TABLE t1 (
+a int,
+b int,
+UNIQUE (a), KEY (b)
+);
+INSERT INTO t1 VALUES (1,1), (2,1);
+CREATE TABLE st1 like t1;
+INSERT INTO st1 VALUES (1,1), (2,1);
+CREATE TABLE st2 like t1;
+INSERT INTO st2 VALUES (1,1), (2,1);
+EXPLAIN
+SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
+FROM t1
+WHERE a = 230;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+SELECT MAX(b), (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
+FROM t1
+WHERE a = 230;
+MAX(b) (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b)
+NULL 0
+DROP TABLE t1, st1, st2;
+#
+# Bug #48709: Assertion failed in sql_select.cc:11782:
+# int join_read_key(JOIN_TAB*)
+#
+CREATE TABLE t1 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t1 VALUES (10,1), (14,1);
+CREATE TABLE t2 (pk int PRIMARY KEY, int_key int);
+INSERT INTO t2 VALUES (3,3), (5,NULL), (7,3);
+# should have eq_ref for t1
+EXPLAIN
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+id select_type table type possible_keys key key_len ref rows Extra
+x x outr ALL x x x x x x
+x x t1 eq_ref x x x x x x
+x x t2 index x x x x x x
+# should not crash on debug binaries
+SELECT * FROM t2 outr
+WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2)
+ORDER BY outr.pk;
+pk int_key
+3 3
+7 3
+DROP TABLE t1,t2;
+End of 5.0 tests.
+create table t_out (subcase char(3),
+a1 char(2), b1 char(2), c1 char(2));
+create table t_in (a2 char(2), b2 char(2), c2 char(2));
+insert into t_out values ('A.1','2a', NULL, '2a');
+insert into t_out values ('A.3', '2a', NULL, '2a');
+insert into t_out values ('A.4', '2a', NULL, 'xx');
+insert into t_out values ('B.1', '2a', '2a', '2a');
+insert into t_out values ('B.2', '2a', '2a', '2a');
+insert into t_out values ('B.3', '3a', 'xx', '3a');
+insert into t_out values ('B.4', 'xx', '3a', '3a');
+insert into t_in values ('1a', '1a', '1a');
+insert into t_in values ('2a', '2a', '2a');
+insert into t_in values (NULL, '2a', '2a');
+insert into t_in values ('3a', NULL, '3a');
+
+Test general IN semantics (not top-level)
+
+case A.1
+select subcase,
+(a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+(a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'A.1';
+subcase pred_in pred_not_in
+A.1 0 1
+case A.2 - impossible
+case A.3
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.3';
+subcase pred_in pred_not_in
+A.3 NULL NULL
+case A.4
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'A.4';
+subcase pred_in pred_not_in
+A.4 0 1
+case B.1
+select subcase,
+(a1, b1, c1) IN (select * from t_in where a2 = 'no_match') pred_in,
+(a1, b1, c1) NOT IN (select * from t_in where a2 = 'no_match') pred_not_in
+from t_out where subcase = 'B.1';
+subcase pred_in pred_not_in
+B.1 0 1
+case B.2
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.2';
+subcase pred_in pred_not_in
+B.2 1 0
+case B.3
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.3';
+subcase pred_in pred_not_in
+B.3 NULL NULL
+case B.4
+select subcase,
+(a1, b1, c1) IN (select * from t_in) pred_in,
+(a1, b1, c1) NOT IN (select * from t_in) pred_not_in
+from t_out where subcase = 'B.4';
+subcase pred_in pred_not_in
+B.4 0 1
+
+Test IN as top-level predicate, and
+as non-top level for cases A.3, B.3 (the only cases with NULL result).
+
+case A.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.1' and
+(a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.1' and
+(a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.1' and
+NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+not_pred_in
+T
+case A.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.3' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.3' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.3' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'A.3' and
+((a1, b1, c1) IN (select * from t_in)) is NULL and
+((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+pred_in
+N
+case A.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'A.4' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'A.4' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'A.4' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+T
+case B.1
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.1' and
+(a1, b1, c1) IN (select * from t_in where a1 = 'no_match');
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.1' and
+(a1, b1, c1) NOT IN (select * from t_in where a1 = 'no_match');
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.1' and
+NOT((a1, b1, c1) IN (select * from t_in where a1 = 'no_match'));
+not_pred_in
+T
+case B.2
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.2' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.2' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.2' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+case B.3
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.3' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.3' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.3' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+F
+select case when count(*) > 0 then 'N' else 'wrong result' end as pred_in from t_out
+where subcase = 'B.3' and
+((a1, b1, c1) IN (select * from t_in)) is NULL and
+((a1, b1, c1) NOT IN (select * from t_in)) is NULL;
+pred_in
+N
+case B.4
+select case when count(*) > 0 then 'T' else 'F' end as pred_in from t_out
+where subcase = 'B.4' and
+(a1, b1, c1) IN (select * from t_in);
+pred_in
+F
+select case when count(*) > 0 then 'T' else 'F' end as pred_not_in from t_out
+where subcase = 'B.4' and
+(a1, b1, c1) NOT IN (select * from t_in);
+pred_not_in
+T
+select case when count(*) > 0 then 'T' else 'F' end as not_pred_in from t_out
+where subcase = 'B.4' and
+NOT((a1, b1, c1) IN (select * from t_in));
+not_pred_in
+T
+drop table t_out;
+drop table t_in;
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+a
+1
+2
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+a
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+a
+1
+2
+SET @@sql_mode='ansi';
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 1 GROUP BY a;
+ERROR HY000: Invalid use of group function
+SELECT a FROM t1 t0
+WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
+ERROR HY000: Invalid use of group function
+SET @@sql_mode=default;
+DROP TABLE t1;
+CREATE TABLE t1 (s1 CHAR(1));
+INSERT INTO t1 VALUES ('a');
+SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1);
+s1
+a
+DROP TABLE t1;
+CREATE TABLE t1(c INT, KEY(c));
+CREATE TABLE t2(a INT, b INT);
+INSERT INTO t2 VALUES (1, 10), (2, NULL);
+INSERT INTO t1 VALUES (1), (3);
+SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
+a b
+DROP TABLE t1,t2;
+CREATE TABLE t1(pk INT PRIMARY KEY, a INT, INDEX idx(a));
+INSERT INTO t1 VALUES (1, 10), (3, 30), (2, 20);
+CREATE TABLE t2(pk INT PRIMARY KEY, a INT, b INT, INDEX idxa(a));
+INSERT INTO t2 VALUES (2, 20, 700), (1, 10, 200), (4, 10, 100);
+SELECT * FROM t1
+WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
+pk a
+1 10
+3 30
+2 20
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
+INSERT INTO t1 VALUES (1,NULL), (9,NULL);
+CREATE TABLE t2 (
+a INT,
+b INT,
+c INT,
+d INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c,d),
+KEY b_2 (b),
+KEY c (c),
+KEY d (d)
+);
+INSERT INTO t2 VALUES
+(43, 2, 11 ,30),
+(44, 2, 12 ,30),
+(45, 1, 1 ,10000),
+(46, 1, 2 ,10000),
+(556,1, 32 ,10000);
+CREATE TABLE t3 (
+a INT,
+b INT,
+c INT,
+PRIMARY KEY (a),
+UNIQUE KEY b (b,c),
+KEY c (c),
+KEY b_2 (b)
+);
+INSERT INTO t3 VALUES (1,1,1), (2,32,1);
+explain
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 index PRIMARY PRIMARY 4 NULL 2 Using index
+1 PRIMARY t3 ref b,b_2 b 5 test.t1.a 1 Using index
+2 DEPENDENT SUBQUERY t2 ref b,b_2,c b 10 test.t3.c,test.t1.a 1 Using where; Using index; Using filesort
+SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
+a incorrect
+1 1
+DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (id int);
+CREATE TABLE t2 (id int, c int);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+INSERT INTO t1 (id) VALUES (1);
+INSERT INTO t2 (id) VALUES (1);
+CREATE VIEW v1 AS
+SELECT t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+UPDATE v1 SET c=1;
+CREATE VIEW v2 (a,b) AS
+SELECT t2.id, t2.c AS c FROM t1, t2
+WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+INSERT INTO v2(a,b) VALUES (2,2);
+ERROR HY000: CHECK OPTION failed 'test.v2'
+SELECT * FROM v1;
+c
+1
+1
+1
+1
+CREATE VIEW v3 AS
+SELECT t2.c AS c FROM t2
+WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+DELETE FROM v3;
+DROP VIEW v1,v2,v3;
+DROP TABLE t1,t2;
+#
+# BUG#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+#
+# Bug#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
+#
+create table t1(id integer primary key, g integer, v integer, s char(1));
+create table t2(id integer primary key, g integer, v integer, s char(1));
+insert into t1 values
+(10, 10, 10, 'l'),
+(20, 20, 20, 'l'),
+(40, 40, 40, 'l'),
+(41, 40, null, 'l'),
+(50, 50, 50, 'l'),
+(51, 50, null, 'l'),
+(60, 60, 60, 'l'),
+(61, 60, null, 'l'),
+(70, 70, 70, 'l'),
+(90, 90, null, 'l');
+insert into t2 values
+(10, 10, 10, 'r'),
+(30, 30, 30, 'r'),
+(50, 50, 50, 'r'),
+(60, 60, 60, 'r'),
+(61, 60, null, 'r'),
+(70, 70, 70, 'r'),
+(71, 70, null, 'r'),
+(80, 80, 80, 'r'),
+(81, 80, null, 'r'),
+(100,100,null, 'r');
+select *
+from t1
+where v in(select v
+from t2
+where t1.g=t2.g) is unknown;
+id g v s
+51 50 NULL l
+61 60 NULL l
+drop table t1, t2;
+CREATE TABLE t1 (a ENUM('rainbow'));
+INSERT INTO t1 VALUES (),(),(),(),();
+SELECT 1 FROM t1 GROUP BY (SELECT 1 FROM t1 ORDER BY AVG(LAST_INSERT_ID()));
+1
+1
+DROP TABLE t1;
+CREATE TABLE t1 (a LONGBLOB);
+INSERT INTO t1 SET a = 'aaaa';
+INSERT INTO t1 SET a = 'aaaa';
+SELECT 1 FROM t1 GROUP BY
+(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
+1
+1
+DROP TABLE t1;
+#
+# Bug #49512 : subquery with aggregate function crash
+# subselect_single_select_engine::exec()
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES();
+# should not crash
+SELECT 1 FROM t1 WHERE a <> SOME
+(
+SELECT MAX((SELECT a FROM t1 LIMIT 1)) AS d
+FROM t1,t1 a
+);
+1
+DROP TABLE t1;
+#
+# Bug #45989 take 2 : memory leak after explain encounters an
+# error in the query
+#
+CREATE TABLE t1(a LONGTEXT);
+INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet));
+INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet));
+EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1,
+(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) AS d1
+WHERE t1.a = d1.a;
+ERROR 42S22: Unknown column 'd1.a' in 'where clause'
+DROP TABLE t1;
+End of 5.1 tests.
+Set up test tables.
+CREATE TABLE t1 (
+t1_id INT UNSIGNED,
+PRIMARY KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t1 (t1_id) VALUES (1), (2), (3), (4), (5);
+CREATE TABLE t2 SELECT * FROM t1;
+CREATE TABLE t3 (
+t3_id INT UNSIGNED AUTO_INCREMENT,
+t1_id INT UNSIGNED,
+amount DECIMAL(16,2),
+PRIMARY KEY(t3_id),
+KEY(t1_id)
+) Engine=MyISAM;
+INSERT INTO t3 (t1_id, t3_id, amount)
+VALUES (1, 1, 100.00), (2, 2, 200.00), (4, 4, 400.00);
+This is the 'inner query' running by itself.
+Produces correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query)
+Produces correct results.
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+Now make t2.t1_id part of a key.
+ALTER TABLE t2 ADD PRIMARY KEY(t1_id);
+Same inner query by itself.
+Still correct results.
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+SELECT * FROM (the same inner query), now with indexes on the LEFT JOIN
+SELECT * FROM (
+SELECT
+t1.t1_id,
+IFNULL((SELECT SUM(amount) FROM t3 WHERE t3.t1_id=t1.t1_id), 0) AS total_amount
+FROM
+t1
+LEFT JOIN t2 ON t2.t1_id=t1.t1_id
+GROUP BY
+t1.t1_id
+) AS t;
+t1_id total_amount
+1 100.00
+2 200.00
+3 0.00
+4 400.00
+5 0.00
+DROP TABLE t3;
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# Bug #52711: Segfault when doing EXPLAIN SELECT with
+# union...order by (select... where...)
+#
+CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a));
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (b INT);
+INSERT INTO t2 VALUES (1),(2);
+# Should not crash
+EXPLAIN
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+# Should not crash
+SELECT * FROM t2 UNION SELECT * FROM t2
+ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE));
+DROP TABLE t1,t2;
+# LP BUG#675248 - select->prep_where references on freed memory
+CREATE TABLE t1 (a int, b int);
+insert into t1 values (1,1),(0,0);
+CREATE TABLE t2 (c int);
+insert into t2 values (1),(2);
+prepare stmt1 from "select sum(a),(select sum(c) from t2 where table1.b) as sub
+from t1 as table1 group by sub";
+execute stmt1;
+sum(a) sub
+0 NULL
+1 3
+deallocate prepare stmt1;
+prepare stmt1 from "select sum(a),(select sum(c) from t2 having table1.b) as sub
+from t1 as table1";
+execute stmt1;
+sum(a) sub
+1 3
+deallocate prepare stmt1;
+drop table t1,t2;
+#
+# Bug LP#693935/#58727: Assertion failure with
+# a single row subquery returning more than one row
+#
+create table t1 (a char(1) charset utf8);
+insert into t1 values ('a'), ('b');
+create table t2 (a binary(1));
+insert into t2 values ('x'), ('y');
+select * from t2 where a=(select a from t1) and a='x';
+ERROR 21000: Subquery returns more than 1 row
+drop table t1,t2;
+End of 5.1 tests
+#
+# No BUG#, a case brought from 5.2's innodb_mysql_lock.test
+#
+create table t1 (i int not null primary key);
+insert into t1 values (1),(2),(3),(4),(5);
+create table t2 (j int not null primary key);
+insert into t2 values (1),(2),(3),(4),(5);
+create table t3 (k int not null primary key);
+insert into t3 values (1),(2),(3);
+create view v2 as select t2.j as j from t2 where t2.j in (select t1.i from t1);
+select * from t3 where k in (select j from v2);
+k
+1
+2
+3
+drop table t1,t2,t3;
+drop view v2;
+#
+# Bug#52068: Optimizer generates invalid semijoin materialization plan
+#
+drop table if exists ot1, ot2, it1, it2;
+CREATE TABLE ot1(a INTEGER);
+INSERT INTO ot1 VALUES(5), (8);
+CREATE TABLE it2(a INTEGER);
+INSERT INTO it2 VALUES(9), (5), (1), (8);
+CREATE TABLE it3(a INTEGER);
+INSERT INTO it3 VALUES(7), (1), (0), (5), (1), (4);
+CREATE TABLE ot4(a INTEGER);
+INSERT INTO ot4 VALUES(1), (3), (5), (7), (9), (7), (3), (1);
+SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+FROM it2,it3);
+a a
+5 1
+8 1
+5 5
+8 5
+5 7
+8 7
+5 7
+8 7
+5 1
+8 1
+explain SELECT * FROM ot1,ot4
+WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
+FROM it2,it3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY it2 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY it3 ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
+1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using where; End temporary; Using join buffer (flat, BNL join)
+DROP TABLE IF EXISTS ot1, ot4, it2, it3;
+#
+# Bug#729039: NULL keys used to evaluate subquery
+#
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (NULL), (1), (NULL), (2);
+CREATE TABLE t2 (a int, INDEX idx(a)) ;
+INSERT INTO t2 VALUES (NULL), (1), (NULL);
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 USE INDEX () WHERE t2.a = t1.a);
+a
+1
+EXPLAIN
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 USE INDEX() WHERE t2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+a
+1
+EXPLAIN
+SELECT * FROM t1
+WHERE EXISTS (SELECT a FROM t2 WHERE t2.a = t1.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+2 DEPENDENT SUBQUERY t2 ref idx idx 5 test.t1.a 2 Using index
+DROP TABLE t1,t2;
+#
+# BUG#752992: Wrong results for a subquery with 'semijoin=on'
+#
+CREATE TABLE t1 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t1 VALUES (11,0);
+INSERT INTO t1 VALUES (12,5);
+INSERT INTO t1 VALUES (15,0);
+CREATE TABLE t2 (pk INTEGER PRIMARY KEY, i INTEGER NOT NULL);
+INSERT INTO t2 VALUES (11,1);
+INSERT INTO t2 VALUES (12,2);
+INSERT INTO t2 VALUES (15,4);
+EXPLAIN SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 3 Start temporary
+1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; Using join buffer (flat, BNL join)
+1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index; End temporary
+SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON 1);
+pk i
+11 0
+12 5
+15 0
+DROP table t1,t2;
+#
+# Bug#751350: crash with pushed condition for outer references when
+# there should be none of such conditions
+#
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0),(0,0);
+EXPLAIN
+SELECT b FROM t1
+WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+GROUP BY b;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+SELECT b FROM t1
+WHERE ('0') IN ( SELECT a FROM t1 GROUP BY a )
+GROUP BY b;
+b
+0
+DROP TABLE t1;
+#
+# Bug #11765713 58705:
+# OPTIMIZER LET ENGINE DEPEND ON UNINITIALIZED VALUES
+# CREATED BY OPT_SUM_QUERY
+#
+CREATE TABLE t1(a INT NOT NULL, KEY (a));
+INSERT INTO t1 VALUES (0), (1);
+SELECT 1 as foo FROM t1 WHERE a < SOME
+(SELECT a FROM t1 WHERE a <=>
+(SELECT a FROM t1)
+);
+ERROR 21000: Subquery returns more than 1 row
+SELECT 1 as foo FROM t1 WHERE a < SOME
+(SELECT a FROM t1 WHERE a <=>
+(SELECT a FROM t1 where a is null)
+);
+foo
+DROP TABLE t1;
+CREATE TABLE t1 (a int(11), b varchar(1));
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+delete from t1;
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+drop table t1;
+#
+# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ;
+INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0);
+DROP TABLE IF EXISTS t3;
+Warnings:
+Note 1051 Unknown table 't3'
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ;
+r
+NULL
+5
+NULL
+5
+DROP TABLE t1, t2, t3;
+End of 5.2 tests
+#
+# BUG#779885: Crash in eliminate_item_equal with materialization=on in
+# maria-5.3
+#
+CREATE TABLE t1 ( f1 int );
+INSERT INTO t1 VALUES (19), (20);
+CREATE TABLE t2 ( f10 varchar(32) );
+INSERT INTO t2 VALUES ('c'),('d');
+CREATE TABLE t3 ( f10 varchar(32) );
+INSERT INTO t3 VALUES ('a'),('b');
+SELECT *
+FROM t1
+WHERE
+( 't' ) IN (
+SELECT t3.f10
+FROM t3
+JOIN t2
+ON t2.f10 = t3.f10
+);
+f1
+DROP TABLE t1,t2,t3;
+#
+# BUG LP:813473: Wrong result with outer join + NOT IN subquery
+# This bug is a duplicate of Bug#11764086 whose test case is added below
+#
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
+create table t3 (d int, e int);
+insert into t3 values (2, 9), (3,10);
+EXPLAIN
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b , t1.c) NOT IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b, t1.c) NOT IN (SELECT * from t3);
+b c
+9 NULL
+9 NULL
+drop table t1, t2, t3;
+End of 5.3 tests
+End of 5.5 tests.
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+#
+# Bug#11764086: Null left operand to NOT IN in WHERE clause
+# behaves differently than real NULL
+#
+CREATE TABLE parent (id int);
+INSERT INTO parent VALUES (1), (2);
+CREATE TABLE child (parent_id int, other int);
+INSERT INTO child VALUES (1,NULL);
+# Offending query (c.parent_id is NULL for null-complemented rows only)
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id NOT IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+);
+id parent_id
+1 1
+2 NULL
+# Some syntactic variations with IS FALSE and IS NOT TRUE
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS NOT TRUE;
+id parent_id
+1 1
+2 NULL
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS FALSE;
+id parent_id
+1 1
+2 NULL
+DROP TABLE parent, child;
+# End of test for bug#11764086.
+#
+# BUG#50257: Missing info in REF column of the EXPLAIN
+# lines for subselects
+#
+CREATE TABLE t1 (a INT, b INT, INDEX (a));
+INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+
+EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ref a a 5 const 1
+
+EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 SUBQUERY t1 ref a a 5 const 1 Using index
+
+DROP TABLE t1;
+#
+# Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET ||
+# BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0), (1);
+CREATE TABLE t2(
+b TEXT,
+c INT,
+PRIMARY KEY (b(1))
+);
+INSERT INTO t2 VALUES ('a', 2), ('b', 3);
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ORDER BY b
+);
+1
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+GROUP BY b
+);
+1
+DROP TABLE t1, t2;
+#
+# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS)
+#
+CREATE TABLE t1 (f1 varchar(1));
+INSERT INTO t1 VALUES ('v'),('s');
+CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key));
+INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'),
+('d'),('y'),('t'),('d'),('s');
+SELECT table1.f1, table2.f1_key
+FROM t1 AS table1, t2 AS table2
+WHERE EXISTS
+(
+SELECT DISTINCT f1_key
+FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
+f1 f1_key
+v j
+s j
+v v
+s v
+v c
+s c
+v m
+s m
+v d
+s d
+v d
+s d
+v y
+s y
+v t
+s t
+v d
+s d
+v s
+s s
+explain SELECT table1.f1, table2.f1_key
+FROM t1 AS table1, t2 AS table2
+WHERE EXISTS
+(
+SELECT DISTINCT f1_key
+FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY table1 ALL NULL NULL NULL NULL 2
+1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
+DROP TABLE t1,t2;
+#
+# LP bug #826279: assertion failure with GROUP BY a result of subquery
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0), (0);
+CREATE TABLE t2 (a int, b int, c int);
+INSERT INTO t2 VALUES (10,7,0), (0,7,0);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,7), (0,7);
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+7 NULL
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+7 NULL
+7 10
+DROP TABLE t1,t2,t3;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+set optimizer_switch=@subselect_tmp;
+set optimizer_switch=default;
+select @@optimizer_switch like '%subquery_cache=on%';
+@@optimizer_switch like '%subquery_cache=on%'
+1
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
index 434bcd33a21..7f9e3185d2e 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -1,8 +1,10 @@
-set optimizer_switch='semijoin=off';
+set @optimizer_switch_for_subselect_test='semijoin=off,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
drop view if exists v2;
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+set @subselect_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
+"semijoin=on,firstmatch=on,loosescan=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
select (select 2);
(select 2)
2
@@ -203,10 +205,11 @@ select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
(select * from t2 where a>1) as tt;
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 <derived3> ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
Warnings:
-Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a` > 1)
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
a
2
@@ -227,7 +230,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t4.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t4`.`b` AS `b`,(select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+Note 1003 select `test`.`t4`.`b` AS `b`,<expr_cache><`test`.`t4`.`a`>((select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`)) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
select * from t3 where exists (select * from t2 where t2.b=t3.a);
a
7
@@ -273,7 +276,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2);
a
7
@@ -365,12 +368,12 @@ INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where; Using index
4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
-2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where
3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
Warnings:
-Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
+Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
ERROR 21000: Operand should contain 1 column(s)
@@ -541,18 +544,24 @@ SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT
numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY t1 ref PRIMARY PRIMARY 3 const 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select 1 from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
ERROR 21000: Subquery returns more than 1 row
EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where multiple equal(1, `test`.`t1`.`numeropost`)
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using index
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select 3 AS `numreponse` from `test`.`t1` where ((3 = 3))
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
drop table t1;
CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1);
@@ -914,6 +923,131 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`a` from `test`.`t2` join `test`.`t3` where ((`test`.`t3`.`a` = `test`.`t2`.`a`) and ((<cache>(`test`.`t1`.`a`) = `test`.`t2`.`a`) or isnull(`test`.`t2`.`a`))) having <is_not_null_test>(`test`.`t2`.`a`)))) AS `t1.a in (select t2.a from t2,t3 where t3.a=t2.a)` from `test`.`t1`
drop table t1,t2,t3;
+# check correct NULL Processing for normal IN/ALL/ANY
+# and 2 ways of max/min optimization
+create table t1 (a int);
+insert into t1 values (1), (100), (NULL), (1000);
+create table t2 (a int not null);
+# subselect returns empty set (for NULL and non-NULL left part)
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 0
+NULL 0
+1000 0
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 1
+100 1
+NULL 1
+1000 1
+select a from t1 where a in (select * from t2);
+a
+select a from t1 where a > any (select * from t2);
+a
+select a from t1 where a > all (select * from t2);
+a
+1
+100
+NULL
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+select a from t1 where a > any (select * from t2 group by a);
+a
+select a from t1 where a > all (select * from t2 group by a);
+a
+1
+100
+NULL
+1000
+insert into t2 values (1),(200);
+# sebselect returns non-empty set without NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 0
+NULL NULL
+1000 0
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 0
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 1
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+1000
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+1000
+drop table t2;
+create table t2 (a int);
+insert into t2 values (1),(NULL),(200);
+# sebselect returns non-empty set with NULLs
+select a, a in (select * from t2) from t1;
+a a in (select * from t2)
+1 1
+100 NULL
+NULL NULL
+1000 NULL
+select a, a > any (select * from t2) from t1;
+a a > any (select * from t2)
+1 NULL
+100 1
+NULL NULL
+1000 1
+select a, a > all (select * from t2) from t1;
+a a > all (select * from t2)
+1 0
+100 0
+NULL NULL
+1000 NULL
+select a from t1 where a in (select * from t2);
+a
+1
+select a from t1 where a > any (select * from t2);
+a
+100
+1000
+select a from t1 where a > all (select * from t2);
+a
+select a from t1 where a in (select * from t2 group by a);
+a
+1
+select a from t1 where a > any (select * from t2 group by a);
+a
+100
+1000
+select a from t1 where a > all (select * from t2 group by a);
+a
+drop table t1, t2;
create table t1 (a float);
select 10.5 IN (SELECT * from t1 LIMIT 1);
ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
@@ -1237,7 +1371,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using index condition
+1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using index condition
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
@@ -1417,7 +1551,7 @@ INSERT INTO t1 VALUES ('z','?');
select * from t1 where s1 > (select max(s2) from t1);
ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
select * from t1 where s1 > any (select max(s2) from t1);
-ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+ERROR HY000: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '<'
drop table t1;
create table t1(toid int,rd int);
create table t2(userid int,pmnew int,pmtotal int);
@@ -1493,7 +1627,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < 'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`)))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
drop table t1,t2;
-create table t2 (a int, b int);
+create table t2 (a int, b int not null);
create table t3 (a int);
insert into t3 values (6),(7),(3);
select * from t3 where a >= all (select b from t2);
@@ -1506,7 +1640,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < (select max(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(NULL) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2);
a
explain extended select * from t3 where a >= some (select b from t2);
@@ -1514,7 +1648,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select min(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(NULL) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
@@ -1525,7 +1659,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < <max>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select NULL from `test`.`t2` group by 1) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2 group by 1);
a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
@@ -1533,7 +1667,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= <min>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(<min>(select NULL from `test`.`t2` group by 1) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
@@ -1541,7 +1675,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
@@ -1549,7 +1683,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
select * from t3 where NULL >= some (select b from t2);
a
explain extended select * from t3 where NULL >= some (select b from t2);
@@ -1557,7 +1691,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= (select min(NULL) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(NULL) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
@@ -1565,7 +1699,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= <min>(select NULL from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
a
@@ -1576,7 +1710,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= <cache>(`test`.`t3`.`a`))))
drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
@@ -1627,7 +1761,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION t1 system NULL NULL NULL NULL 1 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',('f' > <min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`))))
+Note 1003 select 'e' AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',(<min>(select 'e' from `test`.`t1` union select 'e' from `test`.`t1`) < 'f')))
drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
@@ -2830,19 +2964,19 @@ 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
2 DEPENDENT SUBQUERY 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`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
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 Using where
2 DEPENDENT SUBQUERY 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` where <expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = 'N') and (<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) and (<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`)))))
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `test`.`t1` where <expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = 'N') and (<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) and (<cache>(`test`.`t1`.`two`) = `test`.`t2`.`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
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; Using temporary
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
DROP TABLE t1,t2;
CREATE TABLE t1 (a char(5), b char(5));
INSERT INTO t1 VALUES (NULL,'aaa'), ('aaa','aaa');
@@ -2958,7 +3092,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -2970,7 +3104,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using index condition
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -4031,7 +4165,7 @@ CREATE TABLE t1 (a int, b int, KEY (a));
INSERT INTO t1 VALUES (1,1),(2,1);
EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
+1 PRIMARY t1 ref a a 5 const 0 Using where; Using index
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
DROP TABLE t1;
CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
@@ -4804,7 +4938,6 @@ SELECT 1 FROM t1 GROUP BY
1
1
DROP TABLE t1;
-set @@optimizer_switch=@save_optimizer_switch;
#
# Bug #49512 : subquery with aggregate function crash
# subselect_single_select_engine::exec()
@@ -5106,6 +5239,167 @@ SELECT 1 as foo FROM t1 WHERE a < SOME
);
foo
DROP TABLE t1;
+CREATE TABLE t1 (a int(11), b varchar(1));
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+delete from t1;
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+a
+5
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+a
+7
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+a
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+a
+5
+7
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+a
+5
+7
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+a
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+a
+drop table t1;
+#
+# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+#
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ;
+INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0);
+DROP TABLE IF EXISTS t3;
+Warnings:
+Note 1051 Unknown table 't3'
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ;
+r
+NULL
+5
+NULL
+5
+DROP TABLE t1, t2, t3;
+End of 5.2 tests
#
# BUG#779885: Crash in eliminate_item_equal with materialization=on in
# maria-5.3
@@ -5127,5 +5421,247 @@ ON t2.f10 = t3.f10
);
f1
DROP TABLE t1,t2,t3;
+#
+# BUG LP:813473: Wrong result with outer join + NOT IN subquery
+# This bug is a duplicate of Bug#11764086 whose test case is added below
+#
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
+create table t3 (d int, e int);
+insert into t3 values (2, 9), (3,10);
+EXPLAIN
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b , t1.c) NOT IN (SELECT * from t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
+2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b, t1.c) NOT IN (SELECT * from t3);
+b c
+9 NULL
+9 NULL
+drop table t1, t2, t3;
End of 5.3 tests
-set optimizer_switch=default;
+End of 5.5 tests.
+#
+# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+1
+1
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+1
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+1
+1
+1
+SET SESSION sql_mode=@old_sql_mode;
+DROP TABLE t1, t2;
+#
+# Bug#11764086: Null left operand to NOT IN in WHERE clause
+# behaves differently than real NULL
+#
+CREATE TABLE parent (id int);
+INSERT INTO parent VALUES (1), (2);
+CREATE TABLE child (parent_id int, other int);
+INSERT INTO child VALUES (1,NULL);
+# Offending query (c.parent_id is NULL for null-complemented rows only)
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id NOT IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+);
+id parent_id
+1 1
+2 NULL
+# Some syntactic variations with IS FALSE and IS NOT TRUE
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS NOT TRUE;
+id parent_id
+1 1
+2 NULL
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+SELECT parent_id
+FROM child
+WHERE parent_id = 3
+) IS FALSE;
+id parent_id
+1 1
+2 NULL
+DROP TABLE parent, child;
+# End of test for bug#11764086.
+#
+# BUG#50257: Missing info in REF column of the EXPLAIN
+# lines for subselects
+#
+CREATE TABLE t1 (a INT, b INT, INDEX (a));
+INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+
+EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t1 ref a a 5 const 1
+
+EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4
+2 SUBQUERY t1 ref a a 5 const 1 Using index
+
+DROP TABLE t1;
+#
+# Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET ||
+# BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX
+#
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0), (1);
+CREATE TABLE t2(
+b TEXT,
+c INT,
+PRIMARY KEY (b(1))
+);
+INSERT INTO t2 VALUES ('a', 2), ('b', 3);
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ORDER BY b
+);
+1
+SELECT 1 FROM t1 WHERE a =
+(SELECT 1 FROM t2 WHERE b =
+(SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+GROUP BY b
+);
+1
+DROP TABLE t1, t2;
+#
+# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS)
+#
+CREATE TABLE t1 (f1 varchar(1));
+INSERT INTO t1 VALUES ('v'),('s');
+CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key));
+INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'),
+('d'),('y'),('t'),('d'),('s');
+SELECT table1.f1, table2.f1_key
+FROM t1 AS table1, t2 AS table2
+WHERE EXISTS
+(
+SELECT DISTINCT f1_key
+FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
+f1 f1_key
+v j
+s j
+v v
+s v
+v c
+s c
+v m
+s m
+v d
+s d
+v d
+s d
+v y
+s y
+v t
+s t
+v d
+s d
+v s
+s s
+explain SELECT table1.f1, table2.f1_key
+FROM t1 AS table1, t2 AS table2
+WHERE EXISTS
+(
+SELECT DISTINCT f1_key
+FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY table1 ALL NULL NULL NULL NULL 2
+1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
+DROP TABLE t1,t2;
+#
+# LP bug #826279: assertion failure with GROUP BY a result of subquery
+#
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0), (0);
+CREATE TABLE t2 (a int, b int, c int);
+INSERT INTO t2 VALUES (10,7,0), (0,7,0);
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,7), (0,7);
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+WHERE t.a != 0 AND t2.a != 0)
+7 NULL
+SELECT SUM(DISTINCT b),
+(SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+SUM(DISTINCT b) (SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+7 NULL
+7 10
+DROP TABLE t1,t2,t3;
+#
+# Bug#12329653
+# EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+#
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+1
+1
+1
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+EXECUTE stmt ;
+ERROR 21000: Subquery returns more than 1 row
+SET SESSION sql_mode=@old_sql_mode;
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+set optimizer_switch=@subselect_tmp;
+set @optimizer_switch_for_subselect_test=null;
diff --git a/mysql-test/r/subselect_nulls.result b/mysql-test/r/subselect_nulls.result
index 1ae8c9f6237..584c184870d 100644
--- a/mysql-test/r/subselect_nulls.result
+++ b/mysql-test/r/subselect_nulls.result
@@ -1,5 +1,7 @@
drop table if exists x1;
drop table if exists x2;
+set @tmp_subselect_nulls=@@optimizer_switch;
+set optimizer_switch='semijoin=off';
create table x1(k int primary key, d1 int, d2 int);
create table x2(k int primary key, d1 int, d2 int);
insert into x1 values
@@ -110,5 +112,6 @@ where x1.d1=x2.d1 and x1.d2=x2.d2);
k d1 d2
10 10 10
20 20 20
+set optimizer_switch= @tmp_subselect_nulls;
drop table x1;
drop table x2;
diff --git a/mysql-test/r/subselect_partial_match.result b/mysql-test/r/subselect_partial_match.result
index 9d604cc1507..1b39381b42b 100644
--- a/mysql-test/r/subselect_partial_match.result
+++ b/mysql-test/r/subselect_partial_match.result
@@ -1,8 +1,210 @@
+set @save_optimizer_switch=@@optimizer_switch;
+-------------------------------
+Part 1: Feature tests.
+-------------------------------
+Default for all tests.
+set @@optimizer_switch="materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off";
+
+Schema requires partial matching, but data analysis discoveres there is
+no need. This is possible only if all outer columns are not NULL.
+
+create table t1 (a1 char(8) not null, a2 char(8) not null);
+create table t2 (b1 char(8), b2 char(8));
+insert into t1 values ('1 - 00', '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 00', '2 - 00');
+insert into t2 values ('1 - 01', NULL );
+insert into t2 values (NULL , '2 - 02');
+insert into t2 values (NULL , NULL );
+insert into t2 values ('1 - 02', '2 - 02');
+select * from t1
+where (a1, a2) not in (select * from t2 where b1 is not null and b2 is not null);
+a1 a2
+1 - 01 2 - 01
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+a1 a2 in_res
+1 - 00 2 - 00 0
+1 - 01 2 - 01 NULL
+drop table t1, t2;
+
+NULLs in the outer columns, no NULLs in the suqbuery
+
+create table t1 (a1 char(8), a2 char(8));
+create table t2 (b1 char(8) not null, b2 char(8) not null);
+insert into t1 values (NULL , '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+insert into t1 values (NULL , NULL );
+insert into t2 values ('1 - 00', '2 - 00');
+insert into t2 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 02', '2 - 00');
+select * from t1
+where (a1, a2) not in (select * from t2 where b1 is not null and b2 is not null);
+a1 a2
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+a1 a2 in_res
+NULL 2 - 00 NULL
+1 - 01 2 - 01 0
+NULL NULL NULL
+select * from t1
+where (a1, a2) in (select * from t2 where b1 is not null and b2 is not null);
+a1 a2
+1 - 01 2 - 01
+select a1, a2, (a1, a2) in (select * from t2) as in_res from t1;
+a1 a2 in_res
+NULL 2 - 00 NULL
+1 - 01 2 - 01 1
+NULL NULL NULL
+drop table t1, t2;
+
+All columns require partial matching (no non-null columns)
+
+TODO
+
+Both non-NULL columns and columns with NULLs
+
+TODO
+
+Covering NULL rows
+
+create table t1 (a1 char(8), a2 char(8));
+create table t2 (b1 char(8), b2 char(8));
+insert into t1 values ('1 - 00', '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 01', NULL );
+insert into t2 values (NULL , '2 - 02');
+insert into t2 values (NULL , NULL );
+insert into t2 values ('1 - 02', '2 - 02');
+select * from t1
+where (a1, a2) not in (select * from t2);
+a1 a2
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+a1 a2 in_res
+1 - 00 2 - 00 NULL
+1 - 01 2 - 01 NULL
+insert into t2 values ('1 - 01', '2 - 01');
+select * from t1
+where (a1, a2) not in (select * from t2);
+a1 a2
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+a1 a2 in_res
+1 - 00 2 - 00 NULL
+1 - 01 2 - 01 0
+select * from t1
+where (a1, a2) in (select * from t2);
+a1 a2
+1 - 01 2 - 01
+select a1, a2, (a1, a2) in (select * from t2) as in_res from t1;
+a1 a2 in_res
+1 - 00 2 - 00 NULL
+1 - 01 2 - 01 1
+drop table t1, t2;
+
+Covering NULL columns
+
+this case affects only the rowid-merge algorithm
+set @@optimizer_switch="partial_match_rowid_merge=on,partial_match_table_scan=off";
+create table t1 (a1 char(8) not null, a2 char(8), a3 char(8) not null);
+create table t2 (b1 char(8) not null, b2 char(8), b3 char(8) not null);
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+insert into t2 values ('1 - 01', NULL, '3 - x1');
+insert into t2 values ('1 - 02', NULL, '3 - 02');
+insert into t2 values ('1 - 00', NULL, '3 - 00');
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+a1 a2 a3
+1 - 01 2 - 01 3 - 01
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 1
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+a1 a2 a3
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 0
+drop table t1, t2;
+create table t1 (a1 char(8), a2 char(8), a3 char(8) not null);
+create table t2 (b1 char(8), b2 char(8), b3 char(8) not null);
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+insert into t2 values (NULL, NULL, '3 - x1');
+insert into t2 values (NULL, NULL, '3 - 02');
+insert into t2 values (NULL, NULL, '3 - 00');
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+a1 a2 a3
+1 - 01 2 - 01 3 - 01
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 1
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+a1 a2 a3
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 0
+drop table t1, t2;
+
+Covering NULL row, and a NULL column
+
+create table t1 (a1 char(8) not null, a2 char(8), a3 char(8));
+create table t2 (b1 char(8), b2 char(8), b3 char(8));
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+insert into t2 values ('1 - 01', NULL, '3 - x1');
+insert into t2 values (NULL , NULL, NULL );
+insert into t2 values ('1 - 00', NULL, '3 - 00');
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+a1 a2 a3
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 NULL
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+a1 a2 a3
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 NULL
+drop table t1, t2;
+
+Covering NULL row, and covering NULL columns
+
+create table t1 (a1 char(8) not null, a2 char(8), a3 char(8));
+create table t2 (b1 char(8), b2 char(8), b3 char(8));
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+insert into t2 values (NULL, NULL, NULL);
+insert into t2 values (NULL, NULL, NULL);
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+a1 a2 a3
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 NULL
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+a1 a2 a3
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+1 - 00 2 - 00 3 - 00 NULL
+1 - 01 2 - 01 3 - 01 NULL
+drop table t1, t2;
+-------------------------------
+Part 2: Test cases for bugs.
+-------------------------------
drop table if exists t1, t2;
#
# LP BUG#608744
#
-set @save_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch="materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off";
create table t1 (a1 char(1), a2 char(1));
insert into t1 values (NULL, 'b');
@@ -11,7 +213,6 @@ insert into t2 values ('a','b'), ('c', 'd');
select * from t1 where (a1, a2) NOT IN (select b1, b2 from t2);
a1 a2
drop table t1,t2;
-set @@optimizer_switch=@save_optimizer_switch;
#
# LP BUG#601156
#
@@ -21,21 +222,19 @@ INSERT INTO t1 VALUES (4,NULL);
CREATE TABLE t2 (b1 int DEFAULT NULL, b2 int DEFAULT NULL);
INSERT INTO t2 VALUES (6,NULL);
INSERT INTO t2 VALUES (NULL,0);
-set @save_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on';
EXPLAIN EXTENDED
SELECT * FROM (SELECT * FROM t1 WHERE a1 NOT IN (SELECT b2 FROM t2)) table1;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2 100.00
+2 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00 Using where
3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (not(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b2` from `test`.`t2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery3>`.`b2`)))))))
+Note 1003 select `table1`.`a1` AS `a1`,`table1`.`a2` AS `a2` from (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (not(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b2` from `test`.`t2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery3>`.`b2`)))))))) `table1`
DROP TABLE t1, t2;
-set @@optimizer_switch=@save_optimizer_switch;
#
# LP BUG#613009 Crash in Ordered_key::get_field_idx
#
-set @save_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off';
create table t1 (a1 char(3) DEFAULT NULL, a2 char(3) DEFAULT NULL);
insert into t1 values (NULL, 'a21'), (NULL, 'a22');
@@ -46,7 +245,6 @@ id select_type table type possible_keys key key_len ref rows Extra
select * from t1 where (a1, a2) not in (select a1, a2 from t1);
a1 a2
drop table t1;
-set @@optimizer_switch=@save_optimizer_switch;
#
# LP BUG#680058 void Ordered_key::add_key(rownum_t):
# Assertion `key_buff_elements && cur_key_idx < key_buff_elements' failed
@@ -55,10 +253,123 @@ create table t1 (f1 char(1), f2 char(1));
insert into t1 values ('t', '0'), ('0', 't');
create table t2 (f3 char(1), f4 char(1));
insert into t2 values ('t', NULL), ('t', NULL), ('d', 'y');
-set @save_optimizer_switch=@@optimizer_switch;
-SET @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,semijoin=off';
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,semijoin=off';
select * from t1 where (f1, f2) not in (select * from t2);
f1 f2
0 t
-set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
+#
+# LP BUG#809245 Second assertion `bit < (map)->n_bits' with partial_match_merge
+#
+CREATE TABLE t1 (d varchar(32)) ;
+INSERT INTO t1 VALUES ('r');
+CREATE TABLE t2 ( a int, c varchar(32)) ;
+INSERT INTO t2 VALUES (5,'r');
+CREATE TABLE t3 ( a int NOT NULL , d varchar(32)) ;
+INSERT INTO t3 VALUES (10,'g');
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+EXPLAIN SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+SELECT t3.d , t2.c
+FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 SUBQUERY t3 system NULL NULL NULL NULL 1
+2 SUBQUERY t2 system NULL NULL NULL NULL 1
+SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+SELECT t3.d , t2.c
+FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+d
+r
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+EXPLAIN SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+SELECT t3.d , t2.c
+FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1
+SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+SELECT t3.d , t2.c
+FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+d
+r
+drop table t1, t2, t3;
+#
+# LP BUG#809266 Diverging results with partial_match_rowid_merge=on
+#
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (0),(0);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (6,3), (9,NULL);
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+c
+0
+0
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+c
+0
+0
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+c
+0
+0
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2
+2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+c
+0
+0
+drop table t1, t2;
+#
+# LP BUG#856152 Wrong result with NOT IN subquery and partial_match_rowid_merge
+#
+CREATE TABLE t1 ( f1 integer NOT NULL , f2 integer) ;
+INSERT INTO t1 VALUES (3,3),(48,NULL),(49,1);
+CREATE TABLE t2 ( f3 int) ;
+INSERT INTO t2 VALUES (5);
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
+SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+f3
+5
+set @@optimizer_switch='in_to_exists=on,materialization=off';
+EXPLAIN SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1
+2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
+SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+f3
+5
+drop table t1, t2;
+set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result
index 364813030b2..99d8e9d2d77 100644
--- a/mysql-test/r/subselect_sj.result
+++ b/mysql-test/r/subselect_sj.result
@@ -1,4 +1,9 @@
-drop table if exists t0, t1, t2, t3, t4, t10, t11, t12;
+drop table if exists t0, t1, t2, t3, t4, t5, t10, t11, t12;
+drop view if exists v1, v2, v3, v4;
+drop procedure if exists p1;
+set @subselect_sj_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set @save_optimizer_switch=@@optimizer_switch;
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
@@ -699,21 +704,21 @@ FROM it1 LEFT JOIN it2 ON it2.datetime_key);
int_key
0
0
-2
0
-3
0
-7
0
+0
+2
+2
+3
+5
+5
7
7
+7
+8
9
-2
9
-5
-0
-8
-5
EXPLAIN
SELECT int_key FROM ot1
WHERE int_nokey IN (SELECT it2.int_key
@@ -721,7 +726,7 @@ FROM it1 LEFT JOIN it2 ON it2.datetime_key);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY it1 index NULL int_key 4 NULL 2 Using index; Start temporary
1 PRIMARY ot1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
-1 PRIMARY it2 ALL NULL NULL NULL NULL 20 Using where; End temporary
+1 PRIMARY it2 ALL int_key,datetime_key NULL NULL NULL 20 Using where; End temporary; Using join buffer (flat, BNL join)
DROP TABLE ot1, it1, it2;
# End of BUG#38075
#
@@ -1277,9 +1282,9 @@ CREATE VIEW v1 AS SELECT 1;
EXPLAIN
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived3> system NULL NULL NULL NULL 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY <derived3> system NULL NULL NULL NULL 1
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
a a
@@ -1326,4 +1331,691 @@ x
m
c
drop table t1,t2,t3,t4;
-set @@optimizer_switch=@save_optimizer_switch;
+#
+# BUG#751484: Valgrind warning / sporadic crash in evaluate_join_record sql_select.cc:14099 with semijoin
+#
+CREATE TABLE t1 ( f10 int, f11 int, KEY (f10));
+INSERT IGNORE INTO t1 VALUES (0, 0),(0, 0);
+CREATE TABLE t3 ( f10 int);
+INSERT IGNORE INTO t3 VALUES (0);
+set @tmp_751484= @@optimizer_switch;
+set optimizer_switch='materialization=on';
+SELECT * FROM t1
+WHERE f11 IN (
+SELECT C_SQ1_alias1.f11
+FROM t1 AS C_SQ1_alias1
+JOIN t3 AS C_SQ1_alias2
+ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10
+);
+f10 f11
+0 0
+0 0
+set optimizer_switch='materialization=off';
+SELECT * FROM t1
+WHERE f11 IN (
+SELECT C_SQ1_alias1.f11
+FROM t1 AS C_SQ1_alias1
+JOIN t3 AS C_SQ1_alias2
+ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10
+);
+f10 f11
+0 0
+0 0
+set optimizer_switch=@tmp_751484;
+drop table t1, t3;
+# BUG#795530 Wrong result with subquery semijoin materialization and outer join
+# Simplified testcase that uses DuplicateElimination
+#
+create table t1 (a int);
+create table t2 (a int, b char(10));
+insert into t1 values (1),(2);
+insert into t2 values (1, 'one'), (3, 'three');
+create table t3 (b char(10));
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+explain select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where; End temporary; Using join buffer (flat, BNL join)
+select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
+b
+drop table t1, t2, t3;
+#
+# BUG#600958 RQG: Crash in optimize_semijoin_nests
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) DEFAULT NULL,
+col_date_key date DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key),
+KEY col_date_key (col_date_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (10,8,'2002-02-21',NULL);
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) DEFAULT NULL,
+col_date_key date DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key),
+KEY col_date_key (col_date_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (1,7,'1900-01-01','f');
+SELECT col_date_key FROM t1
+WHERE 5 IN (
+SELECT SUBQUERY3_t1 .col_int_key
+FROM t2 SUBQUERY3_t1
+LEFT JOIN t1 SUBQUERY3_t2 ON SUBQUERY3_t1 .col_varchar_key
+);
+col_date_key
+drop table t2, t1;
+#
+# No BUG#: Duplicate weedout check is not done for outer joins
+#
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(1),(2),(2);
+insert into t2 values (1);
+create table t0 (a int);
+insert into t0 values (1),(2);
+set @tmp_20110622= @@optimizer_switch;
+set optimizer_switch='firstmatch=off,loosescan=off,materialization=off';
+# Check DuplicateWeedout + join buffer
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+a
+1
+2
+# Check DuplicateWeedout without join buffer
+set @tmp_jcl_20110622= @@join_cache_level;
+set join_cache_level= 0;
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+a
+1
+2
+# Check FirstMatch without join buffer:
+set optimizer_switch='firstmatch=on';
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+a
+1
+2
+#
+# Now, check the same for multiple inner tables:
+alter table t2 add b int;
+update t2 set b=a;
+create table t3 as select * from t2;
+set optimizer_switch='firstmatch=off';
+set join_cache_level= 0;
+# DuplicateWeedout without join buffer
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+a
+1
+2
+set @@join_cache_level=@tmp_jcl_20110622;
+# DuplicateWeedout + join buffer
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+a
+1
+2
+# Now, let the inner join side have a 'partial' match
+select * from t3;
+a b
+1 1
+insert into t3 values(2,2);
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+a
+1
+2
+set @@optimizer_switch=@tmp_20110622;
+drop table t0, t1, t2, t3;
+#
+# BUG#802965: Crash in do_copy_not_null with semijoin=on in maria-5.3
+#
+set @save_802965= @@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=off,firstmatch=off,loosescan=off';
+CREATE TABLE t2 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t2 VALUES (19),(20);
+CREATE TABLE t1 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t1 VALUES (21),(22),(23),(24);
+SELECT *
+FROM t2 , t1
+WHERE t2.f1 IN
+(
+SELECT SQ1_alias1.f1
+FROM t1 AS SQ1_alias1 LEFT JOIN t2 AS SQ1_alias2 JOIN t2 AS SQ1_alias3 ON SQ1_alias3.f1 ON SQ1_alias3.f1
+)
+AND t1.f1 = t2.f1 ;
+f1 f1
+DROP TABLE t1, t2;
+set optimizer_switch=@save_802965;
+#
+# BUG#803365: Crash in pull_out_semijoin_tables with outer join + semijoin + derived tables in maria-5.3 with WL#106
+#
+CREATE TABLE t1 ( f1 int) ;
+INSERT INTO t1 VALUES (1),(1);
+CREATE TABLE t2 ( f2 int) ;
+INSERT INTO t2 VALUES (1),(1);
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (1),(1);
+SELECT *
+FROM t1
+WHERE t1.f1 IN (
+SELECT t2.f2
+FROM t2
+LEFT JOIN (
+SELECT *
+FROM t3
+) AS alias1
+ON alias1.f3 = t2.f2
+);
+f1
+1
+1
+DROP TABLE t1,t2,t3;
+#
+# BUG#611704: Crash in replace_where_subcondition with nested subquery and semijoin=on
+#
+CREATE TABLE t1 ( f1 int) ;
+CREATE TABLE t2 ( f1 int) ;
+CREATE TABLE t3 ( f1 int) ;
+SELECT * FROM (
+SELECT t3.*
+FROM t2 STRAIGHT_JOIN t3
+ON t3.f1
+AND (t3.f1 ) IN (
+SELECT t1.f1
+FROM t1
+)
+) AS alias1;
+f1
+DROP TABLE t1,t2,t3;
+# BUG#611704: another testcase:
+CREATE TABLE t1 ( f1 int(11), f3 varchar(1), f4 varchar(1)) ;
+CREATE TABLE t2 ( f2 int(11), KEY (f2));
+CREATE TABLE t3 ( f4 varchar(1)) ;
+PREPARE st1 FROM '
+SELECT *
+FROM t1
+STRAIGHT_JOIN ( t2 STRAIGHT_JOIN t3 ON t2.f2 )
+ON (t1.f3) IN ( SELECT f4 FROM t1 )
+';
+EXECUTE st1;
+f1 f3 f4 f2 f4
+DROP TABLE t1,t2,t3;
+#
+# BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
+# (Original testcase)
+#
+CREATE TABLE t1 (f1 int, f2 int );
+INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL);
+CREATE TABLE t2 (f2 int, f3 int );
+INSERT INTO t2 VALUES (NULL,NULL),(0,0);
+CREATE TABLE t3 ( f1 int, f3 int );
+INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0);
+CREATE TABLE t4 ( f2 int, KEY (f2) );
+INSERT INTO t4 VALUES (0),(NULL);
+CREATE VIEW v4 AS SELECT DISTINCT f2 FROM t4 ;
+# The following must not have outer joins:
+explain extended
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
+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 t4 ref f2 f2 5 test.t2.f3 2 100.00 Using index; FirstMatch(t2)
+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`))
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
+f1 f2 f3 f3
+2 0 0 0
+4 0 0 0
+4 0 0 0
+drop view v4;
+drop table t1, t2, t3, t4;
+#
+# BUG#803303: Wrong result with semijoin=on, outer join in maria-5.3-subqueries-mwl90
+#
+# Testcase#1:
+set @tmp803303= @@optimizer_switch;
+set optimizer_switch = 'semijoin=on,materialization=off,firstmatch=off,loosescan=off';
+CREATE TABLE t2 ( f1 int) ;
+INSERT IGNORE INTO t2 VALUES (6),(8);
+CREATE TABLE t1 ( f1 int, f2 int, f3 int) ;
+INSERT IGNORE INTO t1 VALUES (8,0,0),(7,0,0),(9,0,0);
+SELECT alias2.f1
+FROM t2 AS alias1
+LEFT JOIN ( t1 AS alias2 JOIN t1 AS alias3 ON alias3.f2 = alias2.f3 )
+ON alias3.f2 = alias2.f2
+WHERE alias2.f1 IN ( SELECT f1 FROM t2 AS alias4 ) ;
+f1
+8
+8
+8
+8
+8
+8
+drop table t1,t2;
+set optimizer_switch= @tmp803303;
+# Testcase #2:
+CREATE TABLE t1 ( f10 int) ;
+INSERT INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f10 int, f11 varchar(1)) ;
+INSERT INTO t2 VALUES (0,'a'),(0,'b');
+CREATE TABLE t3 ( f10 int) ;
+INSERT INTO t3 VALUES (0),(0),(0),(0),(0);
+CREATE TABLE t4 ( f10 varchar(1), f11 int) ;
+INSERT INTO t4 VALUES ('a',0),('b',0);
+SELECT * FROM t1
+LEFT JOIN ( t2 JOIN t3 ON t3.f10 = t2.f10 ) ON t1.f10 = t2.f10
+WHERE t2.f10 IN (
+SELECT t4.f11
+FROM t4
+WHERE t4.f10 != t2.f11
+);
+f10 f10 f11 f10
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+drop table t1,t2,t3,t4;
+#
+# BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
+#
+set @tmp803457=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+CREATE TABLE t1 (f1 int, f2 int );
+INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL);
+CREATE TABLE t2 (f2 int, f3 int );
+INSERT INTO t2 VALUES (NULL,NULL),(0,0);
+CREATE TABLE t3 ( f1 int, f3 int );
+INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0);
+CREATE TABLE t4 ( f2 int);
+INSERT INTO t4 VALUES (0),(NULL);
+# The following uses Duplicate Weedout, and "End temporary" must not be
+# in the middle of the inner side of an outer join:
+explain
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
+1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3 ) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
+f1 f2 f3 f3
+2 0 0 0
+4 0 0 0
+4 0 0 0
+0 NULL NULL NULL
+DROP TABLE t1, t2, t3, t4;
+set @tmp803457=@@optimizer_switch;
+#
+# BUG#818280: crash in do_copy_not_null() in maria-5.3 with semijoin
+#
+CREATE TABLE t1 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ;
+INSERT IGNORE INTO t1 VALUES (2,7),(1,3),(5,6);
+CREATE TABLE t3 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ;
+INSERT IGNORE INTO t3 VALUES (2,7),(1,3),(5,6);
+CREATE TABLE t2 ( c1 int NOT NULL , c5 int NOT NULL );
+INSERT IGNORE INTO t2 VALUES (2,2),(2,2),(5,6);
+SELECT * FROM t1 WHERE c1 IN ( SELECT t3.c1 FROM t3 LEFT JOIN t2 ON t2 .c1 = t3 .c1 WHERE t2.c5 != 0 );
+c1 c2
+2 7
+5 6
+DROP TABLE t1, t2, t3;
+#
+# BUG#834534: Assertion `0' failed in replace_where_subcondition with semijoin subquery in HAVING
+#
+CREATE TABLE t1 ( d int );
+INSERT INTO t1 VALUES (2),(2),(0),(2),(2);
+CREATE TABLE t2 ( b int );
+INSERT INTO t2 VALUES (4),(3),(3);
+CREATE TABLE t3 ( a int );
+SELECT *
+FROM t3
+WHERE (t3.a) IN (
+SELECT t1.d
+FROM t1
+HAVING ( 4 ) IN (
+SELECT t2.b
+FROM t2
+)
+);
+a
+drop table t1, t2,t3;
+#
+# BUG#834758: Wrong result with innner join, LooseScan, two-column IN() predicate
+#
+set @tmp835758=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
+CREATE TABLE t1 (b int) ;
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (6),(10);
+CREATE TABLE t3 (a int, b int, KEY (b)) ;
+INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5);
+# This used to incorrectly pick a join order of (t1, LooseScan(t3), t2):
+explain
+SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 2 Using index; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL b NULL NULL NULL 5 Using where; End temporary; Using join buffer (flat, BNL join)
+SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
+b a
+5 6
+DROP TABLE t1, t2, t3;
+set @@optimizer_switch= @tmp835758;
+#
+# BUG#834739: Wrong result with 3-way inner join, LooseScan,multipart keys
+#
+set @tmp834739=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
+CREATE TABLE t2 ( b int, c int, KEY (b)) ;
+INSERT INTO t2 VALUES (1,0),(1,0),(9,0),(1,0),(5,0);
+INSERT INTO t2 VALUES (2,0),(3,0),(8,0),(6,0),(5,0);
+CREATE TABLE t3 ( a int);
+INSERT INTO t3 VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+CREATE TABLE t4 ( a int);
+INSERT INTO t4 VALUES (0),(0),(0);
+CREATE TABLE t5 ( b int, a int , KEY (a,b)) ;
+INSERT INTO t5 VALUES (7,0),(9,0);
+explain
+SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t5 index a a 10 NULL 2 Using where; Using index; LooseScan
+1 PRIMARY t4 ALL NULL NULL NULL NULL 3
+1 PRIMARY t2 ref b b 5 test.t5.b 2 Using where; FirstMatch(t5)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
+a
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+DROP TABLE t2, t3, t4, t5;
+set @@optimizer_switch=@tmp834739;
+#
+# BUG#830993: Crash in end_read_record with derived table
+#
+set @tmp_830993=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=off,materialization=off,firstmatch=off';
+set @tmp_830993_jbs= @@join_buffer_size;
+set join_buffer_size=160;
+CREATE TABLE t1 (
+a int(11) NOT NULL AUTO_INCREMENT,
+b int(11) DEFAULT NULL,
+c int(11) DEFAULT NULL,
+d time DEFAULT NULL,
+e varchar(1) DEFAULT NULL,
+f varchar(1) DEFAULT NULL,
+PRIMARY KEY (a),
+KEY c (c),
+KEY d (d),
+KEY e (e,c)
+);
+INSERT INTO t1 VALUES (10,NULL,8,'22:55:23','x','x'),
+(11,8,7,'10:19:31','d','d'),(12,1,1,'14:40:36','r','r'),
+(13,9,7,'04:37:47','f','f'),(14,4,9,'19:34:06','y','y'),
+(15,3,NULL,'20:35:33','u','u'),(16,2,1,NULL,'m','m'),
+(17,NULL,9,'14:43:37',NULL,NULL),(18,2,2,'02:23:09','o','o'),
+(19,NULL,9,'01:22:45','w','w'),(20,6,2,'00:00:00','m','m'),
+(21,7,4,'00:13:25','q','q'),(22,2,0,'03:47:16',NULL,NULL),
+(23,5,4,'01:41:48','d','d'),(24,7,8,'00:00:00','g','g'),
+(25,6,NULL,'22:32:04','x','x'),(26,6,NULL,'16:44:14','f','f'),
+(27,2,0,'17:38:37','p','p'),(28,9,NULL,'08:46:48','j','j'),
+(29,6,8,'14:11:27','c','c');
+CREATE TABLE t2 like t1;
+INSERT INTO t2 VALUES (1,2,4,'22:34:09','v','v'),
+(2,150,62,'14:26:02','v','v'),(3,NULL,7,'14:03:03','c','c'),
+(4,2,1,'01:46:09',NULL,NULL),(5,5,0,'16:21:18','x','x'),
+(6,3,7,'18:56:33','i','i'),(7,1,7,NULL,'e','e'),
+(8,4,1,'09:29:08','p','p'),(9,NULL,7,'19:11:10','s','s'),
+(10,2,1,'11:57:26','j','j'),(11,6,5,'00:39:46','z','z'),
+(12,6,2,'03:28:15','c','c'),(13,8,0,'06:44:18','a','a'),
+(14,2,1,'14:36:39','q','q'),(15,6,8,'18:42:45','y','y'),
+(16,8,1,'02:57:29',NULL,NULL),(17,3,1,'16:46:13','r','r'),
+(18,3,9,'19:39:02','v','v'),(19,9,1,NULL,NULL,NULL),
+(20,6,5,'20:58:33','r','r');
+explain
+SELECT
+alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
+alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
+alias2.e as a2_e, alias2.f as a2_f,
+t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
+FROM
+(SELECT * FROM t2) AS alias1,
+t1 AS alias2,
+t2
+WHERE
+alias1.c IN (SELECT SQ3_alias1.b
+FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
+LIMIT 100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Start temporary
+1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary; Using join buffer (flat, BNL join)
+2 DERIVED t2 ALL NULL NULL NULL NULL 20
+create table t3 as
+SELECT
+alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
+alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
+alias2.e as a2_e, alias2.f as a2_f,
+t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
+FROM
+(SELECT * FROM t2) AS alias1,
+t1 AS alias2,
+t2
+WHERE
+alias1.c IN (SELECT SQ3_alias1.b
+FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
+LIMIT 100;
+drop table t1,t2, t3;
+set optimizer_switch=@tmp_830993;
+set join_buffer_size= @tmp_830993_jbs;
+#
+# BUG##849717: Crash in Item_func::fix_fields on second execution of a prepared statement with semijoin
+#
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int, b int) ;
+PREPARE st1 FROM "SELECT * FROM t2 LEFT JOIN t1 ON t2.a != 0 AND ('j','r') IN ( SELECT b,a FROM t3)";
+EXECUTE st1;
+a a
+EXECUTE st1;
+a a
+DROP TABLE t1, t2, t3;
+#
+# BUG#849776: Wrong result with semijoin + "Impossible where"
+#
+CREATE TABLE t1 ( b varchar(1), a integer) ;
+INSERT INTO t1 VALUES ('z',8);
+CREATE TABLE t2 ( a integer, b varchar(1)) ;
+CREATE TABLE t4 ( a integer, b varchar(1)) ;
+CREATE TABLE t5 ( a integer) ;
+INSERT INTO t5 VALUES (8);
+select * from t5 where (a) in (
+SELECT t1.a
+FROM t1 LEFT JOIN t2 ON t1.a = t2.a
+WHERE t2.b NOT IN (SELECT t4.b FROM t4 WHERE t4.b < t1.b)
+);
+a
+8
+DROP TABLE t1, t2, t4, t5;
+#
+# BUG#861147: Assertion `fixed == 1' failed in Item_func_eq::val_int() with semijoin + materialization + max_join_size
+#
+CREATE TABLE t1 ( f2 int) ;
+CREATE TABLE t2 ( f1 int, f3 int, f4 varchar(3), f5 varchar(35)) ;
+INSERT INTO t2 VALUES (4057,9,'USA','Visalia'),(3993,11,'USA','Waco'),
+(3948,14,'USA','Warren'),(3813,57,'USA','Washington'),
+(4010,11,'USA','Waterbury'),(4017,11,'USA','West Covina'),
+(4004,11,'USA','West Valley City'),(4033,10,'USA','Westminster'),
+(3842,34,'USA','Wichita'),(4018,10,'USA','Wichita Falls'),
+(3899,19,'USA','Winston-Salem'),(3914,17,'USA','Worcester'),
+(3888,20,'USA','Yonkers');
+CREATE TABLE t3 ( f3 int, f4 varchar(3)) ;
+INSERT INTO t3 VALUES (86,'USA');
+CREATE TABLE t4 ( f3 int, f4 varchar(3), f5 varchar(52)) ;
+INSERT INTO t4 VALUES (0,'RUS','Belorussian'),(0,'USA','Portuguese');
+CREATE TABLE t5 ( f2 int) ;
+CREATE TABLE t6 ( f4 varchar(3));
+INSERT INTO t6 VALUES ('RUS'),('USA');
+set @tmp_mjs_861147= @@max_join_size;
+SET max_join_size=10;
+set @tmp_os_861147= @@optimizer_switch;
+set @@optimizer_switch='semijoin=on,materialization=on';
+SELECT *
+FROM t1
+WHERE ( 1 , 3 ) IN (
+SELECT t2.f1 , MAX( t3.f3 )
+FROM t2
+JOIN t3
+WHERE t3.f4 IN (
+SELECT t4.f5
+FROM t4
+STRAIGHT_JOIN t5
+WHERE t4.f4 < t2.f5
+)
+) AND ( 'p' , 'k' ) IN (
+SELECT f4 , f4 FROM t6
+);
+ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay
+set max_join_size= @tmp_mjs_861147;
+set optimizer_switch= @tmp_os_861147;
+DROP TABLE t1,t2,t3,t4,t5,t6;
+#
+# BUG#877288: Wrong result with semijoin + materialization + multipart key
+#
+set @tmp_877288=@@optimizer_switch;
+set optimizer_switch='semijoin=ON,materialization=ON';
+CREATE TABLE t1 ( a int) ;
+INSERT INTO t1 VALUES (19),(19),(19),(20),(20),(20),(20),(20),(20);
+CREATE TABLE t2 ( b int NOT NULL , c int NOT NULL , KEY (b,c)) ;
+INSERT INTO t2 VALUES (14,1),(15,1),(16,1),(17,1),(18,1),(19,1),(20,1);
+CREATE TABLE t3 ( a int, d int) ;
+INSERT INTO t3 VALUES (19,1),(7,1),(3,1),(3,1),(20,1),(3,1),(16,1),(17,1),(9,1),(4,1),(6,1),(15,1),(17,1);
+explain
+SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 13 Using where
+2 SUBQUERY t2 ref b b 4 test.t3.a 1 Using index
+SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
+a
+19
+19
+19
+20
+20
+20
+20
+20
+20
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@tmp_877288;
+#
+# BUG#878753: Assertion '0' failed in replace_where_subcondition with derived_merge
+#
+set @tmp878753= @@optimizer_switch;
+set optimizer_switch= 'semijoin=on,derived_merge=on';
+CREATE TABLE t1 (b int(11)) ;
+CREATE TABLE t2 (c int, b int, d varchar(52) NOT NULL) ;
+CREATE TABLE t3 (b int(11)) ;
+PREPARE st1 FROM '
+ SELECT * FROM t1
+ JOIN (
+ SELECT t2.* FROM t2
+ WHERE t2.d <> "a"
+ AND t2.c IN (
+ SELECT t3.b
+ FROM t3
+ )
+ ) AS alias2
+ ON ( alias2.b = t1.b );
+';
+EXECUTE st1;
+b c b d
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@tmp878753;
+set optimizer_switch=@subselect_sj_tmp;
diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result
index 45dd12a6b77..db99d77f50c 100644
--- a/mysql-test/r/subselect_sj2.result
+++ b/mysql-test/r/subselect_sj2.result
@@ -1,3 +1,6 @@
+set @subselect_sj2_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
drop table if exists t0, t1, t2, t3;
drop view if exists v1;
create table t0 (a int);
@@ -13,6 +16,7 @@ b int,
key(b)
);
insert into t2 select a, a/2 from t0;
+insert into t2 select a+10, a+10/2 from t0;
select * from t1;
a b
1 1
@@ -30,6 +34,16 @@ a b
7 4
8 4
9 5
+10 5
+11 6
+12 7
+13 8
+14 9
+15 10
+16 11
+17 12
+18 13
+19 14
explain select * from t2 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Start temporary
@@ -48,6 +62,7 @@ pk1 char(200), pk2 char(200), pk3 char(200),
primary key(pk1, pk2, pk3)
) engine=innodb;
insert into t3 select a,a, a,a,a from t0;
+insert into t3 select a,a, a+100,a+100,a+100 from t0;
explain select * from t3 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Start temporary
@@ -55,6 +70,8 @@ id select_type table type possible_keys key key_len ref rows Extra
select * from t3 where b in (select a from t1);
a b pk1 pk2 pk3
1 1 1 1 1
+1 1 101 101 101
+2 2 102 102 102
2 2 2 2 2
set @save_max_heap_table_size= @@max_heap_table_size;
set max_heap_table_size=16384;
@@ -264,10 +281,10 @@ explain select *
from t0 where a in
(select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 10 Start temporary
-1 PRIMARY t1 index NULL a 5 NULL 10 Using index; Using join buffer (flat, BNL join)
-1 PRIMARY t2 ref a a 5 test.t1.a 1 Using where; Using index
-1 PRIMARY t3 ref a a 5 test.t1.a 1 Using where; Using index; End temporary
+1 PRIMARY t0 ALL NULL NULL NULL NULL 10
+1 PRIMARY t1 index a a 5 NULL 10 Using where; Using index
+1 PRIMARY t2 ref a a 5 test.t1.a 1 Using index
+1 PRIMARY t3 ref a a 5 test.t1.a 1 Using index; FirstMatch(t0)
drop table t0, t1,t2,t3;
CREATE TABLE t1 (
ID int(11) NOT NULL auto_increment,
@@ -417,6 +434,7 @@ create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4);
create table t1 (a int, b int, key(a));
insert into t1 select a,a from t0;
+insert into t1 select a+5,a from t0;
create table t2 (a int, b int, primary key(a));
insert into t2 select * from t1;
Table t2, unlike table t1, should be displayed as pulled out
@@ -425,11 +443,11 @@ where t0.a in ( select t1.a from t1,t2 where t2.a=t0.a and
t1.b=t2.b);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 5 100.00 Using where
-1 PRIMARY t1 ref a a 5 test.t0.a 1 100.00 Start temporary
-1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 100.00 Using where; End temporary
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 100.00
+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`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t0`.`a`) and (`test`.`t2`.`a` = `test`.`t0`.`a`))
+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`))
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
@@ -744,3 +762,118 @@ LEFT JOIN t2 AS SQ4_alias3 ON SQ4_alias3.f10
GROUP BY field2;
field2
drop table t1, t2, t3;
+#
+# BUG#849763: Wrong result with second execution of prepared statement with semijoin + view
+#
+CREATE TABLE t1 ( c varchar(1)) engine=innodb;
+INSERT INTO t1 VALUES ('r');
+CREATE TABLE t2 ( a integer, b varchar(1), c varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES (1,'r','r');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+PREPARE st1 FROM 'SELECT * FROM t2 WHERE a = SOME (SELECT a FROM v1 WHERE v1.c = t2.c)';
+EXECUTE st1;
+a b c
+1 r r
+EXECUTE st1;
+a b c
+1 r r
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+# BUG#858732: Wrong result with semijoin + loosescan + comma join
+#
+CREATE TABLE t1 (f13 int(11) NOT NULL , PRIMARY KEY (f13)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (16),(24);
+CREATE TABLE t2 (f14 int(11) NOT NULL, f12 varchar(1) NOT NULL, KEY (f12,f14)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (6,'y');
+CREATE TABLE t3 (f12 varchar(1) NOT NULL) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('r'),('s'),('t'),('v'),('w'),('x'),('y');
+# The following must use LooseScan but not join buffering
+explain
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY alias1 const PRIMARY PRIMARY 4 const 1 Using index
+1 PRIMARY alias2 index f12 f12 7 NULL 1 Using index; LooseScan
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 2 Using index; FirstMatch(alias2)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 7 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+f12
+y
+DROP TABLE t1,t2,t3;
+#
+# BUG#869012: Wrong result with semijoin + materialization + AND in WHERE
+#
+CREATE TABLE t1 (f3 varchar(1) , f4 varchar(1) ) engine=InnoDB;
+INSERT IGNORE INTO t1 VALUES ('x','x'),('x','x');
+CREATE TABLE t2 ( f4 varchar(1) ) ;
+INSERT IGNORE INTO t2 VALUES ('g');
+CREATE TABLE t3 (f4 varchar(1) ) Engine=InnoDB;
+INSERT IGNORE INTO t3 VALUES ('x');
+set @tmp_869012=@@optimizer_switch;
+SET optimizer_switch='semijoin=on,materialization=on';
+SELECT *
+FROM t1 , t2
+WHERE ( t1.f4 ) IN ( SELECT f4 FROM t3 )
+AND t2.f4 != t1.f3 ;
+f3 f4 f4
+x x g
+x x g
+set optimizer_switch= @tmp_869012;
+DROP TABLE t1,t2,t3;
+#
+# BUG#869001: Wrong result with semijoin + materialization + firstmatch + multipart key
+#
+set @tmp869001_jcl= @@join_cache_level;
+set @tmp869001_os= @@optimizer_switch;
+SET join_cache_level=0;
+SET optimizer_switch='materialization=on,semijoin=on,firstmatch=on,loosescan=off';
+CREATE TABLE t1 ( f2 int, f3 varchar(1), KEY (f3,f2)) engine=innodb;
+INSERT INTO t1 VALUES (8,'x'),(NULL,'x'),(8,'c');
+CREATE TABLE t2 ( f4 varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES ('x');
+CREATE TABLE t3 ( f1 int) engine=innodb;
+INSERT INTO t3 VALUES (8),(6),(2),(9),(6);
+CREATE TABLE t4 ( f3 varchar(1)) engine=innodb;
+INSERT INTO t4 VALUES ('p'),('j'),('c');
+SELECT *
+FROM t1 JOIN t2 ON (t2.f4 = t1.f3 )
+WHERE ( 8 ) IN (
+SELECT t3.f1 FROM t3 , t4
+);
+f2 f3 f4
+NULL x x
+8 x x
+DROP TABLE t1, t2, t3, t4;
+set join_cache_level= @tmp869001_jcl;
+set optimizer_switch= @tmp869001_os;
+#
+# Bug #881318: join cache + duplicate elimination + left join
+# with empty materialized derived inner table
+#
+CREATE TABLE t1 (b varchar(1)) ENGINE=InnoDB;
+CREATE TABLE t2 (a varchar(1)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('a');
+CREATE TABLE t3 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('c','c');
+CREATE TABLE t4 (b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t4 VALUES ('c'), ('b');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+WHERE t3.b IN (SELECT b FROM t4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+3 DERIVED t1 ALL NULL NULL NULL NULL 1
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+WHERE t3.b IN (SELECT b FROM t4);
+a b b a
+c c NULL NULL
+DROP VIEW v1;
+DROP TABLE t1,t2,t3,t4;
+# This must be the last in the file:
+set optimizer_switch=@subselect_sj2_tmp;
diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result
index 45cce630a22..05da22fc10d 100644
--- a/mysql-test/r/subselect_sj2_jcl6.result
+++ b/mysql-test/r/subselect_sj2_jcl6.result
@@ -1,10 +1,15 @@
set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set join_cache_level=6;
show variables like 'join_cache_level';
Variable_name Value
join_cache_level 6
+set @subselect_sj2_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
drop table if exists t0, t1, t2, t3;
drop view if exists v1;
create table t0 (a int);
@@ -20,6 +25,7 @@ b int,
key(b)
);
insert into t2 select a, a/2 from t0;
+insert into t2 select a+10, a+10/2 from t0;
select * from t1;
a b
1 1
@@ -37,6 +43,16 @@ a b
7 4
8 4
9 5
+10 5
+11 6
+12 7
+13 8
+14 9
+15 10
+16 11
+17 12
+18 13
+19 14
explain select * from t2 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Start temporary
@@ -55,6 +71,7 @@ pk1 char(200), pk2 char(200), pk3 char(200),
primary key(pk1, pk2, pk3)
) engine=innodb;
insert into t3 select a,a, a,a,a from t0;
+insert into t3 select a,a, a+100,a+100,a+100 from t0;
explain select * from t3 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Start temporary
@@ -62,6 +79,8 @@ id select_type table type possible_keys key key_len ref rows Extra
select * from t3 where b in (select a from t1);
a b pk1 pk2 pk3
1 1 1 1 1
+1 1 101 101 101
+2 2 102 102 102
2 2 2 2 2
set @save_max_heap_table_size= @@max_heap_table_size;
set max_heap_table_size=16384;
@@ -271,10 +290,10 @@ explain select *
from t0 where a in
(select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 10 Start temporary
-1 PRIMARY t1 index NULL a 5 NULL 10 Using index; Using join buffer (flat, BNL join)
-1 PRIMARY t2 ref a a 5 test.t1.a 1 Using where; Using index
-1 PRIMARY t3 ref a a 5 test.t1.a 1 Using where; Using index; End temporary
+1 PRIMARY t0 ALL NULL NULL NULL NULL 10
+1 PRIMARY t1 index a a 5 NULL 10 Using where; Using index
+1 PRIMARY t2 ref a a 5 test.t1.a 1 Using index
+1 PRIMARY t3 ref a a 5 test.t1.a 1 Using index; FirstMatch(t0)
drop table t0, t1,t2,t3;
CREATE TABLE t1 (
ID int(11) NOT NULL auto_increment,
@@ -424,6 +443,7 @@ create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4);
create table t1 (a int, b int, key(a));
insert into t1 select a,a from t0;
+insert into t1 select a+5,a from t0;
create table t2 (a int, b int, primary key(a));
insert into t2 select * from t1;
Table t2, unlike table t1, should be displayed as pulled out
@@ -431,12 +451,12 @@ explain extended select * from t0
where t0.a in ( select t1.a from t1,t2 where t2.a=t0.a and
t1.b=t2.b);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 5 100.00 Using where; Start temporary
-1 PRIMARY t1 ref a a 5 test.t0.a 1 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
-1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 100.00 Using where; End temporary; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+1 PRIMARY t0 ALL NULL NULL NULL NULL 5 100.00 Using where
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 100.00 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t0`.`a`) and (`test`.`t2`.`a` = `test`.`t0`.`a`))
+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`))
update t1 set a=3, b=11 where a=4;
update t2 set b=11 where a=3;
# Not anymore:
@@ -753,6 +773,121 @@ LEFT JOIN t2 AS SQ4_alias3 ON SQ4_alias3.f10
GROUP BY field2;
field2
drop table t1, t2, t3;
+#
+# BUG#849763: Wrong result with second execution of prepared statement with semijoin + view
+#
+CREATE TABLE t1 ( c varchar(1)) engine=innodb;
+INSERT INTO t1 VALUES ('r');
+CREATE TABLE t2 ( a integer, b varchar(1), c varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES (1,'r','r');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+PREPARE st1 FROM 'SELECT * FROM t2 WHERE a = SOME (SELECT a FROM v1 WHERE v1.c = t2.c)';
+EXECUTE st1;
+a b c
+1 r r
+EXECUTE st1;
+a b c
+1 r r
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+# BUG#858732: Wrong result with semijoin + loosescan + comma join
+#
+CREATE TABLE t1 (f13 int(11) NOT NULL , PRIMARY KEY (f13)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (16),(24);
+CREATE TABLE t2 (f14 int(11) NOT NULL, f12 varchar(1) NOT NULL, KEY (f12,f14)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (6,'y');
+CREATE TABLE t3 (f12 varchar(1) NOT NULL) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('r'),('s'),('t'),('v'),('w'),('x'),('y');
+# The following must use LooseScan but not join buffering
+explain
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY alias1 const PRIMARY PRIMARY 4 const 1 Using index
+1 PRIMARY alias2 index f12 f12 7 NULL 1 Using index; LooseScan
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 2 Using index; FirstMatch(alias2)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 7 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+f12
+y
+DROP TABLE t1,t2,t3;
+#
+# BUG#869012: Wrong result with semijoin + materialization + AND in WHERE
+#
+CREATE TABLE t1 (f3 varchar(1) , f4 varchar(1) ) engine=InnoDB;
+INSERT IGNORE INTO t1 VALUES ('x','x'),('x','x');
+CREATE TABLE t2 ( f4 varchar(1) ) ;
+INSERT IGNORE INTO t2 VALUES ('g');
+CREATE TABLE t3 (f4 varchar(1) ) Engine=InnoDB;
+INSERT IGNORE INTO t3 VALUES ('x');
+set @tmp_869012=@@optimizer_switch;
+SET optimizer_switch='semijoin=on,materialization=on';
+SELECT *
+FROM t1 , t2
+WHERE ( t1.f4 ) IN ( SELECT f4 FROM t3 )
+AND t2.f4 != t1.f3 ;
+f3 f4 f4
+x x g
+x x g
+set optimizer_switch= @tmp_869012;
+DROP TABLE t1,t2,t3;
+#
+# BUG#869001: Wrong result with semijoin + materialization + firstmatch + multipart key
+#
+set @tmp869001_jcl= @@join_cache_level;
+set @tmp869001_os= @@optimizer_switch;
+SET join_cache_level=0;
+SET optimizer_switch='materialization=on,semijoin=on,firstmatch=on,loosescan=off';
+CREATE TABLE t1 ( f2 int, f3 varchar(1), KEY (f3,f2)) engine=innodb;
+INSERT INTO t1 VALUES (8,'x'),(NULL,'x'),(8,'c');
+CREATE TABLE t2 ( f4 varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES ('x');
+CREATE TABLE t3 ( f1 int) engine=innodb;
+INSERT INTO t3 VALUES (8),(6),(2),(9),(6);
+CREATE TABLE t4 ( f3 varchar(1)) engine=innodb;
+INSERT INTO t4 VALUES ('p'),('j'),('c');
+SELECT *
+FROM t1 JOIN t2 ON (t2.f4 = t1.f3 )
+WHERE ( 8 ) IN (
+SELECT t3.f1 FROM t3 , t4
+);
+f2 f3 f4
+NULL x x
+8 x x
+DROP TABLE t1, t2, t3, t4;
+set join_cache_level= @tmp869001_jcl;
+set optimizer_switch= @tmp869001_os;
+#
+# Bug #881318: join cache + duplicate elimination + left join
+# with empty materialized derived inner table
+#
+CREATE TABLE t1 (b varchar(1)) ENGINE=InnoDB;
+CREATE TABLE t2 (a varchar(1)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('a');
+CREATE TABLE t3 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('c','c');
+CREATE TABLE t4 (b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t4 VALUES ('c'), ('b');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+WHERE t3.b IN (SELECT b FROM t4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where; Start temporary
+1 PRIMARY t2 hash_ALL NULL #hash#$hj 5 test.t3.a 1 Using where; Using join buffer (flat, BNLH join)
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2 Using join buffer (incremental, BNL join)
+1 PRIMARY t4 hash_ALL NULL #hash#$hj 5 test.t3.b 2 Using where; End temporary; Using join buffer (incremental, BNLH join)
+3 DERIVED t1 ALL NULL NULL NULL NULL 1
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+WHERE t3.b IN (SELECT b FROM t4);
+a b b a
+c c NULL NULL
+DROP VIEW v1;
+DROP TABLE t1,t2,t3,t4;
+# This must be the last in the file:
+set optimizer_switch=@subselect_sj2_tmp;
set join_cache_level=default;
show variables like 'join_cache_level';
Variable_name Value
diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result
index 0919e8701e2..75d61d42c31 100644
--- a/mysql-test/r/subselect_sj2_mat.result
+++ b/mysql-test/r/subselect_sj2_mat.result
@@ -1,4 +1,8 @@
set optimizer_switch='materialization=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @subselect_sj2_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
drop table if exists t0, t1, t2, t3;
drop view if exists v1;
create table t0 (a int);
@@ -14,6 +18,7 @@ b int,
key(b)
);
insert into t2 select a, a/2 from t0;
+insert into t2 select a+10, a+10/2 from t0;
select * from t1;
a b
1 1
@@ -31,6 +36,16 @@ a b
7 4
8 4
9 5
+10 5
+11 6
+12 7
+13 8
+14 9
+15 10
+16 11
+17 12
+18 13
+19 14
explain select * from t2 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
@@ -50,14 +65,17 @@ pk1 char(200), pk2 char(200), pk3 char(200),
primary key(pk1, pk2, pk3)
) engine=innodb;
insert into t3 select a,a, a,a,a from t0;
+insert into t3 select a,a, a+100,a+100,a+100 from t0;
explain select * from t3 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t3 ALL b NULL NULL NULL 10
+1 PRIMARY t3 ALL b NULL NULL NULL 20
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
select * from t3 where b in (select a from t1);
a b pk1 pk2 pk3
1 1 1 1 1
+1 1 101 101 101
+2 2 102 102 102
2 2 2 2 2
set @save_max_heap_table_size= @@max_heap_table_size;
set max_heap_table_size=16384;
@@ -102,9 +120,8 @@ set join_buffer_size= @save_join_buffer_size;
set max_heap_table_size= @save_max_heap_table_size;
explain select * from t1 where a in (select b from t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
-2 SUBQUERY t2 index b b 5 NULL 10 Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY t2 ref b b 5 test.t1.a 2 Using index; FirstMatch(t1)
select * from t1;
a b
1 1
@@ -273,10 +290,11 @@ explain select *
from t0 where a in
(select t2.a+t3.a from t1 left join (t2 join t3) on t2.a=t1.a and t3.a=t1.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 10 Start temporary
-1 PRIMARY t1 index NULL a 5 NULL 10 Using index; Using join buffer (flat, BNL join)
-1 PRIMARY t2 ref a a 5 test.t1.a 1 Using where; Using index
-1 PRIMARY t3 ref a a 5 test.t1.a 1 Using where; Using index; End temporary
+1 PRIMARY t0 ALL NULL NULL NULL NULL 10
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 9 func 1 Using where
+2 SUBQUERY t1 index a a 5 NULL 10 Using where; Using index
+2 SUBQUERY t2 ref a a 5 test.t1.a 1 Using index
+2 SUBQUERY t3 ref a a 5 test.t1.a 1 Using index
drop table t0, t1,t2,t3;
CREATE TABLE t1 (
ID int(11) NOT NULL auto_increment,
@@ -427,6 +445,7 @@ create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4);
create table t1 (a int, b int, key(a));
insert into t1 select a,a from t0;
+insert into t1 select a+5,a from t0;
create table t2 (a int, b int, primary key(a));
insert into t2 select * from t1;
Table t2, unlike table t1, should be displayed as pulled out
@@ -435,11 +454,11 @@ where t0.a in ( select t1.a from t1,t2 where t2.a=t0.a and
t1.b=t2.b);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 5 100.00 Using where
-1 PRIMARY t1 ref a a 5 test.t0.a 1 100.00 Start temporary
-1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 100.00 Using where; End temporary
+1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 100.00
+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`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t1`.`a` = `test`.`t0`.`a`) and (`test`.`t2`.`a` = `test`.`t0`.`a`))
+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`))
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
@@ -588,7 +607,7 @@ select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t3 unique_subquery PRIMARY PRIMARY 4 func 1 Using index
+2 SUBQUERY t3 index PRIMARY PRIMARY 4 NULL 10 Using index
drop table t0, t1, t2, t3;
create table t1 (a int);
insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
@@ -755,6 +774,122 @@ LEFT JOIN t2 AS SQ4_alias3 ON SQ4_alias3.f10
GROUP BY field2;
field2
drop table t1, t2, t3;
+#
+# BUG#849763: Wrong result with second execution of prepared statement with semijoin + view
+#
+CREATE TABLE t1 ( c varchar(1)) engine=innodb;
+INSERT INTO t1 VALUES ('r');
+CREATE TABLE t2 ( a integer, b varchar(1), c varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES (1,'r','r');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+PREPARE st1 FROM 'SELECT * FROM t2 WHERE a = SOME (SELECT a FROM v1 WHERE v1.c = t2.c)';
+EXECUTE st1;
+a b c
+1 r r
+EXECUTE st1;
+a b c
+1 r r
+DROP VIEW v1;
+DROP TABLE t1, t2;
+#
+# BUG#858732: Wrong result with semijoin + loosescan + comma join
+#
+CREATE TABLE t1 (f13 int(11) NOT NULL , PRIMARY KEY (f13)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (16),(24);
+CREATE TABLE t2 (f14 int(11) NOT NULL, f12 varchar(1) NOT NULL, KEY (f12,f14)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (6,'y');
+CREATE TABLE t3 (f12 varchar(1) NOT NULL) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('r'),('s'),('t'),('v'),('w'),('x'),('y');
+# The following must use LooseScan but not join buffering
+explain
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY alias1 const PRIMARY PRIMARY 4 const 1 Using index
+1 PRIMARY alias2 index f12 f12 7 NULL 1 Using index; LooseScan
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 2 Using index; FirstMatch(alias2)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 7 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+f12
+y
+DROP TABLE t1,t2,t3;
+#
+# BUG#869012: Wrong result with semijoin + materialization + AND in WHERE
+#
+CREATE TABLE t1 (f3 varchar(1) , f4 varchar(1) ) engine=InnoDB;
+INSERT IGNORE INTO t1 VALUES ('x','x'),('x','x');
+CREATE TABLE t2 ( f4 varchar(1) ) ;
+INSERT IGNORE INTO t2 VALUES ('g');
+CREATE TABLE t3 (f4 varchar(1) ) Engine=InnoDB;
+INSERT IGNORE INTO t3 VALUES ('x');
+set @tmp_869012=@@optimizer_switch;
+SET optimizer_switch='semijoin=on,materialization=on';
+SELECT *
+FROM t1 , t2
+WHERE ( t1.f4 ) IN ( SELECT f4 FROM t3 )
+AND t2.f4 != t1.f3 ;
+f3 f4 f4
+x x g
+x x g
+set optimizer_switch= @tmp_869012;
+DROP TABLE t1,t2,t3;
+#
+# BUG#869001: Wrong result with semijoin + materialization + firstmatch + multipart key
+#
+set @tmp869001_jcl= @@join_cache_level;
+set @tmp869001_os= @@optimizer_switch;
+SET join_cache_level=0;
+SET optimizer_switch='materialization=on,semijoin=on,firstmatch=on,loosescan=off';
+CREATE TABLE t1 ( f2 int, f3 varchar(1), KEY (f3,f2)) engine=innodb;
+INSERT INTO t1 VALUES (8,'x'),(NULL,'x'),(8,'c');
+CREATE TABLE t2 ( f4 varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES ('x');
+CREATE TABLE t3 ( f1 int) engine=innodb;
+INSERT INTO t3 VALUES (8),(6),(2),(9),(6);
+CREATE TABLE t4 ( f3 varchar(1)) engine=innodb;
+INSERT INTO t4 VALUES ('p'),('j'),('c');
+SELECT *
+FROM t1 JOIN t2 ON (t2.f4 = t1.f3 )
+WHERE ( 8 ) IN (
+SELECT t3.f1 FROM t3 , t4
+);
+f2 f3 f4
+NULL x x
+8 x x
+DROP TABLE t1, t2, t3, t4;
+set join_cache_level= @tmp869001_jcl;
+set optimizer_switch= @tmp869001_os;
+#
+# Bug #881318: join cache + duplicate elimination + left join
+# with empty materialized derived inner table
+#
+CREATE TABLE t1 (b varchar(1)) ENGINE=InnoDB;
+CREATE TABLE t2 (a varchar(1)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('a');
+CREATE TABLE t3 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('c','c');
+CREATE TABLE t4 (b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t4 VALUES ('c'), ('b');
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+WHERE t3.b IN (SELECT b FROM t4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
+2 SUBQUERY t4 ALL NULL NULL NULL NULL 2
+3 DERIVED t1 ALL NULL NULL NULL NULL 1
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+WHERE t3.b IN (SELECT b FROM t4);
+a b b a
+c c NULL NULL
+DROP VIEW v1;
+DROP TABLE t1,t2,t3,t4;
+# This must be the last in the file:
+set optimizer_switch=@subselect_sj2_tmp;
set optimizer_switch=default;
select @@optimizer_switch like '%materialization=on%';
@@optimizer_switch like '%materialization=on%'
diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result
index a3eca278db4..2d1da2ea953 100644
--- a/mysql-test/r/subselect_sj_jcl6.result
+++ b/mysql-test/r/subselect_sj_jcl6.result
@@ -1,12 +1,20 @@
set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
set @@optimizer_switch='join_cache_hashed=off';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set join_cache_level=6;
show variables like 'join_cache_level';
Variable_name Value
join_cache_level 6
-drop table if exists t0, t1, t2, t3, t4, t10, t11, t12;
+drop table if exists t0, t1, t2, t3, t4, t5, t10, t11, t12;
+drop view if exists v1, v2, v3, v4;
+drop procedure if exists p1;
+set @subselect_sj_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set @save_optimizer_switch=@@optimizer_switch;
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
@@ -706,22 +714,22 @@ WHERE int_nokey IN (SELECT it2.int_key
FROM it1 LEFT JOIN it2 ON it2.datetime_key);
int_key
0
-2
0
-7
-9
-9
-5
-2
0
0
0
+0
+2
+2
3
+5
+5
+7
7
7
8
-0
-5
+9
+9
EXPLAIN
SELECT int_key FROM ot1
WHERE int_nokey IN (SELECT it2.int_key
@@ -729,7 +737,7 @@ FROM it1 LEFT JOIN it2 ON it2.datetime_key);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY it1 index NULL int_key 4 NULL 2 Using index; Start temporary
1 PRIMARY ot1 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
-1 PRIMARY it2 ALL NULL NULL NULL NULL 20 Using where; End temporary; Using join buffer (incremental, BNL join)
+1 PRIMARY it2 ALL int_key,datetime_key NULL NULL NULL 20 Using where; End temporary; Using join buffer (incremental, BNL join)
DROP TABLE ot1, it1, it2;
# End of BUG#38075
#
@@ -1285,9 +1293,9 @@ CREATE VIEW v1 AS SELECT 1;
EXPLAIN
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived3> system NULL NULL NULL NULL 1
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 DEPENDENT SUBQUERY <derived3> system NULL NULL NULL NULL 1
3 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
SELECT * FROM t1 INNER JOIN t2 ON t2.a != 0 AND t2.a IN (SELECT * FROM v1);
a a
@@ -1334,7 +1342,694 @@ x
m
c
drop table t1,t2,t3,t4;
-set @@optimizer_switch=@save_optimizer_switch;
+#
+# BUG#751484: Valgrind warning / sporadic crash in evaluate_join_record sql_select.cc:14099 with semijoin
+#
+CREATE TABLE t1 ( f10 int, f11 int, KEY (f10));
+INSERT IGNORE INTO t1 VALUES (0, 0),(0, 0);
+CREATE TABLE t3 ( f10 int);
+INSERT IGNORE INTO t3 VALUES (0);
+set @tmp_751484= @@optimizer_switch;
+set optimizer_switch='materialization=on';
+SELECT * FROM t1
+WHERE f11 IN (
+SELECT C_SQ1_alias1.f11
+FROM t1 AS C_SQ1_alias1
+JOIN t3 AS C_SQ1_alias2
+ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10
+);
+f10 f11
+0 0
+0 0
+set optimizer_switch='materialization=off';
+SELECT * FROM t1
+WHERE f11 IN (
+SELECT C_SQ1_alias1.f11
+FROM t1 AS C_SQ1_alias1
+JOIN t3 AS C_SQ1_alias2
+ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10
+);
+f10 f11
+0 0
+0 0
+set optimizer_switch=@tmp_751484;
+drop table t1, t3;
+# BUG#795530 Wrong result with subquery semijoin materialization and outer join
+# Simplified testcase that uses DuplicateElimination
+#
+create table t1 (a int);
+create table t2 (a int, b char(10));
+insert into t1 values (1),(2);
+insert into t2 values (1, 'one'), (3, 'three');
+create table t3 (b char(10));
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+explain select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where; End temporary; Using join buffer (incremental, BNL join)
+select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
+b
+drop table t1, t2, t3;
+#
+# BUG#600958 RQG: Crash in optimize_semijoin_nests
+#
+CREATE TABLE t1 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) DEFAULT NULL,
+col_date_key date DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key),
+KEY col_date_key (col_date_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (10,8,'2002-02-21',NULL);
+CREATE TABLE t2 (
+pk int(11) NOT NULL AUTO_INCREMENT,
+col_int_key int(11) DEFAULT NULL,
+col_date_key date DEFAULT NULL,
+col_varchar_key varchar(1) DEFAULT NULL,
+PRIMARY KEY (pk),
+KEY col_int_key (col_int_key),
+KEY col_date_key (col_date_key),
+KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (1,7,'1900-01-01','f');
+SELECT col_date_key FROM t1
+WHERE 5 IN (
+SELECT SUBQUERY3_t1 .col_int_key
+FROM t2 SUBQUERY3_t1
+LEFT JOIN t1 SUBQUERY3_t2 ON SUBQUERY3_t1 .col_varchar_key
+);
+col_date_key
+drop table t2, t1;
+#
+# No BUG#: Duplicate weedout check is not done for outer joins
+#
+create table t1 (a int);
+create table t2 (a int);
+insert into t1 values (1),(1),(2),(2);
+insert into t2 values (1);
+create table t0 (a int);
+insert into t0 values (1),(2);
+set @tmp_20110622= @@optimizer_switch;
+set optimizer_switch='firstmatch=off,loosescan=off,materialization=off';
+# Check DuplicateWeedout + join buffer
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary; Using join buffer (incremental, BNL join)
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+a
+1
+2
+# Check DuplicateWeedout without join buffer
+set @tmp_jcl_20110622= @@join_cache_level;
+set join_cache_level= 0;
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+a
+1
+2
+# Check FirstMatch without join buffer:
+set optimizer_switch='firstmatch=on';
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+a
+1
+2
+#
+# Now, check the same for multiple inner tables:
+alter table t2 add b int;
+update t2 set b=a;
+create table t3 as select * from t2;
+set optimizer_switch='firstmatch=off';
+set join_cache_level= 0;
+# DuplicateWeedout without join buffer
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Start temporary
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+a
+1
+2
+set @@join_cache_level=@tmp_jcl_20110622;
+# DuplicateWeedout + join buffer
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 1 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where; End temporary; Using join buffer (incremental, BNL join)
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+a
+1
+2
+# Now, let the inner join side have a 'partial' match
+select * from t3;
+a b
+1 1
+insert into t3 values(2,2);
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using join buffer (incremental, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (incremental, BNL join)
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+a
+1
+2
+set @@optimizer_switch=@tmp_20110622;
+drop table t0, t1, t2, t3;
+#
+# BUG#802965: Crash in do_copy_not_null with semijoin=on in maria-5.3
+#
+set @save_802965= @@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=off,firstmatch=off,loosescan=off';
+CREATE TABLE t2 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t2 VALUES (19),(20);
+CREATE TABLE t1 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t1 VALUES (21),(22),(23),(24);
+SELECT *
+FROM t2 , t1
+WHERE t2.f1 IN
+(
+SELECT SQ1_alias1.f1
+FROM t1 AS SQ1_alias1 LEFT JOIN t2 AS SQ1_alias2 JOIN t2 AS SQ1_alias3 ON SQ1_alias3.f1 ON SQ1_alias3.f1
+)
+AND t1.f1 = t2.f1 ;
+f1 f1
+DROP TABLE t1, t2;
+set optimizer_switch=@save_802965;
+#
+# BUG#803365: Crash in pull_out_semijoin_tables with outer join + semijoin + derived tables in maria-5.3 with WL#106
+#
+CREATE TABLE t1 ( f1 int) ;
+INSERT INTO t1 VALUES (1),(1);
+CREATE TABLE t2 ( f2 int) ;
+INSERT INTO t2 VALUES (1),(1);
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (1),(1);
+SELECT *
+FROM t1
+WHERE t1.f1 IN (
+SELECT t2.f2
+FROM t2
+LEFT JOIN (
+SELECT *
+FROM t3
+) AS alias1
+ON alias1.f3 = t2.f2
+);
+f1
+1
+1
+DROP TABLE t1,t2,t3;
+#
+# BUG#611704: Crash in replace_where_subcondition with nested subquery and semijoin=on
+#
+CREATE TABLE t1 ( f1 int) ;
+CREATE TABLE t2 ( f1 int) ;
+CREATE TABLE t3 ( f1 int) ;
+SELECT * FROM (
+SELECT t3.*
+FROM t2 STRAIGHT_JOIN t3
+ON t3.f1
+AND (t3.f1 ) IN (
+SELECT t1.f1
+FROM t1
+)
+) AS alias1;
+f1
+DROP TABLE t1,t2,t3;
+# BUG#611704: another testcase:
+CREATE TABLE t1 ( f1 int(11), f3 varchar(1), f4 varchar(1)) ;
+CREATE TABLE t2 ( f2 int(11), KEY (f2));
+CREATE TABLE t3 ( f4 varchar(1)) ;
+PREPARE st1 FROM '
+SELECT *
+FROM t1
+STRAIGHT_JOIN ( t2 STRAIGHT_JOIN t3 ON t2.f2 )
+ON (t1.f3) IN ( SELECT f4 FROM t1 )
+';
+EXECUTE st1;
+f1 f3 f4 f2 f4
+DROP TABLE t1,t2,t3;
+#
+# BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
+# (Original testcase)
+#
+CREATE TABLE t1 (f1 int, f2 int );
+INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL);
+CREATE TABLE t2 (f2 int, f3 int );
+INSERT INTO t2 VALUES (NULL,NULL),(0,0);
+CREATE TABLE t3 ( f1 int, f3 int );
+INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0);
+CREATE TABLE t4 ( f2 int, KEY (f2) );
+INSERT INTO t4 VALUES (0),(NULL);
+CREATE VIEW v4 AS SELECT DISTINCT f2 FROM t4 ;
+# The following must not have outer joins:
+explain extended
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
+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 t4 ref f2 f2 5 test.t2.f3 2 100.00 Using index; FirstMatch(t2)
+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 (incremental, 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`))
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
+f1 f2 f3 f3
+2 0 0 0
+4 0 0 0
+4 0 0 0
+drop view v4;
+drop table t1, t2, t3, t4;
+#
+# BUG#803303: Wrong result with semijoin=on, outer join in maria-5.3-subqueries-mwl90
+#
+# Testcase#1:
+set @tmp803303= @@optimizer_switch;
+set optimizer_switch = 'semijoin=on,materialization=off,firstmatch=off,loosescan=off';
+CREATE TABLE t2 ( f1 int) ;
+INSERT IGNORE INTO t2 VALUES (6),(8);
+CREATE TABLE t1 ( f1 int, f2 int, f3 int) ;
+INSERT IGNORE INTO t1 VALUES (8,0,0),(7,0,0),(9,0,0);
+SELECT alias2.f1
+FROM t2 AS alias1
+LEFT JOIN ( t1 AS alias2 JOIN t1 AS alias3 ON alias3.f2 = alias2.f3 )
+ON alias3.f2 = alias2.f2
+WHERE alias2.f1 IN ( SELECT f1 FROM t2 AS alias4 ) ;
+f1
+8
+8
+8
+8
+8
+8
+drop table t1,t2;
+set optimizer_switch= @tmp803303;
+# Testcase #2:
+CREATE TABLE t1 ( f10 int) ;
+INSERT INTO t1 VALUES (0),(0);
+CREATE TABLE t2 ( f10 int, f11 varchar(1)) ;
+INSERT INTO t2 VALUES (0,'a'),(0,'b');
+CREATE TABLE t3 ( f10 int) ;
+INSERT INTO t3 VALUES (0),(0),(0),(0),(0);
+CREATE TABLE t4 ( f10 varchar(1), f11 int) ;
+INSERT INTO t4 VALUES ('a',0),('b',0);
+SELECT * FROM t1
+LEFT JOIN ( t2 JOIN t3 ON t3.f10 = t2.f10 ) ON t1.f10 = t2.f10
+WHERE t2.f10 IN (
+SELECT t4.f11
+FROM t4
+WHERE t4.f10 != t2.f11
+);
+f10 f10 f11 f10
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+0 0 b 0
+0 0 b 0
+0 0 a 0
+0 0 a 0
+drop table t1,t2,t3,t4;
+#
+# BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
+#
+set @tmp803457=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+CREATE TABLE t1 (f1 int, f2 int );
+INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL);
+CREATE TABLE t2 (f2 int, f3 int );
+INSERT INTO t2 VALUES (NULL,NULL),(0,0);
+CREATE TABLE t3 ( f1 int, f3 int );
+INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0);
+CREATE TABLE t4 ( f2 int);
+INSERT INTO t4 VALUES (0),(NULL);
+# The following uses Duplicate Weedout, and "End temporary" must not be
+# in the middle of the inner side of an outer join:
+explain
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (incremental, BNL join)
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3 ) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
+f1 f2 f3 f3
+2 0 0 0
+4 0 0 0
+4 0 0 0
+0 NULL NULL NULL
+DROP TABLE t1, t2, t3, t4;
+set @tmp803457=@@optimizer_switch;
+#
+# BUG#818280: crash in do_copy_not_null() in maria-5.3 with semijoin
+#
+CREATE TABLE t1 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ;
+INSERT IGNORE INTO t1 VALUES (2,7),(1,3),(5,6);
+CREATE TABLE t3 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ;
+INSERT IGNORE INTO t3 VALUES (2,7),(1,3),(5,6);
+CREATE TABLE t2 ( c1 int NOT NULL , c5 int NOT NULL );
+INSERT IGNORE INTO t2 VALUES (2,2),(2,2),(5,6);
+SELECT * FROM t1 WHERE c1 IN ( SELECT t3.c1 FROM t3 LEFT JOIN t2 ON t2 .c1 = t3 .c1 WHERE t2.c5 != 0 );
+c1 c2
+2 7
+5 6
+DROP TABLE t1, t2, t3;
+#
+# BUG#834534: Assertion `0' failed in replace_where_subcondition with semijoin subquery in HAVING
+#
+CREATE TABLE t1 ( d int );
+INSERT INTO t1 VALUES (2),(2),(0),(2),(2);
+CREATE TABLE t2 ( b int );
+INSERT INTO t2 VALUES (4),(3),(3);
+CREATE TABLE t3 ( a int );
+SELECT *
+FROM t3
+WHERE (t3.a) IN (
+SELECT t1.d
+FROM t1
+HAVING ( 4 ) IN (
+SELECT t2.b
+FROM t2
+)
+);
+a
+drop table t1, t2,t3;
+#
+# BUG#834758: Wrong result with innner join, LooseScan, two-column IN() predicate
+#
+set @tmp835758=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
+CREATE TABLE t1 (b int) ;
+INSERT INTO t1 VALUES (1),(5);
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (6),(10);
+CREATE TABLE t3 (a int, b int, KEY (b)) ;
+INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5);
+# This used to incorrectly pick a join order of (t1, LooseScan(t3), t2):
+explain
+SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY t2 index PRIMARY PRIMARY 4 NULL 2 Using index; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL b NULL NULL NULL 5 Using where; End temporary; Using join buffer (incremental, BNL join)
+SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
+b a
+5 6
+DROP TABLE t1, t2, t3;
+set @@optimizer_switch= @tmp835758;
+#
+# BUG#834739: Wrong result with 3-way inner join, LooseScan,multipart keys
+#
+set @tmp834739=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
+CREATE TABLE t2 ( b int, c int, KEY (b)) ;
+INSERT INTO t2 VALUES (1,0),(1,0),(9,0),(1,0),(5,0);
+INSERT INTO t2 VALUES (2,0),(3,0),(8,0),(6,0),(5,0);
+CREATE TABLE t3 ( a int);
+INSERT INTO t3 VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+CREATE TABLE t4 ( a int);
+INSERT INTO t4 VALUES (0),(0),(0);
+CREATE TABLE t5 ( b int, a int , KEY (a,b)) ;
+INSERT INTO t5 VALUES (7,0),(9,0);
+explain
+SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t5 index a a 10 NULL 2 Using where; Using index; LooseScan
+1 PRIMARY t4 ALL NULL NULL NULL NULL 3
+1 PRIMARY t2 ref b b 5 test.t5.b 2 Using where; FirstMatch(t5)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; Using join buffer (flat, BNL join)
+SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
+a
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+0
+DROP TABLE t2, t3, t4, t5;
+set @@optimizer_switch=@tmp834739;
+#
+# BUG#830993: Crash in end_read_record with derived table
+#
+set @tmp_830993=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=off,materialization=off,firstmatch=off';
+set @tmp_830993_jbs= @@join_buffer_size;
+set join_buffer_size=160;
+CREATE TABLE t1 (
+a int(11) NOT NULL AUTO_INCREMENT,
+b int(11) DEFAULT NULL,
+c int(11) DEFAULT NULL,
+d time DEFAULT NULL,
+e varchar(1) DEFAULT NULL,
+f varchar(1) DEFAULT NULL,
+PRIMARY KEY (a),
+KEY c (c),
+KEY d (d),
+KEY e (e,c)
+);
+INSERT INTO t1 VALUES (10,NULL,8,'22:55:23','x','x'),
+(11,8,7,'10:19:31','d','d'),(12,1,1,'14:40:36','r','r'),
+(13,9,7,'04:37:47','f','f'),(14,4,9,'19:34:06','y','y'),
+(15,3,NULL,'20:35:33','u','u'),(16,2,1,NULL,'m','m'),
+(17,NULL,9,'14:43:37',NULL,NULL),(18,2,2,'02:23:09','o','o'),
+(19,NULL,9,'01:22:45','w','w'),(20,6,2,'00:00:00','m','m'),
+(21,7,4,'00:13:25','q','q'),(22,2,0,'03:47:16',NULL,NULL),
+(23,5,4,'01:41:48','d','d'),(24,7,8,'00:00:00','g','g'),
+(25,6,NULL,'22:32:04','x','x'),(26,6,NULL,'16:44:14','f','f'),
+(27,2,0,'17:38:37','p','p'),(28,9,NULL,'08:46:48','j','j'),
+(29,6,8,'14:11:27','c','c');
+CREATE TABLE t2 like t1;
+INSERT INTO t2 VALUES (1,2,4,'22:34:09','v','v'),
+(2,150,62,'14:26:02','v','v'),(3,NULL,7,'14:03:03','c','c'),
+(4,2,1,'01:46:09',NULL,NULL),(5,5,0,'16:21:18','x','x'),
+(6,3,7,'18:56:33','i','i'),(7,1,7,NULL,'e','e'),
+(8,4,1,'09:29:08','p','p'),(9,NULL,7,'19:11:10','s','s'),
+(10,2,1,'11:57:26','j','j'),(11,6,5,'00:39:46','z','z'),
+(12,6,2,'03:28:15','c','c'),(13,8,0,'06:44:18','a','a'),
+(14,2,1,'14:36:39','q','q'),(15,6,8,'18:42:45','y','y'),
+(16,8,1,'02:57:29',NULL,NULL),(17,3,1,'16:46:13','r','r'),
+(18,3,9,'19:39:02','v','v'),(19,9,1,NULL,NULL,NULL),
+(20,6,5,'20:58:33','r','r');
+explain
+SELECT
+alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
+alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
+alias2.e as a2_e, alias2.f as a2_f,
+t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
+FROM
+(SELECT * FROM t2) AS alias1,
+t1 AS alias2,
+t2
+WHERE
+alias1.c IN (SELECT SQ3_alias1.b
+FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
+LIMIT 100;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Start temporary
+1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
+1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (incremental, BNL join)
+1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary; Using join buffer (incremental, BNL join)
+2 DERIVED t2 ALL NULL NULL NULL NULL 20
+create table t3 as
+SELECT
+alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
+alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
+alias2.e as a2_e, alias2.f as a2_f,
+t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
+FROM
+(SELECT * FROM t2) AS alias1,
+t1 AS alias2,
+t2
+WHERE
+alias1.c IN (SELECT SQ3_alias1.b
+FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
+LIMIT 100;
+drop table t1,t2, t3;
+set optimizer_switch=@tmp_830993;
+set join_buffer_size= @tmp_830993_jbs;
+#
+# BUG##849717: Crash in Item_func::fix_fields on second execution of a prepared statement with semijoin
+#
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int, b int) ;
+PREPARE st1 FROM "SELECT * FROM t2 LEFT JOIN t1 ON t2.a != 0 AND ('j','r') IN ( SELECT b,a FROM t3)";
+EXECUTE st1;
+a a
+EXECUTE st1;
+a a
+DROP TABLE t1, t2, t3;
+#
+# BUG#849776: Wrong result with semijoin + "Impossible where"
+#
+CREATE TABLE t1 ( b varchar(1), a integer) ;
+INSERT INTO t1 VALUES ('z',8);
+CREATE TABLE t2 ( a integer, b varchar(1)) ;
+CREATE TABLE t4 ( a integer, b varchar(1)) ;
+CREATE TABLE t5 ( a integer) ;
+INSERT INTO t5 VALUES (8);
+select * from t5 where (a) in (
+SELECT t1.a
+FROM t1 LEFT JOIN t2 ON t1.a = t2.a
+WHERE t2.b NOT IN (SELECT t4.b FROM t4 WHERE t4.b < t1.b)
+);
+a
+8
+DROP TABLE t1, t2, t4, t5;
+#
+# BUG#861147: Assertion `fixed == 1' failed in Item_func_eq::val_int() with semijoin + materialization + max_join_size
+#
+CREATE TABLE t1 ( f2 int) ;
+CREATE TABLE t2 ( f1 int, f3 int, f4 varchar(3), f5 varchar(35)) ;
+INSERT INTO t2 VALUES (4057,9,'USA','Visalia'),(3993,11,'USA','Waco'),
+(3948,14,'USA','Warren'),(3813,57,'USA','Washington'),
+(4010,11,'USA','Waterbury'),(4017,11,'USA','West Covina'),
+(4004,11,'USA','West Valley City'),(4033,10,'USA','Westminster'),
+(3842,34,'USA','Wichita'),(4018,10,'USA','Wichita Falls'),
+(3899,19,'USA','Winston-Salem'),(3914,17,'USA','Worcester'),
+(3888,20,'USA','Yonkers');
+CREATE TABLE t3 ( f3 int, f4 varchar(3)) ;
+INSERT INTO t3 VALUES (86,'USA');
+CREATE TABLE t4 ( f3 int, f4 varchar(3), f5 varchar(52)) ;
+INSERT INTO t4 VALUES (0,'RUS','Belorussian'),(0,'USA','Portuguese');
+CREATE TABLE t5 ( f2 int) ;
+CREATE TABLE t6 ( f4 varchar(3));
+INSERT INTO t6 VALUES ('RUS'),('USA');
+set @tmp_mjs_861147= @@max_join_size;
+SET max_join_size=10;
+set @tmp_os_861147= @@optimizer_switch;
+set @@optimizer_switch='semijoin=on,materialization=on';
+SELECT *
+FROM t1
+WHERE ( 1 , 3 ) IN (
+SELECT t2.f1 , MAX( t3.f3 )
+FROM t2
+JOIN t3
+WHERE t3.f4 IN (
+SELECT t4.f5
+FROM t4
+STRAIGHT_JOIN t5
+WHERE t4.f4 < t2.f5
+)
+) AND ( 'p' , 'k' ) IN (
+SELECT f4 , f4 FROM t6
+);
+ERROR 42000: The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay
+set max_join_size= @tmp_mjs_861147;
+set optimizer_switch= @tmp_os_861147;
+DROP TABLE t1,t2,t3,t4,t5,t6;
+#
+# BUG#877288: Wrong result with semijoin + materialization + multipart key
+#
+set @tmp_877288=@@optimizer_switch;
+set optimizer_switch='semijoin=ON,materialization=ON';
+CREATE TABLE t1 ( a int) ;
+INSERT INTO t1 VALUES (19),(19),(19),(20),(20),(20),(20),(20),(20);
+CREATE TABLE t2 ( b int NOT NULL , c int NOT NULL , KEY (b,c)) ;
+INSERT INTO t2 VALUES (14,1),(15,1),(16,1),(17,1),(18,1),(19,1),(20,1);
+CREATE TABLE t3 ( a int, d int) ;
+INSERT INTO t3 VALUES (19,1),(7,1),(3,1),(3,1),(20,1),(3,1),(16,1),(17,1),(9,1),(4,1),(6,1),(15,1),(17,1);
+explain
+SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 9
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
+2 SUBQUERY t3 ALL NULL NULL NULL NULL 13 Using where
+2 SUBQUERY t2 ref b b 4 test.t3.a 1 Using index
+SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
+a
+19
+19
+19
+20
+20
+20
+20
+20
+20
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@tmp_877288;
+#
+# BUG#878753: Assertion '0' failed in replace_where_subcondition with derived_merge
+#
+set @tmp878753= @@optimizer_switch;
+set optimizer_switch= 'semijoin=on,derived_merge=on';
+CREATE TABLE t1 (b int(11)) ;
+CREATE TABLE t2 (c int, b int, d varchar(52) NOT NULL) ;
+CREATE TABLE t3 (b int(11)) ;
+PREPARE st1 FROM '
+ SELECT * FROM t1
+ JOIN (
+ SELECT t2.* FROM t2
+ WHERE t2.d <> "a"
+ AND t2.c IN (
+ SELECT t3.b
+ FROM t3
+ )
+ ) AS alias2
+ ON ( alias2.b = t1.b );
+';
+EXECUTE st1;
+b c b d
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@tmp878753;
+set optimizer_switch=@subselect_sj_tmp;
#
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
#
@@ -1342,6 +2037,8 @@ CREATE TABLE t0 (a INT);
INSERT INTO t0 VALUES (0),(1),(2),(3),(4);
CREATE TABLE t1 (a INT, b INT, KEY(a));
INSERT INTO t1 SELECT a, a from t0;
+INSERT INTO t1 SELECT a+5, a from t0;
+INSERT INTO t1 SELECT a+10, a from t0;
CREATE TABLE t2 (a INT, b INT, PRIMARY KEY(a));
INSERT INTO t2 SELECT * FROM t1;
UPDATE t1 SET a=3, b=11 WHERE a=4;
diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result
index f1e26561f4c..465e482fb66 100644
--- a/mysql-test/r/subselect_sj_mat.result
+++ b/mysql-test/r/subselect_sj_mat.result
@@ -1,4 +1,8 @@
-drop table if exists t1, t2, t3, t1i, t2i, t3i;
+set @subselect_sj_mat_tmp= @@optimizer_switch;
+set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on');
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @optimizer_switch_local_default= @@optimizer_switch;
+drop table if exists t1, t2, t3, t4, t5, t1i, t2i, t3i;
drop table if exists columns;
drop table if exists t1_16, t2_16, t3_16;
drop view if exists v1, v2, v1m, v2m;
@@ -190,28 +194,34 @@ a1 a2
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1);
ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch='default,semijoin=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
prepare st1 from
"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
execute st1;
a1 a2
1 - 01 2 - 01
1 - 02 2 - 02
-set @@optimizer_switch='default,semijoin=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
execute st1;
a1 a2
1 - 01 2 - 01
1 - 02 2 - 02
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
prepare st1 from
"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
-set @@optimizer_switch='default,semijoin=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
execute st1;
a1 a2
1 - 01 2 - 01
1 - 02 2 - 02
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
execute st1;
a1 a2
1 - 01 2 - 01
@@ -434,7 +444,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`.`a2`,`test`.`t1`.`a1`>(<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`.`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'))
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
@@ -458,7 +468,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`.`a2`,`test`.`t1`.`a1`>(<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`.`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'))
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
@@ -511,7 +521,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
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (((<cache>(`test`.`t1`.`a1`) = '1 - 01') or isnull('1 - 01')) and ((<cache>(`test`.`t1`.`a2`) = '2 - 01') or isnull('2 - 01')) and <is_not_null_test>('1 - 01') and <is_not_null_test>('2 - 01')))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (((<cache>(`test`.`t1`.`a1`) = '1 - 01') or isnull('1 - 01')) and ((<cache>(`test`.`t1`.`a2`) = '2 - 01') or isnull('2 - 01')) and <is_not_null_test>('1 - 01') and <is_not_null_test>('2 - 01')))))
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
a1 a2
1 - 01 2 - 01
@@ -521,7 +531,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
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a2`,`test`.`t1`.`a1`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (((<cache>(`test`.`t1`.`a1`) = '1 - 01') or isnull('1 - 01')) and ((<cache>(`test`.`t1`.`a2`) = '2 - 01') or isnull('2 - 01')) and <is_not_null_test>('1 - 01') and <is_not_null_test>('2 - 01')))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select '1 - 01','2 - 01' having (((<cache>(`test`.`t1`.`a1`) = '1 - 01') or isnull('1 - 01')) and ((<cache>(`test`.`t1`.`a2`) = '2 - 01') or isnull('2 - 01')) and <is_not_null_test>('1 - 01') and <is_not_null_test>('2 - 01')))))
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01' from dual);
a1 a2
1 - 01 2 - 01
@@ -846,15 +856,16 @@ explain extended select left(a1,7), left(a2,7)
from t1_1024
where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
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
-1 PRIMARY <subquery2> eq_ref NULL distinct_key 15 func,func 1 100.00 Using where
-2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Start temporary
+1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; 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`.`b1` > '0') and (`test`.`t1_1024`.`a1` = substr(`test`.`t2_1024`.`b1`,1,1024)))
select left(a1,7), left(a2,7)
from t1_1024
where a1 in (select substring(b1,1,1024) from t2_1024 where b1 > '0');
left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
explain extended select left(a1,7), left(a2,7)
from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2);
@@ -940,15 +951,16 @@ explain extended select left(a1,7), left(a2,7)
from t1_1025
where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
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
-1 PRIMARY <subquery2> eq_ref NULL distinct_key 15 func,func 1 100.00 Using where
-2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Start temporary
+1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; 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`.`b1` > '0') and (`test`.`t1_1025`.`a1` = substr(`test`.`t2_1025`.`b1`,1,1025)))
select left(a1,7), left(a2,7)
from t1_1025
where a1 in (select substring(b1,1,1025) from t2_1025 where b1 > '0');
left(a1,7) left(a2,7)
+1 - 01x 2 - 01x
+1 - 02x 2 - 02x
explain extended select left(a1,7), left(a2,7)
from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2);
@@ -1134,7 +1146,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t1.b' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`,max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`c` from `test`.`t2` where (<nop>(<expr_cache><`test`.`t2`.`d`,max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where (max(`test`.`t1`.`b`) = `test`.`t3`.`e`) having (<cache>(`test`.`t2`.`d`) >= <ref_null_helper>(`test`.`t3`.`e`)))))) and (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`,`test`.`t1`.`b`,max(`test`.`t1`.`b`),max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`c` from `test`.`t2` where (<nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`,max(`test`.`t1`.`b`),max(`test`.`t1`.`b`)>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where (max(`test`.`t1`.`b`) = `test`.`t3`.`e`) having (<cache>(`test`.`t2`.`d`) >= <ref_null_helper>(`test`.`t3`.`e`)))))) and (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`)))))
select a from t1 group by a
having a in (select c from t2 where d >= some(select e from t3 where max(b)=e));
a
@@ -1182,21 +1194,26 @@ select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
min(a1)
NULL
set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+1 PRIMARY t1 system NULL NULL NULL NULL 1
2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
min(a1)
-set @@optimizer_switch='default,semijoin=off';
+NULL
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
explain select min(a1) from t1 where 7 in (select b1 from t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+1 PRIMARY t1 system NULL NULL NULL NULL 1
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
select min(a1) from t1 where 7 in (select b1 from t2);
min(a1)
-set @@optimizer_switch='default,materialization=off';
+NULL
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
# with MariaDB and MWL#90, this particular case is solved:
explain select min(a1) from t1 where 7 in (select b1 from t2);
id select_type table type possible_keys key key_len ref rows Extra
@@ -1207,10 +1224,11 @@ NULL
# but when we go around MWL#90 code, the problem still shows up:
explain select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+1 PRIMARY t1 system NULL NULL NULL NULL 1
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
select min(a1) from t1 where 7 in (select b1 from t2) or 2> 4;
min(a1)
+NULL
set @@optimizer_switch= @save_optimizer_switch;
drop table t1,t2;
create table t1 (a char(2), b varchar(10));
@@ -1229,6 +1247,230 @@ a b
execute st1;
a b
drop table t1;
+#
+# BUG#49630: Segfault in select_describe() with double
+# nested subquery and materialization
+#
+CREATE TABLE t1 (t1i int);
+CREATE TABLE t2 (t2i int);
+CREATE TABLE t3 (t3i int);
+CREATE TABLE t4 (t4i int);
+INSERT INTO t1 VALUES (1);
+INSERT INTO t2 VALUES (1),(2);
+INSERT INTO t3 VALUES (1),(2);
+INSERT INTO t4 VALUES (1),(2);
+
+EXPLAIN
+SELECT t1i
+FROM t1 JOIN t4 ON t1i=t4i
+WHERE (t1i) IN (
+SELECT t2i
+FROM t2
+WHERE (t2i) IN (
+SELECT t3i
+FROM t3
+GROUP BY t3i
+)
+);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 5 const 1 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using temporary
+DROP TABLE t1,t2,t3,t4;
+CREATE TABLE t1 (
+pk INTEGER AUTO_INCREMENT,
+col_int_nokey INTEGER,
+col_int_key INTEGER,
+col_varchar_key VARCHAR(1),
+PRIMARY KEY (pk),
+KEY (col_int_key),
+KEY (col_varchar_key, col_int_key)
+)
+;
+INSERT INTO t1 (
+col_int_key, col_int_nokey, col_varchar_key
+)
+VALUES
+(2, NULL, 'w'),
+(9, 7, 'm'),
+(3, 9, 'm'),
+(9, 7, 'k'),
+(NULL, 4, 'r'),
+(9, 2, 't'),
+(3, 6, 'j'),
+(8, 8, 'u'),
+(8, NULL, 'h'),
+(53, 5, 'o'),
+(0, NULL, NULL),
+(5, 6, 'k'),
+(166, 188, 'e'),
+(3, 2, 'n'),
+(0, 1, 't'),
+(1, 1, 'c'),
+(9, 0, 'm'),
+(5, 9, 'y'),
+(6, NULL, 'f'),
+(2, 4, 'd')
+;
+SELECT table2.col_varchar_key AS field1,
+table2.col_int_nokey AS field2
+FROM ( t1 AS table1 LEFT OUTER JOIN t1 AS table2
+ON (table2.col_varchar_key = table1.col_varchar_key ) )
+WHERE table1.pk = 6
+HAVING ( field2 ) IN
+( SELECT SUBQUERY2_t2.col_int_nokey AS SUBQUERY2_field2
+FROM ( t1 AS SUBQUERY2_t1 JOIN t1 AS SUBQUERY2_t2
+ON (SUBQUERY2_t2.col_varchar_key = SUBQUERY2_t1.col_varchar_key ) ) )
+ORDER BY field2
+;
+field1 field2
+t 1
+t 2
+drop table t1;
+#
+# BUG#53103: MTR test ps crashes in optimize_cond()
+# when running with --debug
+#
+CREATE TABLE t1(track varchar(15));
+INSERT INTO t1 VALUES ('CAD'), ('CAD');
+PREPARE STMT FROM
+"SELECT 1 FROM t1
+ WHERE
+ track IN (SELECT track FROM t1
+ GROUP BY track
+ HAVING track>='CAD')";
+EXECUTE STMT ;
+1
+1
+1
+EXECUTE STMT ;
+1
+1
+1
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
+# End of BUG#53103
+#
+# BUG#54511 - Assertion failed: cache != 0L in file
+# sql_select.cc::sub_select_cache on HAVING
+#
+CREATE TABLE t1 (i int(11));
+CREATE TABLE t2 (c char(1));
+CREATE TABLE t3 (c char(1));
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES ('a'), ('b');
+INSERT INTO t3 VALUES ('x'), ('y');
+SELECT COUNT( i ),i
+FROM t1
+HAVING ('c')
+IN (SELECT t2.c FROM (t2 JOIN t3));
+COUNT( i ) i
+DROP TABLE t1,t2,t3;
+# End BUG#54511
+#
+# BUG#56367 - Assertion exec_method != EXEC_MATERIALIZATION...
+# on subquery in FROM
+#
+CREATE TABLE t1 (a INTEGER);
+CREATE TABLE t2 (b INTEGER);
+INSERT INTO t2 VALUES (1);
+explain SELECT a FROM (
+SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
+SELECT a FROM (
+SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+a
+DROP TABLE t1, t2;
+# End BUG#56367
+#
+# Bug#59833 - materialization=on/off leads to different result set
+# when using IN
+#
+CREATE TABLE t1 (
+pk int NOT NULL,
+f1 int DEFAULT NULL,
+PRIMARY KEY (pk)
+) ENGINE=MyISAM;
+CREATE TABLE t2 (
+pk int NOT NULL,
+f1 int DEFAULT NULL,
+PRIMARY KEY (pk)
+) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (10,0);
+INSERT INTO t2 VALUES (10,0),(11,0);
+explain SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 system NULL NULL NULL NULL 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 const 1
+1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+2 SUBQUERY t1 system NULL NULL NULL NULL 1
+SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+f1 pk pk
+DROP TABLE t1, t2;
+# End Bug#59833
+#
+# Bug#11852644 - CRASH IN ITEM_REF::SAVE_IN_FIELD ON SELECT DISTINCT
+#
+CREATE TABLE t1 (
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_varchar_key (col_varchar_key))
+;
+INSERT INTO t1 VALUES
+('v','v'),('r','r');
+CREATE TABLE t2 (
+col_varchar_key varchar(1) DEFAULT NULL,
+col_varchar_nokey varchar(1) DEFAULT NULL,
+KEY col_varchar_key(col_varchar_key))
+;
+INSERT INTO t2 VALUES
+('r','r'),('c','c');
+CREATE VIEW v3 AS SELECT * FROM t2;
+SELECT DISTINCT alias2.col_varchar_key
+FROM t1 AS alias1 JOIN v3 AS alias2
+ON alias2.col_varchar_key = alias1.col_varchar_key
+HAVING col_varchar_key IN (SELECT col_varchar_nokey FROM t2)
+;
+col_varchar_key
+r
+DROP TABLE t1, t2;
+DROP VIEW v3;
+# End Bug#11852644
+
+# Bug#12668294 - GROUP BY ON EMPTY RESULT GIVES EMPTY ROW
+# INSTEAD OF NULL WHEN MATERIALIZATION ON
+
+CREATE TABLE t1 (col_int_nokey INT) ENGINE=MEMORY;
+CREATE TABLE t2 (col_int_nokey INT) ENGINE=MEMORY;
+INSERT INTO t2 VALUES (8),(7);
+CREATE TABLE t3 (col_int_nokey INT) ENGINE=MEMORY;
+INSERT INTO t3 VALUES (7);
+SELECT MIN(t3.col_int_nokey),t1.col_int_nokey AS field3
+FROM t3
+LEFT JOIN t1
+ON t1.col_int_nokey
+WHERE (194, 200) IN (
+SELECT SQ4_alias1.col_int_nokey,
+SQ4_alias2.col_int_nokey
+FROM t2 AS SQ4_alias1
+JOIN
+t2 AS SQ4_alias2
+ON SQ4_alias2.col_int_nokey = 5
+)
+GROUP BY field3 ;
+MIN(t3.col_int_nokey) field3
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
CREATE TABLE t1 (f1 INT, f2 DECIMAL(5,3)) ENGINE=MyISAM;
INSERT INTO t1 (f1, f2) VALUES (1, 1.789);
INSERT INTO t1 (f1, f2) VALUES (13, 1.454);
@@ -1237,7 +1479,8 @@ CREATE TABLE t2 LIKE t1;
INSERT INTO t2 VALUES (1, 1.789);
INSERT INTO t2 VALUES (13, 1.454);
set @save_optimizer_switch=@@optimizer_switch;
-SET @@optimizer_switch='default,semijoin=on,materialization=on';
+set @@optimizer_switch=@optimizer_switch_local_default;
+SET @@optimizer_switch='semijoin=on,materialization=on';
EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 2
@@ -1260,7 +1503,8 @@ INSERT INTO t1 VALUES (1,'o','ffff','ffff','ffoo'),(2,'f','ffff','ffff','ffff');
CREATE TABLE t2 LIKE t1;
INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff');
set @save_optimizer_switch=@@optimizer_switch;
-SET @@optimizer_switch='default,semijoin=on,materialization=on';
+set @@optimizer_switch=@optimizer_switch_local_default;
+SET @@optimizer_switch='semijoin=on,materialization=on';
EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
@@ -1358,3 +1602,168 @@ select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,
left(a1,7) left(a2,7)
1 - 01x 2 - 01x
drop table t1_1024, t2_1024;
+#
+# BUG##836491: Crash in Item_field::Item_field from add_ref_to_table_cond() with semijoin+materialization
+#
+CREATE TABLE t1 (c int, d varchar(1), KEY(d)) ;
+INSERT INTO t1 VALUES (2,'x'),(2,'x'),(2,'j'),(2,'c');
+CREATE TABLE t2 (a int, d varchar(1)) ;
+INSERT INTO t2 VALUES (1,'x');
+CREATE TABLE t3 (d varchar(1)) ;
+INSERT INTO t3 VALUES ('x'),('x'),('j'),('c');
+SELECT t2.a, t1.c
+FROM t1, t2
+WHERE t2.d IN ( SELECT d FROM t3 )
+AND t1.d = t2.d
+GROUP BY 1 , 2;
+a c
+1 2
+drop table t1,t2,t3;
+#
+# BUG#836523: Crash in JOIN::get_partial_cost_and_fanout with semijoin+materialization
+#
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('a'),('a');
+CREATE TABLE t2 (a varchar(1));
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (1),(2);
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('a'),('a');
+SELECT t1.a
+FROM t1
+WHERE t1.a IN (
+SELECT t2.a
+FROM t2, t3
+)
+HAVING a IN (
+SELECT a
+FROM t4
+);
+a
+DROP TABLE t1, t2, t3, t4;
+#
+# BUG#836507: Crash in setup_sj_materialization_part1() with semijoin+materialization
+#
+CREATE TABLE t1 (a int) ;
+INSERT IGNORE INTO t1 VALUES (1),(1);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1);
+CREATE TABLE t3 (a int);
+CREATE TABLE t4 (a int);
+INSERT INTO t4 VALUES (2),(2);
+CREATE TABLE t5 (a int);
+INSERT INTO t5 VALUES (1);
+SELECT * FROM t1
+WHERE (a) IN (
+SELECT t5.a
+FROM (
+t2
+LEFT JOIN ( t3 , t4 )
+ON 1 = 1
+)
+JOIN t5
+);
+a
+1
+1
+DROP TABLE t1,t2,t3,t4,t5;
+#
+# BUG#836532: Crash in Item_equal_fields_iterator::get_curr_field with semijoin+materialization
+#
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES ('a'),('a');
+Warnings:
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 1
+Warning 1366 Incorrect integer value: 'a' for column 'a' at row 2
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('m'),('o');
+CREATE TABLE t3 (a varchar(1) , b varchar(1) ) ;
+INSERT INTO t3 VALUES ('b','b');
+CREATE TABLE t5 (a varchar(1), KEY (a)) ;
+INSERT INTO t5 VALUES ('d'),('e');
+SELECT *
+FROM t2
+WHERE t2.a = ALL (
+SELECT t4.a
+FROM t4
+WHERE t4.a IN (
+SELECT t3.a
+FROM t3 , t5
+WHERE ( t5.a = t3.b )
+)
+);
+a
+0
+0
+DROP TABLE t2,t3,t4,t5;
+#
+# BUG#860300: Second crash with get_fanout_with_deps() with semijoin + materialization
+#
+set @tmp_860300=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f2 int);
+INSERT INTO t1 VALUES (9),(6);
+CREATE TABLE t3 (f4 int);
+CREATE TABLE t4 (f6 varchar(1));
+SELECT *
+FROM t3
+WHERE 'h' IN (SELECT f6
+FROM t4
+WHERE 5 IN (SELECT f2 FROM t1)
+GROUP BY t4.f6);
+f4
+DROP TABLE t1,t3,t4;
+set optimizer_switch=@tmp_860300;
+#
+# BUG#860535: Assertion `keypart_map' failed in mi_rkey with semijoin
+#
+set @tmp_860535=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f3 int) ;
+INSERT INTO t1 VALUES (1),(7);
+CREATE TABLE t2 (f3 int , f5 varchar(1), KEY (f3)) ;
+INSERT INTO t2 VALUES (7,'b');
+CREATE TABLE t3 (f3 int , f4 varchar(1) , KEY(f3), KEY (f4,f3)) ;
+INSERT INTO t3 VALUES (1,'t'),(7,'g');
+CREATE TABLE t4
+SELECT f3
+FROM t1 WHERE ( f3 ) NOT IN (
+SELECT f3
+FROM t2
+WHERE f5 IN (
+SELECT f4
+FROM t3
+WHERE t3.f3 < 3
+)
+);
+SELECT * FROM t4;
+f3
+1
+7
+DROP TABLE t1, t2, t3, t4;
+set optimizer_switch=@tmp_860535;
+#
+# BUG#860553: Crash in create_ref_for_key with semijoin + materialization
+#
+CREATE TABLE t1 (f1 int) ;
+CREATE TABLE t2 (f5 varchar(52) NOT NULL) ;
+CREATE TABLE t3 (f1 varchar(3), f4 varchar(52) , KEY (f4), PRIMARY KEY (f1));
+CREATE TABLE t4 (f3 int, KEY (f3));
+INSERT INTO t4 VALUES (17),(20);
+CREATE TABLE t5 (f2 int);
+INSERT INTO t5 VALUES (0),(0);
+SELECT *
+FROM t1
+JOIN t2
+ON ( t2.f5 ) IN (
+SELECT t3.f4
+FROM t3
+WHERE ( 1 ) IN (
+SELECT t4.f3
+FROM t4 , t5
+)
+);
+f1 f5
+DROP TABLE t1, t2, t3, t4, t5;
+# This must be at the end:
+set optimizer_switch=@subselect_sj_mat_tmp;
diff --git a/mysql-test/r/subselect_sj_nonmerged.result b/mysql-test/r/subselect_sj_nonmerged.result
index 9304c26ece6..192c0812236 100644
--- a/mysql-test/r/subselect_sj_nonmerged.result
+++ b/mysql-test/r/subselect_sj_nonmerged.result
@@ -1,6 +1,7 @@
drop table if exists t0, t1, t2, t3, t4;
set @save_optimizer_switch=@@optimizer_switch;
-set optimizer_switch='materialization=on';
+set optimizer_switch='semijoin=on,materialization=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table t1 as select * from t0;
@@ -75,7 +76,7 @@ t4.b in (select max(t2.a) from t1, t2 group by t2.b);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5 Using where
1 PRIMARY <subquery3> ALL distinct_key NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
-1 PRIMARY t4 ref a a 10 <subquery2>.max(t2.a),<subquery3>.max(t2.a) 11
+1 PRIMARY t4 ref a a 10 <subquery2>.max(t2.a),<subquery3>.max(t2.a) 12
3 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
3 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result
index d3cbc134de9..5079d72aaea 100644
--- a/mysql-test/r/system_mysql_db.result
+++ b/mysql-test/r/system_mysql_db.result
@@ -117,7 +117,7 @@ user CREATE TABLE `user` (
`max_questions` int(11) unsigned NOT NULL DEFAULT '0',
`max_updates` int(11) unsigned NOT NULL DEFAULT '0',
`max_connections` int(11) unsigned NOT NULL DEFAULT '0',
- `max_user_connections` int(11) unsigned NOT NULL DEFAULT '0',
+ `max_user_connections` int(11) NOT NULL DEFAULT '0',
`plugin` char(60) CHARACTER SET latin1 NOT NULL DEFAULT '',
`auth_string` text COLLATE utf8_bin NOT NULL,
PRIMARY KEY (`Host`,`User`)
diff --git a/mysql-test/r/table_elim.result b/mysql-test/r/table_elim.result
index bb29cd7679d..b4d3a2f6f2f 100644
--- a/mysql-test/r/table_elim.result
+++ b/mysql-test/r/table_elim.result
@@ -128,7 +128,7 @@ Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` where (`f`.`id` in (1,2,3
This should use facts and a1 tables:
explain extended select id from v1 where attr1 between 12 and 14;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using index condition; Rowid-ordered scan
+1 SIMPLE a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using where
1 SIMPLE f eq_ref PRIMARY PRIMARY 4 test.a1.id 1 100.00 Using index
Warnings:
Note 1276 Field or reference 'test.a2.id' of SELECT #3 was resolved in SELECT #2
@@ -136,7 +136,7 @@ Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t1` `a1` whe
This should use facts, a2 and its subquery:
explain extended select id from v1 where attr2 between 12 and 14;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using where
1 SIMPLE f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using index
3 DEPENDENT SUBQUERY t2 ref PRIMARY PRIMARY 4 test.a2.id 2 100.00 Using index
Warnings:
@@ -156,7 +156,7 @@ Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` where (`f`.`id` in (1,2,3
This should use facts and a1 tables:
explain extended select id from v2 where attr1 between 12 and 14;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using index condition; Rowid-ordered scan
+1 SIMPLE a1 range PRIMARY,attr1 attr1 5 NULL 2 100.00 Using where
1 SIMPLE f eq_ref PRIMARY PRIMARY 4 test.a1.id 1 100.00 Using index
Warnings:
Note 1276 Field or reference 'test.f.id' of SELECT #3 was resolved in SELECT #2
@@ -164,7 +164,7 @@ Note 1003 select `f`.`id` AS `id` from `test`.`t0` `f` join `test`.`t1` `a1` whe
This should use facts, a2 and its subquery:
explain extended select id from v2 where attr2 between 12 and 14;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using index condition; Rowid-ordered scan
+1 SIMPLE a2 range PRIMARY,attr2 attr2 5 NULL 5 100.00 Using where
1 SIMPLE f eq_ref PRIMARY PRIMARY 4 test.a2.id 1 100.00 Using where; Using index
3 DEPENDENT SUBQUERY t2 ref PRIMARY PRIMARY 4 test.f.id 2 100.00 Using index
Warnings:
@@ -272,7 +272,8 @@ drop table t1, t2;
create table t1 (a char(10) primary key);
insert into t1 values ('foo'),('bar');
create table t2 (a char(10), unique key(a(2)));
-insert into t2 values ('foo'),('bar');
+insert into t2 values
+('foo'),('bar'),('boo'),('car'),('coo'),('par'),('doo'),('tar');
explain select t1.* from t1 left join t2 on t2.a=t1.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL PRIMARY 10 NULL 2 Using index
@@ -416,7 +417,7 @@ select t1.*
from t1 left join t2 on (t2.pk=3 and t2.b=3) or (t2.pk= 4 and t2.b=3);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Rowid-ordered scan
+1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where
drop table t1, t2;
#
# LPBUG#523593: Running RQG optimizer_no_subquery crashes MariaDB
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 089845560ed..efe63285c9c 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -2117,3 +2117,22 @@ b
DROP DATABASE db1;
USE test;
End of 5.1 tests.
+create table t1 (i int);
+create table t2 (i int);
+flush tables;
+flush status;
+CREATE DEFINER=`root`@`localhost` TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW BEGIN DELETE FROM t2 WHERE t2.i = OLD.i; END //
+insert into t1 values (1),(2);
+insert into t2 values (1),(2);
+delete from t1 where i=1;
+show status like 'Opened_tables';
+Variable_name Value
+Opened_tables 3
+select * from t1;
+i
+2
+select * from t2;
+i
+2
+drop table t1,t2;
+End of 5.2 tests.
diff --git a/mysql-test/r/user_limits-2.result b/mysql-test/r/user_limits-2.result
new file mode 100644
index 00000000000..d9daec5c089
--- /dev/null
+++ b/mysql-test/r/user_limits-2.result
@@ -0,0 +1,2 @@
+set global max_user_connections=100;
+ERROR HY000: The MySQL server is running with the --max-user-connections=0 option so it cannot execute this statement
diff --git a/mysql-test/r/user_limits.result b/mysql-test/r/user_limits.result
index a94eb4616d1..776a25d55e6 100644
--- a/mysql-test/r/user_limits.result
+++ b/mysql-test/r/user_limits.result
@@ -1,3 +1,4 @@
+set @my_max_user_connections= @@global.max_user_connections;
drop table if exists t1;
create table t1 (i int);
delete from mysql.user where user like 'mysqltest\_%';
@@ -12,9 +13,9 @@ i
select * from t1;
i
select * from t1;
-ERROR 42000: User 'mysqltest_1' has exceeded the 'max_questions' resource (current value: 2)
+ERROR 42000: User 'mysqltest_1' has exceeded the 'max_queries_per_hour' resource (current value: 2)
select * from t1;
-ERROR 42000: User 'mysqltest_1' has exceeded the 'max_questions' resource (current value: 2)
+ERROR 42000: User 'mysqltest_1' has exceeded the 'max_queries_per_hour' resource (current value: 2)
drop user mysqltest_1@localhost;
grant usage on *.* to mysqltest_1@localhost with max_updates_per_hour 2;
flush user_resources;
@@ -27,11 +28,11 @@ i
delete from t1;
delete from t1;
delete from t1;
-ERROR 42000: User 'mysqltest_1' has exceeded the 'max_updates' resource (current value: 2)
+ERROR 42000: User 'mysqltest_1' has exceeded the 'max_updates_per_hour' resource (current value: 2)
select * from t1;
i
delete from t1;
-ERROR 42000: User 'mysqltest_1' has exceeded the 'max_updates' resource (current value: 2)
+ERROR 42000: User 'mysqltest_1' has exceeded the 'max_updates_per_hour' resource (current value: 2)
select * from t1;
i
drop user mysqltest_1@localhost;
@@ -65,10 +66,20 @@ select * from t1;
i
connect(localhost,mysqltest_1,,test,MYSQL_PORT,MYSQL_SOCK);
ERROR 42000: User 'mysqltest_1' has exceeded the 'max_user_connections' resource (current value: 3)
+grant usage on *.* to mysqltest_1@localhost with max_user_connections -1;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_USER_CONNECTIONS -1
+flush user_resources;
+show grants for mysqltest_1@localhost;
+Grants for mysqltest_1@localhost
+GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' WITH MAX_USER_CONNECTIONS -1
+connect(localhost,mysqltest_1,,test,MYSQL_PORT,MYSQL_SOCK);
+ERROR 42000: User 'mysqltest_1' has exceeded the 'max_user_connections' resource (current value: -1)
drop user mysqltest_1@localhost;
select @@session.max_user_connections, @@global.max_user_connections;
@@session.max_user_connections @@global.max_user_connections
-0 0
+1000 1000
set session max_user_connections= 2;
ERROR HY000: Variable 'max_user_connections' is a GLOBAL variable and should be set with SET GLOBAL
set global max_user_connections= 2;
@@ -92,5 +103,21 @@ select @@session.max_user_connections, @@global.max_user_connections;
connect(localhost,mysqltest_1,,test,MYSQL_PORT,MYSQL_SOCK);
ERROR 42000: User 'mysqltest_1' has exceeded the 'max_user_connections' resource (current value: 3)
set global max_user_connections= 0;
+grant usage on *.* to mysqltest_1@localhost with max_user_connections 0;
+set global max_user_connections=-1;
+show variables like "max_user_user_connections";
+Variable_name Value
+select @@max_user_connections;
+@@max_user_connections
+-1
+select @@global.max_user_connections;
+@@global.max_user_connections
+-1
+connect(localhost,mysqltest_1,,test,MYSQL_PORT,MYSQL_SOCK);
+ERROR 42000: User mysqltest_1 already has more than 'max_user_connections' active connections
+set global max_user_connections=1;
+connect(localhost,mysqltest_1,,test,MYSQL_PORT,MYSQL_SOCK);
+ERROR 42000: User mysqltest_1 already has more than 'max_user_connections' active connections
drop user mysqltest_1@localhost;
drop table t1;
+set global max_user_connections= @my_max_user_connections;
diff --git a/mysql-test/r/variables-big.result b/mysql-test/r/variables-big.result
index 71b32393d82..793363fc7c1 100644
--- a/mysql-test/r/variables-big.result
+++ b/mysql-test/r/variables-big.result
@@ -1,20 +1,20 @@
SET SESSION transaction_prealloc_size=1024*1024*1024*1;
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
+Id User Host db Command Time State Info Progress
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST 0.000
SET SESSION transaction_prealloc_size=1024*1024*1024*2;
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
+Id User Host db Command Time State Info Progress
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST 0.000
SET SESSION transaction_prealloc_size=1024*1024*1024*3;
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
+Id User Host db Command Time State Info Progress
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST 0.000
SET SESSION transaction_prealloc_size=1024*1024*1024*4;
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
+Id User Host db Command Time State Info Progress
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST 0.000
SET SESSION transaction_prealloc_size=1024*1024*1024*5;
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST
+Id User Host db Command Time State Info Progress
+<Id> root <Host> test Query <Time> NULL SHOW PROCESSLIST 0.000
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index 890eb9fcc20..44eddb18667 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -14,6 +14,7 @@ set @my_max_delayed_threads =@@global.max_delayed_threads;
set @my_max_heap_table_size =@@global.max_heap_table_size;
set @my_max_insert_delayed_threads=@@global.max_insert_delayed_threads;
set @my_max_join_size =@@global.max_join_size;
+set @my_max_user_connections =@@global.max_user_connections;
set @my_myisam_data_pointer_size =@@global.myisam_data_pointer_size;
set @my_myisam_max_sort_file_size =@@global.myisam_max_sort_file_size;
set @my_net_buffer_length =@@global.net_buffer_length;
@@ -27,6 +28,7 @@ set @my_thread_cache_size =@@global.thread_cache_size;
set @my_max_allowed_packet =@@global.max_allowed_packet;
set @my_delay_key_write =@@global.delay_key_write;
set @my_join_buffer_size =@@global.join_buffer_size;
+set @my_log_warnings =@@global.log_warnings;
set @`test`=1;
select @test, @`test`, @TEST, @`TEST`, @"teSt";
@test @`test` @TEST @`TEST` @"teSt"
@@ -1048,7 +1050,7 @@ set global max_delayed_threads =@my_max_delayed_threads;
set global max_heap_table_size =@my_max_heap_table_size;
set global max_insert_delayed_threads=@my_max_insert_delayed_threads;
set global max_join_size =@my_max_join_size;
-set global max_user_connections =default;
+set global max_user_connections =@my_max_user_connections;
set global max_write_lock_count =default;
set global myisam_data_pointer_size =@my_myisam_data_pointer_size;
set global myisam_max_sort_file_size =@my_myisam_max_sort_file_size;
@@ -1065,6 +1067,7 @@ set global thread_cache_size =@my_thread_cache_size;
set global max_allowed_packet = default;
set global delay_key_write =@my_delay_key_write;
set global join_buffer_size =@my_join_buffer_size;
+set global log_warnings =@my_log_warnings;
show global variables where Variable_name='table_definition_cache' or
Variable_name='table_lock_wait_timeout';
Variable_name Value
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 9f720019303..f9e5c875726 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -1256,8 +1256,8 @@ s1
insert into t1 values (0);
execute stmt1;
s1
-1
0
+1
deallocate prepare stmt1;
drop view v2;
drop table t1, t2;
@@ -2134,12 +2134,12 @@ INSERT INTO t1 VALUES (2, 'foo2');
INSERT INTO t1 VALUES (1, 'foo1');
SELECT * FROM v1;
id f
-2 foo2
1 foo1
+2 foo2
SELECT * FROM v1;
id f
-2 foo2
1 foo1
+2 foo2
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (pk int PRIMARY KEY, b int);
@@ -3135,17 +3135,18 @@ Warnings:
Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` order by `test`.`t1`.`f2`
select * from v1 order by f1;
f1 f2
-1 1
1 2
1 3
+1 1
+2 3
2 1
2 2
-2 3
explain extended select * from v1 order by f1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 100.00 Using filesort
Warnings:
-Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` order by `test`.`t1`.`f1`,`test`.`t1`.`f2`
+Note 1926 View 'test'.'v1' ORDER BY clause ignored because there is other ORDER BY clause already.
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2` from `test`.`t1` order by `test`.`t1`.`f1`
drop view v1;
drop table t1;
CREATE TABLE t1 (
@@ -3711,7 +3712,7 @@ CREATE TABLE t1 (c INT);
CREATE VIEW v1 (view_column) AS SELECT c AS alias FROM t1 HAVING alias;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`c` AS `view_column` from `t1` having `view_column` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`c` AS `view_column` from `t1` having (`view_column` <> 0) latin1 latin1_swedish_ci
SELECT * FROM v1;
view_column
@@ -3906,6 +3907,23 @@ SELECT * FROM v1;
a
DROP VIEW v1;
DROP TABLE t1;
+#
+# LP BUG#777809 (a retrograded condition for view ON)
+#
+CREATE TABLE t1 ( f1 int NOT NULL , f6 int NOT NULL ) ;
+INSERT IGNORE INTO t1 VALUES (20, 2);
+CREATE TABLE t2 ( f3 int NOT NULL ) ;
+INSERT IGNORE INTO t2 VALUES (7);
+CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2;
+PREPARE prep_stmt FROM 'SELECT t1.f6 FROM t1 RIGHT JOIN v2 ON v2.f3 WHERE t1.f1 != 0';
+EXECUTE prep_stmt;
+f6
+2
+EXECUTE prep_stmt;
+f6
+2
+drop view v2;
+drop table t1,t2;
# -----------------------------------------------------------------
# -- End of 5.1 tests.
# -----------------------------------------------------------------
@@ -4184,3 +4202,173 @@ DELETE FROM v3;
ERROR HY000: The target table v3 of the DELETE is not updatable
DROP VIEW v1,v2,v3;
DROP TABLE t1;
+#
+# Bug#798621: crash with a view string field equal
+# to a constant
+#
+CREATE TABLE t1 (a varchar(32), b int) ;
+INSERT INTO t1 VALUES ('j', NULL), ('c', 8), ('c', 1);
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE TABLE t2 (a varchar(32)) ;
+INSERT INTO t2 VALUES ('j'), ('c');
+SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a
+WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b;
+a b a
+c 1 c
+EXPLAIN EXTENDED
+SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a
+WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b;
+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`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where ((`test`.`t1`.`b` = 1) or ((`test`.`t1`.`a` = 'a') and (length(`test`.`t1`.`a`) >= `test`.`t1`.`b`)))
+DROP VIEW v1;
+DROP TABLE t1,t2;
+# Bug#798625: duplicate of the previous one, but without crash
+CREATE TABLE t1 (f1 int NOT NULL, f2 int, f3 int, f4 varchar(32), f5 int) ;
+INSERT INTO t1 VALUES (20,5,2,'r', 0);
+CREATE VIEW v1 AS SELECT * FROM t1;
+SELECT v1.f4 FROM v1
+WHERE f1<>0 OR f2<>0 AND f4='v' AND (f2<>0 OR f3<>0 AND f5<>0 OR f4 LIKE '%b%');
+f4
+r
+EXPLAIN EXTENDED
+SELECT v1.f4 FROM v1
+WHERE f1<>0 OR f2<>0 AND f4='v' AND (f2<>0 OR f3<>0 AND f5<>0 OR f4 LIKE '%b%');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00
+Warnings:
+Note 1003 select 'r' AS `f4` from `test`.`t1` where ((20 <> 0) or 0)
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# Bug#798576: abort on a GROUP BY query over a view with left join
+# that can be converted to inner join
+#
+CREATE TABLE t1 (a int NOT NULL , b int NOT NULL) ;
+INSERT INTO t1 VALUES (214,0), (6,6), (6,0), (7,0);
+CREATE TABLE t2 (b int) ;
+INSERT INTO t2 VALUES (88), (78), (6);
+CREATE ALGORITHM=MERGE VIEW v1 AS
+SELECT t1.a, t2.b FROM (t2 LEFT JOIN t1 ON t2.b > t1.a) WHERE t1.b <= 0;
+SELECT * FROM v1;
+a b
+6 88
+6 78
+7 88
+7 78
+SELECT a, MIN(b) FROM v1 GROUP BY a;
+a MIN(b)
+6 78
+7 78
+DROP VIEW v1;
+DROP TABLE t1,t2;
+#
+# LP bug #793386: unexpected 'Duplicate column name ''' error
+# at the second execution of a PS using a view
+#
+CREATE TABLE t1 (f1 int, f2 int, f3 int, f4 int);
+CREATE VIEW v1 AS
+SELECT t.f1, t.f2, s.f3, s.f4 FROM t1 t, t1 s
+WHERE t.f4 >= s.f2 AND s.f3 < 0;
+PREPARE stmt1 FROM
+"SELECT s.f1 AS f1, s.f2 AS f2, s.f3 AS f3, t.f4 AS f4
+ FROM v1 AS t LEFT JOIN v1 AS s ON t.f4=s.f4 WHERE t.f2 <> 1225";
+EXECUTE stmt1;
+f1 f2 f3 f4
+EXECUTE stmt1;
+f1 f2 f3 f4
+DEALLOCATE PREPARE stmt1;
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# LP BUG#806071 (2 views with ORDER BY)
+#
+CREATE TABLE t1 (f1 int);
+INSERT INTO t1 VALUES (1),(1);
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT f1 FROM t1;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT f1 FROM v1 ORDER BY f1;
+SELECT * FROM v2 AS a1, v2 AS a2;
+f1 f1
+1 1
+1 1
+1 1
+1 1
+EXPLAIN EXTENDED SELECT * FROM v2 AS a1, v2 AS a2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE <derived3> ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort
+1 SIMPLE <derived5> ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join)
+5 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED t1 ALL NULL NULL NULL NULL 2 100.00
+Warnings:
+Note 1926 View 'test'.'v2' ORDER BY clause ignored because there is other ORDER BY clause already.
+Note 1003 select `v1`.`f1` AS `f1`,`v1`.`f1` AS `f1` from `test`.`v1` join `test`.`v1` order by `v1`.`f1`
+DROP VIEW v1, v2;
+DROP TABLE t1;
+#
+# LP bug #823189: dependent subquery with RIGHT JOIN
+# referencing view in WHERE
+#
+CREATE TABLE t1 (a varchar(32));
+INSERT INTO t1 VALUES ('y'), ('w');
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (10);
+CREATE TABLE t3 (a varchar(32), b int);
+CREATE TABLE t4 (a varchar(32));
+INSERT INTO t4 VALUES ('y'), ('w');
+CREATE VIEW v1 AS SELECT * FROM t1;
+EXPLAIN EXTENDED
+SELECT * FROM t1, t2
+WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+WHERE t4.a >= t1.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 0 0.00 const row not found
+2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`a` AS `a`,10 AS `a` from `test`.`t1` join `test`.`t2` where (not(<expr_cache><10,`test`.`t1`.`a`>(<in_optimizer>(10,<exists>(select NULL from `test`.`t4` left join `test`.`t3` on(multiple equal(NULL, `test`.`t4`.`a`)) where ((`test`.`t4`.`a` >= `test`.`t1`.`a`) and trigcond(((<cache>(10) = NULL) or isnull(NULL)))) having trigcond(<is_not_null_test>(NULL)))))))
+SELECT * FROM t1, t2
+WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+WHERE t4.a >= t1.a);
+a a
+EXPLAIN EXTENDED
+SELECT * FROM v1, t2
+WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+WHERE t4.a >= v1.a);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
+2 DEPENDENT SUBQUERY t3 system NULL NULL NULL NULL 0 0.00 const row not found
+2 DEPENDENT SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1276 Field or reference 'v1.a' of SELECT #2 was resolved in SELECT #1
+Note 1003 select `test`.`t1`.`a` AS `a`,10 AS `a` from `test`.`t1` join `test`.`t2` where (not(<expr_cache><10,`test`.`t1`.`a`>(<in_optimizer>(10,<exists>(select NULL from `test`.`t4` left join `test`.`t3` on(multiple equal(NULL, `test`.`t4`.`a`)) where ((`test`.`t4`.`a` >= `test`.`t1`.`a`) and trigcond(((<cache>(10) = NULL) or isnull(NULL)))) having trigcond(<is_not_null_test>(NULL)))))))
+SELECT * FROM v1, t2
+WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+WHERE t4.a >= v1.a);
+a a
+DROP VIEW v1;
+DROP TABLE t1,t2,t3,t4;
+#
+# BUG#833600: Wrong result with view + outer join + uncorrelated subquery (non-semijoin)
+#
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (0,0),(0,0);
+CREATE TABLE t2 ( a int, b int );
+INSERT IGNORE INTO t2 VALUES (1,0),(1,0);
+CREATE TABLE t3 ( b int );
+INSERT IGNORE INTO t3 VALUES (0),(0);
+CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2;
+SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ;
+a b a b
+NULL NULL 1 0
+NULL NULL 1 0
+SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ;
+a b a b
+NULL NULL 1 0
+NULL NULL 1 0
+DROP VIEW v2;
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/suite/binlog/r/binlog_row_annotate.result b/mysql-test/suite/binlog/r/binlog_row_annotate.result
index 647c07af2f8..dc43e96694a 100644
--- a/mysql-test/suite/binlog/r/binlog_row_annotate.result
+++ b/mysql-test/suite/binlog/r/binlog_row_annotate.result
@@ -427,7 +427,7 @@ ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
#
#####################################################################################
-# mysqlbinlog --skip-annotate-rows-events
+# mysqlbinlog --skip-annotate-row-events
# No Annotates should appear in this output
#####################################################################################
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
@@ -1013,7 +1013,7 @@ ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
#
#####################################################################################
-# mysqlbinlog --read-from-remote-server --skip-annotate-rows-events
+# mysqlbinlog --read-from-remote-server --skip-annotate-row-events
# No Annotates should appear in this output
#####################################################################################
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
diff --git a/mysql-test/suite/binlog/t/binlog_row_annotate.test b/mysql-test/suite/binlog/t/binlog_row_annotate.test
index c5db9ef2148..a0f72c9222c 100644
--- a/mysql-test/suite/binlog/t/binlog_row_annotate.test
+++ b/mysql-test/suite/binlog/t/binlog_row_annotate.test
@@ -1,11 +1,11 @@
###############################################################################
# WL47: Store in binlog text of statements that caused RBR events
# new event: ANNOTATE_ROWS_EVENT
-# new master option: --binlog-annotate-rows-events
-# new mysqlbinlog option: --skip-annotate-rows-events
+# new master option: --binlog-annotate-row-events
+# new mysqlbinlog option: --skip-annotate-row-events
#
# Intended to test that:
-# *** If the --binlog-annotate-rows-events option is switched on on master
+# *** If the --binlog-annotate-row-events option is switched on on master
# then Annotate_rows events:
# - are generated;
# - are genrated only once for "multi-table-maps" rbr queries;
@@ -13,9 +13,9 @@
# - are generated when the corresponding queries are filtered away partialy
# (e.g. in case of multi-delete).
# *** Annotate_rows events are printed by mysqlbinlog started without
-# --skip-annotate-rows-events options both in remote and local cases.
+# --skip-annotate-row-events options both in remote and local cases.
# *** Annotate_rows events are not printed by mysqlbinlog started with
-# --skip-annotate-rows-events options both in remote and local cases.
+# --skip-annotate-row-events options both in remote and local cases.
###############################################################################
--source include/have_log_bin.inc
@@ -54,11 +54,11 @@ CREATE TABLE xtest1.xt1(a int);
CREATE DATABASE xtest2;
CREATE TABLE xtest2.xt2(a int);
-# By default SESSION binlog_annotate_rows_events = OFF
+# By default SESSION binlog_annotate_row_events = OFF
INSERT INTO test1.t1 VALUES (1), (2), (3);
-SET SESSION binlog_annotate_rows_events = ON;
+SET SESSION binlog_annotate_row_events = ON;
INSERT INTO test2.t2 VALUES (1), (2), (3);
INSERT INTO test3.t3 VALUES (1), (2), (3);
@@ -133,13 +133,13 @@ let $MYSQLD_DATADIR= `select @@datadir`;
--echo #
--echo #####################################################################################
---echo # mysqlbinlog --skip-annotate-rows-events
+--echo # mysqlbinlog --skip-annotate-row-events
--echo # No Annotates should appear in this output
--echo #####################################################################################
let $MYSQLD_DATADIR= `select @@datadir`;
--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/
---exec $MYSQL_BINLOG --base64-output=decode-rows --skip-annotate-rows-events -v -v $MYSQLD_DATADIR/master-bin.000001
+--exec $MYSQL_BINLOG --base64-output=decode-rows --skip-annotate-row-events -v -v $MYSQLD_DATADIR/master-bin.000001
--echo #
--echo #####################################################################################
@@ -169,13 +169,13 @@ let $MYSQLD_DATADIR= `select @@datadir`;
--echo #
--echo #####################################################################################
---echo # mysqlbinlog --read-from-remote-server --skip-annotate-rows-events
+--echo # mysqlbinlog --read-from-remote-server --skip-annotate-row-events
--echo # No Annotates should appear in this output
--echo #####################################################################################
let $MYSQLD_DATADIR= `select @@datadir`;
--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/
---exec $MYSQL_BINLOG --base64-output=decode-rows --skip-annotate-rows-events -v -v --read-from-remote-server --user=root --host=localhost --port=$MASTER_MYPORT master-bin.000001
+--exec $MYSQL_BINLOG --base64-output=decode-rows --skip-annotate-row-events -v -v --read-from-remote-server --user=root --host=localhost --port=$MASTER_MYPORT master-bin.000001
# Clean-up
diff --git a/mysql-test/suite/funcs_1/datadict/datadict_priv.inc b/mysql-test/suite/funcs_1/datadict/datadict_priv.inc
index 60c16279311..913f6635822 100644
--- a/mysql-test/suite/funcs_1/datadict/datadict_priv.inc
+++ b/mysql-test/suite/funcs_1/datadict/datadict_priv.inc
@@ -17,7 +17,7 @@
# let $table= processlist;
#
# columns of the information_schema table e.g. to use in a select.
-# let $columns= ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO;
+# let $columns= ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, PROGRESS;
#
# Where clause for an update.
# let $update_where= WHERE id=1 ;
diff --git a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc
index 544560ec526..6b4a84ad193 100644
--- a/mysql-test/suite/funcs_1/datadict/processlist_priv.inc
+++ b/mysql-test/suite/funcs_1/datadict/processlist_priv.inc
@@ -66,7 +66,7 @@
let $table= processlist;
#
# columns of the information_schema table e.g. to use in a select.
-let $columns= ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS;
+let $columns= ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS;
#
# Where clause for an update.
let $update_where= WHERE id=1 ;
diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result
index a7b03a5c18b..cd9df766e65 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_is.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_is.result
@@ -320,6 +320,9 @@ NULL information_schema PROCESSLIST DB 4 NULL YES varchar 64 192 NULL NULL NULL
NULL information_schema PROCESSLIST HOST 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema PROCESSLIST ID 1 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4) select
NULL information_schema PROCESSLIST INFO 8 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select
+NULL information_schema PROCESSLIST MAX_STAGE 11 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2) select
+NULL information_schema PROCESSLIST PROGRESS 12 0.000 NO decimal NULL NULL 7 3 NULL NULL NULL decimal(7,3) select
+NULL information_schema PROCESSLIST STAGE 10 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2) select
NULL information_schema PROCESSLIST STATE 7 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select
NULL information_schema PROCESSLIST TIME 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(7) select
NULL information_schema PROCESSLIST TIME_MS 9 0.000 NO decimal NULL NULL 22 3 NULL NULL NULL decimal(22,3) select
@@ -532,6 +535,7 @@ NULL datetime NULL NULL
NULL decimal NULL NULL
NULL double NULL NULL
NULL int NULL NULL
+NULL tinyint NULL NULL
--> CHAR(0) is allowed (see manual), and here both CHARACHTER_* values
--> are 0, which is intended behavior, and the result of 0 / 0 IS NULL
SELECT CHARACTER_OCTET_LENGTH / CHARACTER_MAXIMUM_LENGTH AS COL_CML,
@@ -870,6 +874,9 @@ NULL information_schema PROCESSLIST TIME int NULL NULL NULL NULL int(7)
3.0000 information_schema PROCESSLIST STATE varchar 64 192 utf8 utf8_general_ci varchar(64)
1.0000 information_schema PROCESSLIST INFO longtext 4294967295 4294967295 utf8 utf8_general_ci longtext
NULL information_schema PROCESSLIST TIME_MS decimal NULL NULL NULL NULL decimal(22,3)
+NULL information_schema PROCESSLIST STAGE tinyint NULL NULL NULL NULL tinyint(2)
+NULL information_schema PROCESSLIST MAX_STAGE tinyint NULL NULL NULL NULL tinyint(2)
+NULL information_schema PROCESSLIST PROGRESS decimal NULL NULL NULL NULL decimal(7,3)
3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result
index b2dffaafe10..cca95be6841 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result
@@ -7,6 +7,29 @@ NULL information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NO varchar 32 96 NU
NULL information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
NULL information_schema CHARACTER_SETS DESCRIPTION 3 NO varchar 60 180 NULL NULL NULL utf8 utf8_general_ci varchar(60)
NULL information_schema CHARACTER_SETS MAXLEN 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(3)
+NULL information_schema CLIENT_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL NULL double
+NULL information_schema CLIENT_STATISTICS BYTES_RECEIVED 7 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS BYTES_SENT 8 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS CLIENT 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema CLIENT_STATISTICS COMMIT_TRANSACTIONS 18 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS CONNECTED_TIME 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL NULL double
+NULL information_schema CLIENT_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_INSERTED 13 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_READ 10 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_SENT 11 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_UPDATED 14 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS SELECT_COMMANDS 15 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS 2 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS UPDATE_COMMANDS 16 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
NULL information_schema COLLATIONS CHARACTER_SET_NAME 2 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
NULL information_schema COLLATIONS COLLATION_NAME 1 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
NULL information_schema COLLATIONS ID 3 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(11)
@@ -42,7 +65,7 @@ NULL information_schema COLUMN_PRIVILEGES PRIVILEGE_TYPE 6 NO varchar 64 192 NU
NULL information_schema COLUMN_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
NULL information_schema COLUMN_PRIVILEGES TABLE_NAME 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema COLUMN_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
-NULL information_schema ENGINES COMMENT 3 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80)
+NULL information_schema ENGINES COMMENT 3 NO varchar 160 480 NULL NULL NULL utf8 utf8_general_ci varchar(160)
NULL information_schema ENGINES ENGINE 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema ENGINES SAVEPOINTS 6 NULL YES varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
NULL information_schema ENGINES SUPPORT 2 NO varchar 8 24 NULL NULL NULL utf8 utf8_general_ci varchar(8)
@@ -114,6 +137,132 @@ NULL information_schema GLOBAL_STATUS VARIABLE_NAME 1 NO varchar 64 192 NULL NU
NULL information_schema GLOBAL_STATUS VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
NULL information_schema GLOBAL_VARIABLES VARIABLE_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema GLOBAL_VARIABLES VARIABLE_VALUE 2 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema INDEX_STATISTICS INDEX_NAME 3 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INDEX_STATISTICS ROWS_READ 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema INDEX_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INDEX_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_BUFFER_POOL_PAGES fix_count 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES flush_type 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES lru_position 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES page_no 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES page_type 1 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema INNODB_BUFFER_POOL_PAGES space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB compressed 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB fix_count 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB flush_type 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB lru_position 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB next_page_no 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB page_no 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB part_len 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB space_id 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX access_time 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX data_size 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX dirty 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX fix_count 12 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX flush_type 13 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX hashed 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX index_id 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX lru_position 11 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX modified 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX n_recs 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX old 10 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX page_no 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_CMP compress_ops 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP compress_ops_ok 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP compress_time 4 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP page_size 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(5)
+NULL information_schema INNODB_CMP uncompress_ops 5 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP uncompress_time 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMPMEM pages_free 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMPMEM pages_used 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMPMEM page_size 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(5)
+NULL information_schema INNODB_CMPMEM relocation_ops 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema INNODB_CMPMEM relocation_time 5 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMPMEM_RESET pages_free 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMPMEM_RESET pages_used 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMPMEM_RESET page_size 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(5)
+NULL information_schema INNODB_CMPMEM_RESET relocation_ops 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema INNODB_CMPMEM_RESET relocation_time 5 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP_RESET compress_ops 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP_RESET compress_ops_ok 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP_RESET compress_time 4 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP_RESET page_size 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(5)
+NULL information_schema INNODB_CMP_RESET uncompress_ops 5 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_CMP_RESET uncompress_time 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema INNODB_INDEX_STATS fields 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_INDEX_STATS index_name 3 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_INDEX_STATS index_size 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_INDEX_STATS leaf_pages 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_INDEX_STATS row_per_keys 5 NO varchar 256 768 NULL NULL NULL utf8 utf8_general_ci varchar(256)
+NULL information_schema INNODB_INDEX_STATS table_name 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_INDEX_STATS table_schema 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_LOCKS lock_data 10 NULL YES varchar 8192 24576 NULL NULL NULL utf8 utf8_general_ci varchar(8192)
+NULL information_schema INNODB_LOCKS lock_id 1 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81)
+NULL information_schema INNODB_LOCKS lock_index 6 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema INNODB_LOCKS lock_mode 3 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema INNODB_LOCKS lock_page 8 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_LOCKS lock_rec 9 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_LOCKS lock_space 7 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_LOCKS lock_table 5 NO varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema INNODB_LOCKS lock_trx_id 2 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18)
+NULL information_schema INNODB_LOCKS lock_type 4 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
+NULL information_schema INNODB_LOCK_WAITS blocking_lock_id 4 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81)
+NULL information_schema INNODB_LOCK_WAITS blocking_trx_id 3 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18)
+NULL information_schema INNODB_LOCK_WAITS requested_lock_id 2 NO varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81)
+NULL information_schema INNODB_LOCK_WAITS requesting_trx_id 1 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18)
+NULL information_schema INNODB_RSEG curr_size 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_RSEG max_size 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_RSEG page_no 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_RSEG rseg_id 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_RSEG space_id 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_RSEG zip_size 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES ID 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES NAME 3 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_SYS_INDEXES N_FIELDS 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES PAGE_NO 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES SPACE 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES TABLE_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS DIFF_VALS 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS INDEX_ID 1 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS KEY_COLS 2 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS NON_NULL_VALS 4 NULL YES bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES CLUSTER_NAME 8 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_SYS_TABLES ID 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES MIX_ID 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES MIX_LEN 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES NAME 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_SYS_TABLES N_COLS 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES SCHEMA 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_SYS_TABLES SPACE 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES TYPE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_TABLE_STATS clust_size 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_TABLE_STATS modified 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_TABLE_STATS other_size 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_TABLE_STATS rows 3 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_TABLE_STATS table_name 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_TABLE_STATS table_schema 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_TRX trx_id 1 NO varchar 18 54 NULL NULL NULL utf8 utf8_general_ci varchar(18)
+NULL information_schema INNODB_TRX trx_mysql_thread_id 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_TRX trx_query 8 NULL YES varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema INNODB_TRX trx_requested_lock_id 4 NULL YES varchar 81 243 NULL NULL NULL utf8 utf8_general_ci varchar(81)
+NULL information_schema INNODB_TRX trx_started 3 0000-00-00 00:00:00 NO datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema INNODB_TRX trx_state 2 NO varchar 13 39 NULL NULL NULL utf8 utf8_general_ci varchar(13)
+NULL information_schema INNODB_TRX trx_wait_started 5 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema INNODB_TRX trx_weight 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES BLOCK_SIZE 5 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES DIRTY_BLOCKS 8 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES FULL_SIZE 4 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES KEY_CACHE_NAME 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema KEY_CACHES READS 10 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES READ_REQUESTS 9 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES SEGMENTS 2 NULL YES int NULL NULL 10 0 NULL NULL NULL int(3) unsigned
+NULL information_schema KEY_CACHES SEGMENT_NUMBER 3 NULL YES int NULL NULL 10 0 NULL NULL NULL int(3) unsigned
+NULL information_schema KEY_CACHES UNUSED_BLOCKS 7 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES USED_BLOCKS 6 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES WRITES 12 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES WRITE_REQUESTS 11 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
NULL information_schema KEY_COLUMN_USAGE COLUMN_NAME 7 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
NULL information_schema KEY_COLUMN_USAGE CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
@@ -151,11 +300,16 @@ NULL information_schema PARTITIONS TABLE_NAME 3 NO varchar 64 192 NULL NULL NUL
NULL information_schema PARTITIONS TABLE_ROWS 13 0 NO bigint NULL NULL 20 0 NULL NULL NULL bigint(21) unsigned
NULL information_schema PARTITIONS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema PARTITIONS UPDATE_TIME 20 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
+NULL information_schema PBXT_STATISTICS ID 1 0 NO int NULL NULL 10 0 NULL NULL NULL int(4)
+NULL information_schema PBXT_STATISTICS Name 2 NO varchar 40 120 NULL NULL NULL utf8 utf8_general_ci varchar(40)
+NULL information_schema PBXT_STATISTICS Value 3 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(8)
NULL information_schema PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema PLUGINS PLUGIN_AUTH_VERSION 12 NULL YES varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80)
NULL information_schema PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
NULL information_schema PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20)
NULL information_schema PLUGINS PLUGIN_LICENSE 10 NULL YES varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80)
+NULL information_schema PLUGINS PLUGIN_MATURITY 11 NULL YES varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12)
NULL information_schema PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10)
NULL information_schema PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80)
@@ -166,8 +320,12 @@ NULL information_schema PROCESSLIST DB 4 NULL YES varchar 64 192 NULL NULL NULL
NULL information_schema PROCESSLIST HOST 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema PROCESSLIST ID 1 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
NULL information_schema PROCESSLIST INFO 8 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema PROCESSLIST MAX_STAGE 11 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2)
+NULL information_schema PROCESSLIST PROGRESS 12 0.000 NO decimal NULL NULL 7 3 NULL NULL NULL decimal(7,3)
+NULL information_schema PROCESSLIST STAGE 10 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(2)
NULL information_schema PROCESSLIST STATE 7 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema PROCESSLIST TIME 6 0 NO int NULL NULL 10 0 NULL NULL NULL int(7)
+NULL information_schema PROCESSLIST TIME_MS 9 0.000 NO decimal NULL NULL 22 3 NULL NULL NULL decimal(22,3)
NULL information_schema PROCESSLIST USER 2 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16)
NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG 1 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
NULL information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
@@ -265,6 +423,11 @@ NULL information_schema TABLE_PRIVILEGES PRIVILEGE_TYPE 5 NO varchar 64 192 NUL
NULL information_schema TABLE_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
NULL information_schema TABLE_PRIVILEGES TABLE_NAME 4 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema TABLE_PRIVILEGES TABLE_SCHEMA 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
+NULL information_schema TABLE_STATISTICS ROWS_CHANGED 4 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema TABLE_STATISTICS ROWS_CHANGED_X_INDEXES 5 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema TABLE_STATISTICS ROWS_READ 3 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema TABLE_STATISTICS TABLE_NAME 2 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
+NULL information_schema TABLE_STATISTICS TABLE_SCHEMA 1 NO varchar 192 576 NULL NULL NULL utf8 utf8_general_ci varchar(192)
NULL information_schema TRIGGERS ACTION_CONDITION 9 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
NULL information_schema TRIGGERS ACTION_ORDER 8 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(4)
NULL information_schema TRIGGERS ACTION_ORIENTATION 11 NO varchar 9 27 NULL NULL NULL utf8 utf8_general_ci varchar(9)
@@ -291,6 +454,29 @@ NULL information_schema USER_PRIVILEGES GRANTEE 1 NO varchar 81 243 NULL NULL N
NULL information_schema USER_PRIVILEGES IS_GRANTABLE 4 NO varchar 3 9 NULL NULL NULL utf8 utf8_general_ci varchar(3)
NULL information_schema USER_PRIVILEGES PRIVILEGE_TYPE 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema USER_PRIVILEGES TABLE_CATALOG 2 NULL YES varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
+NULL information_schema USER_STATISTICS ACCESS_DENIED 22 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS BINLOG_BYTES_WRITTEN 9 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS BUSY_TIME 5 0 NO double NULL NULL 21 NULL NULL NULL NULL double
+NULL information_schema USER_STATISTICS BYTES_RECEIVED 7 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS BYTES_SENT 8 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS COMMIT_TRANSACTIONS 18 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS CONCURRENT_CONNECTIONS 3 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema USER_STATISTICS CONNECTED_TIME 4 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema USER_STATISTICS CPU_TIME 6 0 NO double NULL NULL 21 NULL NULL NULL NULL double
+NULL information_schema USER_STATISTICS DENIED_CONNECTIONS 20 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS EMPTY_QUERIES 23 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS LOST_CONNECTIONS 21 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS OTHER_COMMANDS 17 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROLLBACK_TRANSACTIONS 19 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_DELETED 12 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_INSERTED 13 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_READ 10 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_SENT 11 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_UPDATED 14 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS SELECT_COMMANDS 15 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS TOTAL_CONNECTIONS 2 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
+NULL information_schema USER_STATISTICS UPDATE_COMMANDS 16 0 NO bigint NULL NULL 19 0 NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS USER 1 NO varchar 48 144 NULL NULL NULL utf8 utf8_general_ci varchar(48)
NULL information_schema VIEWS CHARACTER_SET_CLIENT 9 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
NULL information_schema VIEWS CHECK_OPTION 5 NO varchar 8 24 NULL NULL NULL utf8 utf8_general_ci varchar(8)
NULL information_schema VIEWS COLLATION_CONNECTION 10 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32)
@@ -301,6 +487,11 @@ NULL information_schema VIEWS TABLE_CATALOG 1 NULL YES varchar 512 1536 NULL NUL
NULL information_schema VIEWS TABLE_NAME 3 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema VIEWS TABLE_SCHEMA 2 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
NULL information_schema VIEWS VIEW_DEFINITION 4 NULL NO longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext
+NULL information_schema XTRADB_ADMIN_COMMAND result_message 1 NO varchar 1024 3072 NULL NULL NULL utf8 utf8_general_ci varchar(1024)
+NULL information_schema XTRADB_ENHANCEMENTS comment 3 NO varchar 100 300 NULL NULL NULL utf8 utf8_general_ci varchar(100)
+NULL information_schema XTRADB_ENHANCEMENTS description 2 NO varchar 255 765 NULL NULL NULL utf8 utf8_general_ci varchar(255)
+NULL information_schema XTRADB_ENHANCEMENTS link 4 NO varchar 255 765 NULL NULL NULL utf8 utf8_general_ci varchar(255)
+NULL information_schema XTRADB_ENHANCEMENTS name 1 NO varchar 255 765 NULL NULL NULL utf8 utf8_general_ci varchar(255)
##########################################################################
# Show the quotient of CHARACTER_OCTET_LENGTH and CHARACTER_MAXIMUM_LENGTH
##########################################################################
@@ -344,6 +535,7 @@ NULL datetime NULL NULL
NULL decimal NULL NULL
NULL double NULL NULL
NULL int NULL NULL
+NULL tinyint NULL NULL
--> CHAR(0) is allowed (see manual), and here both CHARACHTER_* values
--> are 0, which is intended behavior, and the result of 0 / 0 IS NULL
SELECT CHARACTER_OCTET_LENGTH / CHARACTER_MAXIMUM_LENGTH AS COL_CML,
@@ -366,28 +558,28 @@ COL_CML TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH C
3.0000 information_schema CHARACTER_SETS DESCRIPTION varchar 60 180 utf8 utf8_general_ci varchar(60)
NULL information_schema CHARACTER_SETS MAXLEN bigint NULL NULL NULL NULL bigint(3)
3.0000 information_schema CLIENT_STATISTICS CLIENT varchar 64 192 utf8 utf8_general_ci varchar(64)
-NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS CONNECTED_TIME int NULL NULL NULL NULL int(21)
+NULL information_schema CLIENT_STATISTICS TOTAL_CONNECTIONS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS CONCURRENT_CONNECTIONS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS CONNECTED_TIME bigint NULL NULL NULL NULL bigint(21)
NULL information_schema CLIENT_STATISTICS BUSY_TIME double NULL NULL NULL NULL double
NULL information_schema CLIENT_STATISTICS CPU_TIME double NULL NULL NULL NULL double
-NULL information_schema CLIENT_STATISTICS BYTES_RECEIVED int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS BYTES_SENT int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS ROWS_READ int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS ROWS_SENT int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS ROWS_DELETED int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS ROWS_INSERTED int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS ROWS_UPDATED int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS SELECT_COMMANDS int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS UPDATE_COMMANDS int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS OTHER_COMMANDS int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS COMMIT_TRANSACTIONS int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS ROLLBACK_TRANSACTIONS int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS DENIED_CONNECTIONS int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS LOST_CONNECTIONS int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS ACCESS_DENIED int NULL NULL NULL NULL int(21)
-NULL information_schema CLIENT_STATISTICS EMPTY_QUERIES int NULL NULL NULL NULL int(21)
+NULL information_schema CLIENT_STATISTICS BYTES_RECEIVED bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS BYTES_SENT bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS BINLOG_BYTES_WRITTEN bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_READ bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_SENT bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_DELETED bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_INSERTED bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROWS_UPDATED bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS SELECT_COMMANDS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS UPDATE_COMMANDS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS OTHER_COMMANDS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS COMMIT_TRANSACTIONS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ROLLBACK_TRANSACTIONS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS DENIED_CONNECTIONS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS LOST_CONNECTIONS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS ACCESS_DENIED bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema CLIENT_STATISTICS EMPTY_QUERIES bigint NULL NULL NULL NULL bigint(21)
3.0000 information_schema COLLATIONS COLLATION_NAME varchar 32 96 utf8 utf8_general_ci varchar(32)
3.0000 information_schema COLLATIONS CHARACTER_SET_NAME varchar 32 96 utf8 utf8_general_ci varchar(32)
NULL information_schema COLLATIONS ID bigint NULL NULL NULL NULL bigint(11)
@@ -425,7 +617,7 @@ NULL information_schema COLUMNS DATETIME_PRECISION bigint NULL NULL NULL NULL bi
3.0000 information_schema COLUMN_PRIVILEGES IS_GRANTABLE varchar 3 9 utf8 utf8_general_ci varchar(3)
3.0000 information_schema ENGINES ENGINE varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema ENGINES SUPPORT varchar 8 24 utf8 utf8_general_ci varchar(8)
-3.0000 information_schema ENGINES COMMENT varchar 80 240 utf8 utf8_general_ci varchar(80)
+3.0000 information_schema ENGINES COMMENT varchar 160 480 utf8 utf8_general_ci varchar(160)
3.0000 information_schema ENGINES TRANSACTIONS varchar 3 9 utf8 utf8_general_ci varchar(3)
3.0000 information_schema ENGINES XA varchar 3 9 utf8 utf8_general_ci varchar(3)
3.0000 information_schema ENGINES SAVEPOINTS varchar 3 9 utf8 utf8_general_ci varchar(3)
@@ -498,7 +690,7 @@ NULL information_schema FILES CHECKSUM bigint NULL NULL NULL NULL bigint(21) uns
3.0000 information_schema INDEX_STATISTICS TABLE_SCHEMA varchar 192 576 utf8 utf8_general_ci varchar(192)
3.0000 information_schema INDEX_STATISTICS TABLE_NAME varchar 192 576 utf8 utf8_general_ci varchar(192)
3.0000 information_schema INDEX_STATISTICS INDEX_NAME varchar 192 576 utf8 utf8_general_ci varchar(192)
-NULL information_schema INDEX_STATISTICS ROWS_READ int NULL NULL NULL NULL int(21)
+NULL information_schema INDEX_STATISTICS ROWS_READ bigint NULL NULL NULL NULL bigint(21)
3.0000 information_schema INNODB_BUFFER_POOL_PAGES page_type varchar 64 192 utf8 utf8_general_ci varchar(64)
NULL information_schema INNODB_BUFFER_POOL_PAGES space_id bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES page_no bigint NULL NULL NULL NULL bigint(21) unsigned
@@ -513,15 +705,13 @@ NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB next_page_no bigint NULL N
NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB lru_position bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB fix_count bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_BLOB flush_type bigint NULL NULL NULL NULL bigint(21) unsigned
-3.0000 information_schema INNODB_BUFFER_POOL_PAGES_INDEX schema_name varchar 64 192 utf8 utf8_general_ci varchar(64)
-3.0000 information_schema INNODB_BUFFER_POOL_PAGES_INDEX table_name varchar 64 192 utf8 utf8_general_ci varchar(64)
-3.0000 information_schema INNODB_BUFFER_POOL_PAGES_INDEX index_name varchar 64 192 utf8 utf8_general_ci varchar(64)
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX index_id bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX space_id bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX page_no bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX n_recs bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX data_size bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX hashed bigint NULL NULL NULL NULL bigint(21) unsigned
-NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX accessed bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX access_time bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX modified bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX dirty bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_BUFFER_POOL_PAGES_INDEX old bigint NULL NULL NULL NULL bigint(21) unsigned
@@ -550,6 +740,7 @@ NULL information_schema INNODB_CMP_RESET compress_ops_ok int NULL NULL NULL NULL
NULL information_schema INNODB_CMP_RESET compress_time int NULL NULL NULL NULL int(11)
NULL information_schema INNODB_CMP_RESET uncompress_ops int NULL NULL NULL NULL int(11)
NULL information_schema INNODB_CMP_RESET uncompress_time int NULL NULL NULL NULL int(11)
+3.0000 information_schema INNODB_INDEX_STATS table_schema varchar 192 576 utf8 utf8_general_ci varchar(192)
3.0000 information_schema INNODB_INDEX_STATS table_name varchar 192 576 utf8 utf8_general_ci varchar(192)
3.0000 information_schema INNODB_INDEX_STATS index_name varchar 192 576 utf8 utf8_general_ci varchar(192)
NULL information_schema INNODB_INDEX_STATS fields bigint NULL NULL NULL NULL bigint(21) unsigned
@@ -576,6 +767,27 @@ NULL information_schema INNODB_RSEG zip_size bigint NULL NULL NULL NULL bigint(2
NULL information_schema INNODB_RSEG page_no bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_RSEG max_size bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_RSEG curr_size bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES TABLE_ID bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES ID bigint NULL NULL NULL NULL bigint(21) unsigned
+3.0000 information_schema INNODB_SYS_INDEXES NAME varchar 192 576 utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_SYS_INDEXES N_FIELDS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES TYPE bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES SPACE bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_INDEXES PAGE_NO bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS INDEX_ID bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS KEY_COLS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS DIFF_VALS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_STATS NON_NULL_VALS bigint NULL NULL NULL NULL bigint(21) unsigned
+3.0000 information_schema INNODB_SYS_TABLES SCHEMA varchar 192 576 utf8 utf8_general_ci varchar(192)
+3.0000 information_schema INNODB_SYS_TABLES NAME varchar 192 576 utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_SYS_TABLES ID bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES N_COLS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES TYPE bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES MIX_ID bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema INNODB_SYS_TABLES MIX_LEN bigint NULL NULL NULL NULL bigint(21) unsigned
+3.0000 information_schema INNODB_SYS_TABLES CLUSTER_NAME varchar 192 576 utf8 utf8_general_ci varchar(192)
+NULL information_schema INNODB_SYS_TABLES SPACE bigint NULL NULL NULL NULL bigint(21) unsigned
+3.0000 information_schema INNODB_TABLE_STATS table_schema varchar 192 576 utf8 utf8_general_ci varchar(192)
3.0000 information_schema INNODB_TABLE_STATS table_name varchar 192 576 utf8 utf8_general_ci varchar(192)
NULL information_schema INNODB_TABLE_STATS rows bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_TABLE_STATS clust_size bigint NULL NULL NULL NULL bigint(21) unsigned
@@ -589,6 +801,18 @@ NULL information_schema INNODB_TRX trx_wait_started datetime NULL NULL NULL NULL
NULL information_schema INNODB_TRX trx_weight bigint NULL NULL NULL NULL bigint(21) unsigned
NULL information_schema INNODB_TRX trx_mysql_thread_id bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema INNODB_TRX trx_query varchar 1024 3072 utf8 utf8_general_ci varchar(1024)
+3.0000 information_schema KEY_CACHES KEY_CACHE_NAME varchar 192 576 utf8 utf8_general_ci varchar(192)
+NULL information_schema KEY_CACHES SEGMENTS int NULL NULL NULL NULL int(3) unsigned
+NULL information_schema KEY_CACHES SEGMENT_NUMBER int NULL NULL NULL NULL int(3) unsigned
+NULL information_schema KEY_CACHES FULL_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES BLOCK_SIZE bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES USED_BLOCKS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES UNUSED_BLOCKS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES DIRTY_BLOCKS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES READ_REQUESTS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES READS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES WRITE_REQUESTS bigint NULL NULL NULL NULL bigint(21) unsigned
+NULL information_schema KEY_CACHES WRITES bigint NULL NULL NULL NULL bigint(21) unsigned
3.0000 information_schema KEY_COLUMN_USAGE CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
3.0000 information_schema KEY_COLUMN_USAGE CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema KEY_COLUMN_USAGE CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
@@ -626,6 +850,9 @@ NULL information_schema PARTITIONS CHECKSUM bigint NULL NULL NULL NULL bigint(21
3.0000 information_schema PARTITIONS PARTITION_COMMENT varchar 80 240 utf8 utf8_general_ci varchar(80)
3.0000 information_schema PARTITIONS NODEGROUP varchar 12 36 utf8 utf8_general_ci varchar(12)
3.0000 information_schema PARTITIONS TABLESPACE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
+NULL information_schema PBXT_STATISTICS ID int NULL NULL NULL NULL int(4)
+3.0000 information_schema PBXT_STATISTICS Name varchar 40 120 utf8 utf8_general_ci varchar(40)
+NULL information_schema PBXT_STATISTICS Value bigint NULL NULL NULL NULL bigint(8)
3.0000 information_schema PLUGINS PLUGIN_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema PLUGINS PLUGIN_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20)
3.0000 information_schema PLUGINS PLUGIN_STATUS varchar 10 30 utf8 utf8_general_ci varchar(10)
@@ -636,6 +863,8 @@ NULL information_schema PARTITIONS CHECKSUM bigint NULL NULL NULL NULL bigint(21
3.0000 information_schema PLUGINS PLUGIN_AUTHOR varchar 64 192 utf8 utf8_general_ci varchar(64)
1.0000 information_schema PLUGINS PLUGIN_DESCRIPTION longtext 4294967295 4294967295 utf8 utf8_general_ci longtext
3.0000 information_schema PLUGINS PLUGIN_LICENSE varchar 80 240 utf8 utf8_general_ci varchar(80)
+3.0000 information_schema PLUGINS PLUGIN_MATURITY varchar 12 36 utf8 utf8_general_ci varchar(12)
+3.0000 information_schema PLUGINS PLUGIN_AUTH_VERSION varchar 80 240 utf8 utf8_general_ci varchar(80)
NULL information_schema PROCESSLIST ID bigint NULL NULL NULL NULL bigint(4)
3.0000 information_schema PROCESSLIST USER varchar 16 48 utf8 utf8_general_ci varchar(16)
3.0000 information_schema PROCESSLIST HOST varchar 64 192 utf8 utf8_general_ci varchar(64)
@@ -645,6 +874,9 @@ NULL information_schema PROCESSLIST TIME int NULL NULL NULL NULL int(7)
3.0000 information_schema PROCESSLIST STATE varchar 64 192 utf8 utf8_general_ci varchar(64)
1.0000 information_schema PROCESSLIST INFO longtext 4294967295 4294967295 utf8 utf8_general_ci longtext
NULL information_schema PROCESSLIST TIME_MS decimal NULL NULL NULL NULL decimal(22,3)
+NULL information_schema PROCESSLIST STAGE tinyint NULL NULL NULL NULL tinyint(2)
+NULL information_schema PROCESSLIST MAX_STAGE tinyint NULL NULL NULL NULL tinyint(2)
+NULL information_schema PROCESSLIST PROGRESS decimal NULL NULL NULL NULL decimal(7,3)
3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema REFERENTIAL_CONSTRAINTS CONSTRAINT_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
@@ -743,9 +975,9 @@ NULL information_schema TABLES CHECKSUM bigint NULL NULL NULL NULL bigint(21) un
3.0000 information_schema TABLE_PRIVILEGES IS_GRANTABLE varchar 3 9 utf8 utf8_general_ci varchar(3)
3.0000 information_schema TABLE_STATISTICS TABLE_SCHEMA varchar 192 576 utf8 utf8_general_ci varchar(192)
3.0000 information_schema TABLE_STATISTICS TABLE_NAME varchar 192 576 utf8 utf8_general_ci varchar(192)
-NULL information_schema TABLE_STATISTICS ROWS_READ int NULL NULL NULL NULL int(21)
-NULL information_schema TABLE_STATISTICS ROWS_CHANGED int NULL NULL NULL NULL int(21)
-NULL information_schema TABLE_STATISTICS ROWS_CHANGED_X_INDEXES int NULL NULL NULL NULL int(21)
+NULL information_schema TABLE_STATISTICS ROWS_READ bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema TABLE_STATISTICS ROWS_CHANGED bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema TABLE_STATISTICS ROWS_CHANGED_X_INDEXES bigint NULL NULL NULL NULL bigint(21)
3.0000 information_schema TRIGGERS TRIGGER_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
3.0000 information_schema TRIGGERS TRIGGER_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema TRIGGERS TRIGGER_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
@@ -773,28 +1005,28 @@ NULL information_schema TRIGGERS CREATED datetime NULL NULL NULL NULL datetime
3.0000 information_schema USER_PRIVILEGES PRIVILEGE_TYPE varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema USER_PRIVILEGES IS_GRANTABLE varchar 3 9 utf8 utf8_general_ci varchar(3)
3.0000 information_schema USER_STATISTICS USER varchar 48 144 utf8 utf8_general_ci varchar(48)
-NULL information_schema USER_STATISTICS TOTAL_CONNECTIONS int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS CONCURRENT_CONNECTIONS int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS CONNECTED_TIME int NULL NULL NULL NULL int(21)
+NULL information_schema USER_STATISTICS TOTAL_CONNECTIONS int NULL NULL NULL NULL int(11)
+NULL information_schema USER_STATISTICS CONCURRENT_CONNECTIONS int NULL NULL NULL NULL int(11)
+NULL information_schema USER_STATISTICS CONNECTED_TIME int NULL NULL NULL NULL int(11)
NULL information_schema USER_STATISTICS BUSY_TIME double NULL NULL NULL NULL double
NULL information_schema USER_STATISTICS CPU_TIME double NULL NULL NULL NULL double
-NULL information_schema USER_STATISTICS BYTES_RECEIVED int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS BYTES_SENT int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS BINLOG_BYTES_WRITTEN int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS ROWS_READ int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS ROWS_SENT int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS ROWS_DELETED int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS ROWS_INSERTED int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS ROWS_UPDATED int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS SELECT_COMMANDS int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS UPDATE_COMMANDS int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS OTHER_COMMANDS int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS COMMIT_TRANSACTIONS int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS ROLLBACK_TRANSACTIONS int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS DENIED_CONNECTIONS int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS LOST_CONNECTIONS int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS ACCESS_DENIED int NULL NULL NULL NULL int(21)
-NULL information_schema USER_STATISTICS EMPTY_QUERIES int NULL NULL NULL NULL int(21)
+NULL information_schema USER_STATISTICS BYTES_RECEIVED bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS BYTES_SENT bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS BINLOG_BYTES_WRITTEN bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_READ bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_SENT bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_DELETED bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_INSERTED bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROWS_UPDATED bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS SELECT_COMMANDS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS UPDATE_COMMANDS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS OTHER_COMMANDS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS COMMIT_TRANSACTIONS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ROLLBACK_TRANSACTIONS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS DENIED_CONNECTIONS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS LOST_CONNECTIONS bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS ACCESS_DENIED bigint NULL NULL NULL NULL bigint(21)
+NULL information_schema USER_STATISTICS EMPTY_QUERIES bigint NULL NULL NULL NULL bigint(21)
3.0000 information_schema VIEWS TABLE_CATALOG varchar 512 1536 utf8 utf8_general_ci varchar(512)
3.0000 information_schema VIEWS TABLE_SCHEMA varchar 64 192 utf8 utf8_general_ci varchar(64)
3.0000 information_schema VIEWS TABLE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64)
@@ -805,6 +1037,7 @@ NULL information_schema USER_STATISTICS EMPTY_QUERIES int NULL NULL NULL NULL in
3.0000 information_schema VIEWS SECURITY_TYPE varchar 7 21 utf8 utf8_general_ci varchar(7)
3.0000 information_schema VIEWS CHARACTER_SET_CLIENT varchar 32 96 utf8 utf8_general_ci varchar(32)
3.0000 information_schema VIEWS COLLATION_CONNECTION varchar 32 96 utf8 utf8_general_ci varchar(32)
+3.0000 information_schema XTRADB_ADMIN_COMMAND result_message varchar 1024 3072 utf8 utf8_general_ci varchar(1024)
3.0000 information_schema XTRADB_ENHANCEMENTS name varchar 255 765 utf8 utf8_general_ci varchar(255)
3.0000 information_schema XTRADB_ENHANCEMENTS description varchar 255 765 utf8 utf8_general_ci varchar(255)
3.0000 information_schema XTRADB_ENHANCEMENTS comment varchar 100 300 utf8 utf8_general_ci varchar(100)
diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
index e93070952f4..8d486bae3a3 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
@@ -197,7 +197,7 @@ NULL mysql user Lock_tables_priv 21 N NO enum 1 3 NULL NULL NULL utf8 utf8_gener
NULL mysql user max_connections 38 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references
NULL mysql user max_questions 36 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references
NULL mysql user max_updates 37 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references
-NULL mysql user max_user_connections 39 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references
+NULL mysql user max_user_connections 39 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
NULL mysql user Password 3 NO char 41 41 NULL NULL NULL latin1 latin1_bin char(41) select,insert,update,references
NULL mysql user plugin 40 NO char 60 60 NULL NULL NULL latin1 latin1_swedish_ci char(60) select,insert,update,references
NULL mysql user Process_priv 12 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
@@ -499,6 +499,6 @@ NULL mysql time_zone_transition_type Is_DST tinyint NULL NULL NULL NULL tinyint(
NULL mysql user max_questions int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_updates int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_connections int NULL NULL NULL NULL int(11) unsigned
-NULL mysql user max_user_connections int NULL NULL NULL NULL int(11) unsigned
+NULL mysql user max_user_connections int NULL NULL NULL NULL int(11)
1.0000 mysql user plugin char 60 60 latin1 latin1_swedish_ci char(60)
1.0000 mysql user auth_string text 65535 65535 utf8 utf8_bin text
diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result
index 941fb873596..8617628532c 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql_embedded.result
@@ -49,7 +49,7 @@ NULL mysql event modified 9 0000-00-00 00:00:00 NO timestamp NULL NULL NULL NULL
NULL mysql event name 2 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64) PRI
NULL mysql event on_completion 14 DROP NO enum 8 24 NULL NULL NULL utf8 utf8_general_ci enum('DROP','PRESERVE')
NULL mysql event originator 17 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned
-NULL mysql event sql_mode 15 NO set 478 1434 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+NULL mysql event sql_mode 15 NO set 494 1482 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
NULL mysql event starts 11 NULL YES datetime NULL NULL NULL NULL 0 NULL NULL datetime
NULL mysql event status 13 ENABLED NO enum 18 54 NULL NULL NULL utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
NULL mysql event time_zone 18 SYSTEM NO char 64 64 NULL NULL NULL latin1 latin1_swedish_ci char(64)
@@ -59,7 +59,7 @@ NULL mysql func ret 2 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(1)
NULL mysql func type 4 NULL NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('function','aggregate')
NULL mysql general_log argument 6 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext
NULL mysql general_log command_type 5 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64)
-NULL mysql general_log event_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP
+NULL mysql general_log event_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP
NULL mysql general_log server_id 4 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned
NULL mysql general_log thread_id 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11)
NULL mysql general_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext
@@ -124,7 +124,7 @@ NULL mysql proc returns 10 NULL NO longblob 4294967295 4294967295 NULL NULL NULL
NULL mysql proc security_type 8 DEFINER NO enum 7 21 NULL NULL NULL utf8 utf8_general_ci enum('INVOKER','DEFINER')
NULL mysql proc specific_name 4 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci char(64)
NULL mysql proc sql_data_access 6 CONTAINS_SQL NO enum 17 51 NULL NULL NULL utf8 utf8_general_ci enum('CONTAINS_SQL','NO_SQL','READS_SQL_DATA','MODIFIES_SQL_DATA')
-NULL mysql proc sql_mode 15 NO set 478 1434 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+NULL mysql proc sql_mode 15 NO set 494 1482 NULL NULL NULL utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
NULL mysql proc type 3 NULL NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('FUNCTION','PROCEDURE') PRI
NULL mysql procs_priv Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
NULL mysql procs_priv Grantor 6 NO char 77 231 NULL NULL NULL utf8 utf8_bin char(77) MUL
@@ -146,13 +146,13 @@ NULL mysql servers Wrapper 8 NO char 64 192 NULL NULL NULL utf8 utf8_general_ci
NULL mysql slow_log db 7 NULL NO varchar 512 1536 NULL NULL NULL utf8 utf8_general_ci varchar(512)
NULL mysql slow_log insert_id 9 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11)
NULL mysql slow_log last_insert_id 8 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11)
-NULL mysql slow_log lock_time 4 NULL NO time NULL NULL NULL NULL 0 NULL NULL time
-NULL mysql slow_log query_time 3 NULL NO time NULL NULL NULL NULL 0 NULL NULL time
+NULL mysql slow_log lock_time 4 NULL NO time NULL NULL NULL NULL 6 NULL NULL time(6)
+NULL mysql slow_log query_time 3 NULL NO time NULL NULL NULL NULL 6 NULL NULL time(6)
NULL mysql slow_log rows_examined 6 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11)
NULL mysql slow_log rows_sent 5 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11)
NULL mysql slow_log server_id 10 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned
NULL mysql slow_log sql_text 11 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext
-NULL mysql slow_log start_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 0 NULL NULL timestamp on update CURRENT_TIMESTAMP
+NULL mysql slow_log start_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP
NULL mysql slow_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext
NULL mysql tables_priv Column_priv 8 NO set 31 93 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','References')
NULL mysql tables_priv Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI
@@ -178,6 +178,7 @@ NULL mysql time_zone_transition_type Time_zone_id 1 NULL NO int NULL NULL 10 0 N
NULL mysql time_zone_transition_type Transition_type_id 2 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned PRI
NULL mysql user Alter_priv 17 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
NULL mysql user Alter_routine_priv 28 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
+NULL mysql user auth_string 41 NULL NO text 65535 65535 NULL NULL NULL utf8 utf8_bin text
NULL mysql user Create_priv 8 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
NULL mysql user Create_routine_priv 27 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
NULL mysql user Create_tmp_table_priv 20 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
@@ -198,6 +199,7 @@ NULL mysql user max_questions 36 0 NO int NULL NULL 10 0 NULL NULL NULL int(11)
NULL mysql user max_updates 37 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned
NULL mysql user max_user_connections 39 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned
NULL mysql user Password 3 NO char 41 41 NULL NULL NULL latin1 latin1_bin char(41)
+NULL mysql user plugin 40 NO char 60 60 NULL NULL NULL latin1 latin1_swedish_ci char(60)
NULL mysql user Process_priv 12 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
NULL mysql user References_priv 15 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
NULL mysql user Reload_priv 10 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y')
@@ -233,6 +235,7 @@ COL_CML DATA_TYPE CHARACTER_SET_NAME COLLATION_NAME
1.0000 char latin1 latin1_bin
1.0000 char latin1 latin1_swedish_ci
1.0000 varchar latin1 latin1_swedish_ci
+1.0000 text utf8 utf8_bin
1.0000 mediumtext utf8 utf8_general_ci
1.0000 text utf8 utf8_general_ci
SELECT DISTINCT
@@ -327,7 +330,7 @@ NULL mysql event starts datetime NULL NULL NULL NULL datetime
NULL mysql event ends datetime NULL NULL NULL NULL datetime
3.0000 mysql event status enum 18 54 utf8 utf8_general_ci enum('ENABLED','DISABLED','SLAVESIDE_DISABLED')
3.0000 mysql event on_completion enum 8 24 utf8 utf8_general_ci enum('DROP','PRESERVE')
-3.0000 mysql event sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql event sql_mode set 494 1482 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql event comment char 64 192 utf8 utf8_bin char(64)
NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
1.0000 mysql event time_zone char 64 64 latin1 latin1_swedish_ci char(64)
@@ -339,7 +342,7 @@ NULL mysql event originator int NULL NULL NULL NULL int(10) unsigned
NULL mysql func ret tinyint NULL NULL NULL NULL tinyint(1)
3.0000 mysql func dl char 128 384 utf8 utf8_bin char(128)
3.0000 mysql func type enum 9 27 utf8 utf8_general_ci enum('function','aggregate')
-NULL mysql general_log event_time timestamp NULL NULL NULL NULL timestamp
+NULL mysql general_log event_time timestamp NULL NULL NULL NULL timestamp(6)
1.0000 mysql general_log user_host mediumtext 16777215 16777215 utf8 utf8_general_ci mediumtext
NULL mysql general_log thread_id int NULL NULL NULL NULL int(11)
NULL mysql general_log server_id int NULL NULL NULL NULL int(10) unsigned
@@ -402,7 +405,7 @@ NULL mysql ndb_binlog_index schemaops bigint NULL NULL NULL NULL bigint(20) unsi
3.0000 mysql proc definer char 77 231 utf8 utf8_bin char(77)
NULL mysql proc created timestamp NULL NULL NULL NULL timestamp
NULL mysql proc modified timestamp NULL NULL NULL NULL timestamp
-3.0000 mysql proc sql_mode set 478 1434 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
+3.0000 mysql proc sql_mode set 494 1482 utf8 utf8_general_ci set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','IGNORE_BAD_TABLE_OPTIONS','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE','NO_ENGINE_SUBSTITUTION','PAD_CHAR_TO_FULL_LENGTH')
3.0000 mysql proc comment char 64 192 utf8 utf8_bin char(64)
3.0000 mysql proc character_set_client char 32 96 utf8 utf8_bin char(32)
3.0000 mysql proc collation_connection char 32 96 utf8 utf8_bin char(32)
@@ -425,10 +428,10 @@ NULL mysql servers Port int NULL NULL NULL NULL int(4)
3.0000 mysql servers Socket char 64 192 utf8 utf8_general_ci char(64)
3.0000 mysql servers Wrapper char 64 192 utf8 utf8_general_ci char(64)
3.0000 mysql servers Owner char 64 192 utf8 utf8_general_ci char(64)
-NULL mysql slow_log start_time timestamp NULL NULL NULL NULL timestamp
+NULL mysql slow_log start_time timestamp NULL NULL NULL NULL timestamp(6)
1.0000 mysql slow_log user_host mediumtext 16777215 16777215 utf8 utf8_general_ci mediumtext
-NULL mysql slow_log query_time time NULL NULL NULL NULL time
-NULL mysql slow_log lock_time time NULL NULL NULL NULL time
+NULL mysql slow_log query_time time NULL NULL NULL NULL time(6)
+NULL mysql slow_log lock_time time NULL NULL NULL NULL time(6)
NULL mysql slow_log rows_sent int NULL NULL NULL NULL int(11)
NULL mysql slow_log rows_examined int NULL NULL NULL NULL int(11)
3.0000 mysql slow_log db varchar 512 1536 utf8 utf8_general_ci varchar(512)
@@ -497,3 +500,5 @@ NULL mysql user max_questions int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_updates int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_connections int NULL NULL NULL NULL int(11) unsigned
NULL mysql user max_user_connections int NULL NULL NULL NULL int(11) unsigned
+1.0000 mysql user plugin char 60 60 latin1 latin1_swedish_ci char(60)
+1.0000 mysql user auth_string text 65535 65535 utf8 utf8_bin text
diff --git a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result
index 187724a035c..f4fe0a880e7 100644
--- a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result
+++ b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result
@@ -38,6 +38,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME CLIENT_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME COLLATIONS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -245,6 +268,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME INDEX_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME INNODB_BUFFER_POOL_PAGES
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -498,6 +544,75 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_INDEXES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_STATS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_TABLES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME INNODB_TABLE_STATS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -544,6 +659,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME KEY_CACHES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME KEY_COLUMN_USAGE
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -590,6 +728,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME PBXT_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME PLUGINS
TABLE_TYPE SYSTEM VIEW
ENGINE MYISAM_OR_MARIA
@@ -866,6 +1027,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME TABLE_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME TRIGGERS
TABLE_TYPE SYSTEM VIEW
ENGINE MYISAM_OR_MARIA
@@ -912,6 +1096,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME USER_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME VIEWS
TABLE_TYPE SYSTEM VIEW
ENGINE MYISAM_OR_MARIA
@@ -935,6 +1142,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME XTRADB_ADMIN_COMMAND
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME XTRADB_ENHANCEMENTS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -998,6 +1228,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME CLIENT_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME COLLATIONS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1205,6 +1458,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME INDEX_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME INNODB_BUFFER_POOL_PAGES
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1458,6 +1734,75 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_INDEXES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_STATS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
+TABLE_NAME INNODB_SYS_TABLES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME INNODB_TABLE_STATS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1504,6 +1849,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME KEY_CACHES
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME KEY_COLUMN_USAGE
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
@@ -1550,6 +1918,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME PBXT_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME PLUGINS
TABLE_TYPE SYSTEM VIEW
ENGINE MYISAM_OR_MARIA
@@ -1826,6 +2217,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME TABLE_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME TRIGGERS
TABLE_TYPE SYSTEM VIEW
ENGINE MYISAM_OR_MARIA
@@ -1872,6 +2286,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME USER_STATISTICS
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME VIEWS
TABLE_TYPE SYSTEM VIEW
ENGINE MYISAM_OR_MARIA
@@ -1895,6 +2332,29 @@ user_comment
Separator -----------------------------------------------------
TABLE_CATALOG NULL
TABLE_SCHEMA information_schema
+TABLE_NAME XTRADB_ADMIN_COMMAND
+TABLE_TYPE SYSTEM VIEW
+ENGINE MEMORY
+VERSION 10
+ROW_FORMAT Fixed
+TABLE_ROWS #TBLR#
+AVG_ROW_LENGTH #ARL#
+DATA_LENGTH #DL#
+MAX_DATA_LENGTH #MDL#
+INDEX_LENGTH #IL#
+DATA_FREE #DF#
+AUTO_INCREMENT NULL
+CREATE_TIME #CRT#
+UPDATE_TIME #UT#
+CHECK_TIME #CT#
+TABLE_COLLATION utf8_general_ci
+CHECKSUM NULL
+CREATE_OPTIONS #CO#
+TABLE_COMMENT #TC#
+user_comment
+Separator -----------------------------------------------------
+TABLE_CATALOG NULL
+TABLE_SCHEMA information_schema
TABLE_NAME XTRADB_ENHANCEMENTS
TABLE_TYPE SYSTEM VIEW
ENGINE MEMORY
diff --git a/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result b/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result
index e5eeed7c82b..b5d330dffb5 100644
--- a/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result
+++ b/mysql-test/suite/funcs_1/r/processlist_priv_no_prot.result
@@ -30,28 +30,31 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Query TIME NULL SHOW processlist
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-SELECT * FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID root HOST_NAME information_schema Query TIME executing SELECT * FROM processlist ORDER BY id TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
-SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID root HOST_NAME information_schema Query TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id TIME_MS
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+SELECT * FROM processlist ORDER BY id;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID root HOST_NAME information_schema Query TIME executing SELECT * FROM processlist ORDER BY id TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID root HOST_NAME information_schema Query TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist;
UPDATE test.t_processlist SET user='horst' WHERE id=1 ;
INSERT INTO processlist SELECT * FROM test.t_processlist;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
DROP TABLE test.t_processlist;
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist WITH CHECK OPTION;
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist WITH CHECK OPTION;
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist;
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist;
DROP VIEW test.v_processlist;
UPDATE processlist SET user='any_user' WHERE id=1 ;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
@@ -99,25 +102,28 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM processlist ORDER BY id TIME_MS
-SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS FROM processlist ORDER BY id TIME_MS
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM processlist ORDER BY id TIME_MS 0 0 0.000
+SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id TIME_MS 0 0 0.000
CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist;
UPDATE test.t_processlist SET user='horst' WHERE id=1 ;
INSERT INTO processlist SELECT * FROM test.t_processlist;
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
DROP TABLE test.t_processlist;
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist WITH CHECK OPTION;
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist WITH CHECK OPTION;
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS) AS SELECT * FROM processlist;
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist;
DROP VIEW test.v_processlist;
UPDATE processlist SET user='any_user' WHERE id=1 ;
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
@@ -165,11 +171,11 @@ SHOW GRANTS;
Grants for ddicttestuser1@localhost
GRANT PROCESS ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
####################################################################################
4.2 New connection con101 (ddicttestuser1 with PROCESS privilege)
SHOW/SELECT shows all processes/threads.
@@ -178,15 +184,15 @@ SHOW GRANTS;
Grants for ddicttestuser1@localhost
GRANT PROCESS ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+Id User Host db Command Time State Info Progress
ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
5 Grant PROCESS privilege to anonymous user.
connection default (user=root)
@@ -201,17 +207,17 @@ SHOW GRANTS;
Grants for @localhost
GRANT PROCESS ON *.* TO ''@'localhost'
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
-ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
6 Revoke PROCESS privilege from ddicttestuser1
connection default (user=root)
@@ -226,15 +232,15 @@ SHOW GRANTS;
Grants for ddicttestuser1@localhost
GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
7 Revoke PROCESS privilege from anonymous user
connection default (user=root)
@@ -249,9 +255,9 @@ SHOW GRANTS FOR ''@'localhost';
Grants for @localhost
GRANT USAGE ON *.* TO ''@'localhost'
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
-ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
8 Grant SUPER (does not imply PROCESS) privilege to ddicttestuser1
connection default (user=root)
@@ -265,17 +271,17 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
Grants for ddicttestuser1@localhost
GRANT SUPER ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
9 Revoke SUPER privilege from user ddicttestuser1
connection default (user=root)
@@ -290,19 +296,19 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
Grants for ddicttestuser1@localhost
GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
10 Grant SUPER privilege with grant option to user ddicttestuser1.
connection default (user=root)
@@ -338,23 +344,8 @@ SHOW GRANTS FOR 'ddicttestuser2'@'localhost';
Grants for ddicttestuser2@localhost
GRANT PROCESS ON *.* TO 'ddicttestuser2'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser2 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
@@ -362,7 +353,22 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
-ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser2 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
11 User ddicttestuser1 revokes PROCESS privilege from user ddicttestuser2
connection ddicttestuser1;
@@ -376,13 +382,13 @@ SHOW GRANTS;
Grants for ddicttestuser2@localhost
GRANT USAGE ON *.* TO 'ddicttestuser2'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser2 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser2 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
11.2 Revoke SUPER,PROCESS,GRANT OPTION privilege from user ddicttestuser1
connection default (user=root)
@@ -399,18 +405,7 @@ GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA
GRANT PROCESS ON *.* TO 'ddicttestuser2'@'localhost';
ERROR 28000: Access denied for user 'ddicttestuser1'@'localhost' (using password: YES)
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
@@ -418,6 +413,17 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
12 Revoke the SELECT privilege from user ddicttestuser1
connection default (user=root)
@@ -434,19 +440,7 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
Grants for ddicttestuser1@localhost
GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
-SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS
+Id User Host db Command Time State Info Progress
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
@@ -455,6 +449,18 @@ ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+SELECT * FROM information_schema.processlist;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
12.2 Revoke only the SELECT privilege on the information_schema from ddicttestuser1.
connection default (user=root)
diff --git a/mysql-test/suite/funcs_1/r/processlist_priv_ps.result b/mysql-test/suite/funcs_1/r/processlist_priv_ps.result
index c5aabfe315c..bc4c197a4bb 100644
--- a/mysql-test/suite/funcs_1/r/processlist_priv_ps.result
+++ b/mysql-test/suite/funcs_1/r/processlist_priv_ps.result
@@ -29,30 +29,32 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`COMMAND` varchar(16) NOT NULL DEFAULT '',
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
- `INFO` longtext
+ `INFO` longtext,
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Query TIME NULL SHOW processlist
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
SELECT * FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID root HOST_NAME information_schema Execute TIME executing SELECT * FROM processlist ORDER BY id
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID root HOST_NAME information_schema Execute TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM processlist ORDER BY id
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID root HOST_NAME information_schema Execute TIME executing SELECT * FROM processlist ORDER BY id TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID root HOST_NAME information_schema Execute TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist;
UPDATE test.t_processlist SET user='horst' WHERE id=1 ;
INSERT INTO processlist SELECT * FROM test.t_processlist;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
DROP TABLE test.t_processlist;
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO) AS SELECT * FROM processlist WITH CHECK OPTION;
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist WITH CHECK OPTION;
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO) AS SELECT * FROM processlist;
-UPDATE test.v_processlist SET TIME=NOW() WHERE id = 1;
-ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist;
DROP VIEW test.v_processlist;
UPDATE processlist SET user='any_user' WHERE id=1 ;
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
@@ -99,27 +101,29 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`COMMAND` varchar(16) NOT NULL DEFAULT '',
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
- `INFO` longtext
+ `INFO` longtext,
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM processlist ORDER BY id
-SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM processlist ORDER BY id;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO FROM processlist ORDER BY id
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM processlist ORDER BY id TIME_MS 0 0 0.000
+SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS FROM processlist ORDER BY id TIME_MS 0 0 0.000
CREATE TEMPORARY TABLE test.t_processlist AS SELECT * FROM processlist;
UPDATE test.t_processlist SET user='horst' WHERE id=1 ;
INSERT INTO processlist SELECT * FROM test.t_processlist;
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
DROP TABLE test.t_processlist;
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO) AS SELECT * FROM processlist WITH CHECK OPTION;
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist WITH CHECK OPTION;
ERROR HY000: CHECK OPTION on non-updatable view 'test.v_processlist'
-CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO) AS SELECT * FROM processlist;
-UPDATE test.v_processlist SET TIME=NOW() WHERE id = 1;
-ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
+CREATE VIEW test.v_processlist (ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO, TIME_MS, STAGE, MAX_STAGE, PROGRESS) AS SELECT * FROM processlist;
DROP VIEW test.v_processlist;
UPDATE processlist SET user='any_user' WHERE id=1 ;
ERROR 42000: Access denied for user 'ddicttestuser1'@'localhost' to database 'information_schema'
@@ -167,11 +171,11 @@ SHOW GRANTS;
Grants for ddicttestuser1@localhost
GRANT PROCESS ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
####################################################################################
4.2 New connection con101 (ddicttestuser1 with PROCESS privilege)
SHOW/SELECT shows all processes/threads.
@@ -180,15 +184,15 @@ SHOW GRANTS;
Grants for ddicttestuser1@localhost
GRANT PROCESS ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID root HOST_NAME information_schema Sleep TIME NULL
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
5 Grant PROCESS privilege to anonymous user.
connection default (user=root)
@@ -203,17 +207,17 @@ SHOW GRANTS;
Grants for @localhost
GRANT PROCESS ON *.* TO ''@'localhost'
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID root HOST_NAME information_schema Sleep TIME NULL
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
6 Revoke PROCESS privilege from ddicttestuser1
connection default (user=root)
@@ -228,15 +232,15 @@ SHOW GRANTS;
Grants for ddicttestuser1@localhost
GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
7 Revoke PROCESS privilege from anonymous user
connection default (user=root)
@@ -251,9 +255,9 @@ SHOW GRANTS FOR ''@'localhost';
Grants for @localhost
GRANT USAGE ON *.* TO ''@'localhost'
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist
-ID HOST_NAME information_schema Sleep TIME NULL
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
8 Grant SUPER (does not imply PROCESS) privilege to ddicttestuser1
connection default (user=root)
@@ -267,17 +271,17 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
Grants for ddicttestuser1@localhost
GRANT SUPER ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
9 Revoke SUPER privilege from user ddicttestuser1
connection default (user=root)
@@ -292,19 +296,19 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
Grants for ddicttestuser1@localhost
GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
10 Grant SUPER privilege with grant option to user ddicttestuser1.
connection default (user=root)
@@ -340,31 +344,31 @@ SHOW GRANTS FOR 'ddicttestuser2'@'localhost';
Grants for ddicttestuser2@localhost
GRANT PROCESS ON *.* TO 'ddicttestuser2'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID root HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID ddicttestuser2 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID root HOST_NAME information_schema Sleep TIME NULL
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser2 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID root HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
11 User ddicttestuser1 revokes PROCESS privilege from user ddicttestuser2
connection ddicttestuser1;
@@ -378,13 +382,13 @@ SHOW GRANTS;
Grants for ddicttestuser2@localhost
GRANT USAGE ON *.* TO 'ddicttestuser2'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser2 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID ddicttestuser2 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist
-ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser2 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser2 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
11.2 Revoke SUPER,PROCESS,GRANT OPTION privilege from user ddicttestuser1
connection default (user=root)
@@ -401,25 +405,25 @@ GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA
GRANT PROCESS ON *.* TO 'ddicttestuser2'@'localhost';
ERROR 28000: Access denied for user 'ddicttestuser1'@'localhost' (using password: YES)
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
12 Revoke the SELECT privilege from user ddicttestuser1
connection default (user=root)
@@ -436,27 +440,27 @@ SHOW GRANTS FOR 'ddicttestuser1'@'localhost';
Grants for ddicttestuser1@localhost
GRANT USAGE ON *.* TO 'ddicttestuser1'@'localhost' IDENTIFIED BY PASSWORD '*22DA61451703738F203CDB9DB041ACBA1F4760B1'
SHOW processlist;
-Id User Host db Command Time State Info
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist
+Id User Host db Command Time State Info Progress
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS
+ID ddicttestuser1 HOST_NAME information_schema Query TIME NULL SHOW processlist TIME_MS
SELECT * FROM information_schema.processlist;
-ID USER HOST DB COMMAND TIME STATE INFO
-ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
-ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+ID ddicttestuser1 HOST_NAME information_schema Execute TIME executing SELECT * FROM information_schema.processlist TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
+ID ddicttestuser1 HOST_NAME information_schema Sleep TIME NULL TIME_MS 0 0 0.000
####################################################################################
12.2 Revoke only the SELECT privilege on the information_schema from ddicttestuser1.
connection default (user=root)
diff --git a/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result b/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result
index aa554553f7f..c5533166acc 100644
--- a/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result
+++ b/mysql-test/suite/funcs_1/r/processlist_val_no_prot.result
@@ -20,17 +20,20 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
`INFO` longtext,
- `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000'
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
# Ensure that the information about the own connection is correct.
#--------------------------------------------------------------------------
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> root <HOST_NAME> test Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> root <HOST_NAME> test Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> test Query <TIME> NULL SHOW FULL PROCESSLIST
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> test Query <TIME> NULL SHOW FULL PROCESSLIST <TIME_MS>
SET @default_id = CONNECTION_ID();
SELECT COUNT(*) = 1 AS "Expect exact one connection with this id"
FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = @default_id;
@@ -73,13 +76,13 @@ Has TIME a reasonable value?
# Poll till the connection con1 is in state COMMAND = 'Sleep'.
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS>
-<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000
SELECT ID,TIME INTO @test_user_con1_id,@time FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE COMMAND = 'Sleep' AND USER = 'test_user';
SELECT @test_user_con1_id = @default_id + 1
@@ -107,11 +110,11 @@ Expect 1
# ----- switch to connection con1 (user = test_user) -----
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
+Id User Host db Command Time State Info Progress
+<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
# Ensure that the user test_user sees all connections with his username.
#----------------------------------------------------------------------------
@@ -124,13 +127,13 @@ Id User Host db Command Time State Info
# ----- switch to connection con2 (user = test_user) -----
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL
-<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
+Id User Host db Command Time State Info Progress
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
# ----- switch to connection default (user = root) -----
SELECT ID INTO @test_user_con2_id FROM INFORMATION_SCHEMA.PROCESSLIST
@@ -150,15 +153,15 @@ SELECT sleep(10), 17;
# Poll till connection con2 is in state 'User sleep'.
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 <TIME_MS>
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS>
-<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL
-<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 0.000
SELECT STATE, TIME, INFO INTO @state, @time, @info
FROM INFORMATION_SCHEMA.PROCESSLIST
WHERE ID = @test_user_con2_id;
@@ -197,10 +200,10 @@ SELECT COUNT(*) FROM test.t1;
# Poll till INFO is no more NULL and State = "Table Lock".
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema Query <TIME> Table lock SELECT COUNT(*) FROM test.t1 <TIME_MS>
-<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS>
-<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Query <TIME> Table lock SELECT COUNT(*) FROM test.t1 <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema Query <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
UNLOCK TABLES;
# ----- switch to connection con2 (user = test_user) -----
@@ -231,20 +234,20 @@ SELECT count(*),'BEGIN-This is the representative of a very long statement.This
# SHOW PROCESSLIST statement truncated after 100 char
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO TIME_MS
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 <TIME_MS>
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL <TIME_MS>
-<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS>
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW FULL PROCESSLIST
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW FULL PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 0.000
SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW PROCESSLIST
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL
-<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representativ
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representativ 0.000
UNLOCK TABLES;
# ----- switch to connection con2 (user = test_user) -----
diff --git a/mysql-test/suite/funcs_1/r/processlist_val_ps.result b/mysql-test/suite/funcs_1/r/processlist_val_ps.result
index 448c68eadb8..546f2a19b61 100644
--- a/mysql-test/suite/funcs_1/r/processlist_val_ps.result
+++ b/mysql-test/suite/funcs_1/r/processlist_val_ps.result
@@ -19,140 +19,245 @@ PROCESSLIST CREATE TEMPORARY TABLE `PROCESSLIST` (
`COMMAND` varchar(16) NOT NULL DEFAULT '',
`TIME` int(7) NOT NULL DEFAULT '0',
`STATE` varchar(64) DEFAULT NULL,
- `INFO` longtext
+ `INFO` longtext,
+ `TIME_MS` decimal(22,3) NOT NULL DEFAULT '0.000',
+ `STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `MAX_STAGE` tinyint(2) NOT NULL DEFAULT '0',
+ `PROGRESS` decimal(7,3) NOT NULL DEFAULT '0.000'
) DEFAULT CHARSET=utf8
-SELECT COUNT(*) FROM INFORMATION_SCHEMA.PROCESSLIST;
-COUNT(*)
-1
-USE test;
+# Ensure that the information about the own connection is correct.
+#--------------------------------------------------------------------------
+
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO
-<ID> root localhost test Execute 0 executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> root <HOST_NAME> test Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root localhost test Query 0 NULL SHOW FULL PROCESSLIST
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> test Query <TIME> NULL SHOW FULL PROCESSLIST <TIME_MS>
+SET @default_id = CONNECTION_ID();
+SELECT COUNT(*) = 1 AS "Expect exact one connection with this id"
+FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = @default_id;
+Expect exact one connection with this id
+1
+SELECT COUNT(*) = 1 AS "Expect 1"
+FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = @default_id
+AND USER = 'root' AND DB = 'test' AND Command IN('Query','Execute')
+AND State = 'executing';
+Expect 1
+1
USE information_schema;
+SELECT COUNT(*) = 1 AS "Is the DB correct?"
+FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID = @default_id AND DB = 'information_schema';
+Is the DB correct?
+1
+SELECT @my_info := INFO FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID = @default_id;
+@my_info := INFO
+SELECT @my_info := INFO FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID = @default_id
+SELECT @my_info = 'SELECT @my_info := INFO FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID = @default_id'
+ AS 'Is the content of PROCESSLIST.INFO correct?';
+Is the content of PROCESSLIST.INFO correct?
+1
+SELECT COUNT(*) = 1 AS "Has TIME a reasonable value?"
+FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID = @default_id AND 0 <= TIME < 10 AND 0 <= TIME_MS < 10000;
+Has TIME a reasonable value?
+1
+# Ensure that the information about an inactive connection is correct.
+#--------------------------------------------------------------------------
+
+# ----- establish connection con1 (user = test_user) -----
+
+# ----- switch to connection default (user = root) -----
+
+# Poll till the connection con1 is in state COMMAND = 'Sleep'.
+
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO
-<ID> root localhost information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root localhost information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
-SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST;
-INFO
-SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST
-SELECT ID INTO @my_proclist_id FROM INFORMATION_SCHEMA.PROCESSLIST;
-
------ establish connection ddicttestuser1 (user = ddicttestuser1) -----
-
------ switch to connection default (user = root) -----
-SELECT @time > 0;
-@time > 0
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000
+SELECT ID,TIME INTO @test_user_con1_id,@time FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE COMMAND = 'Sleep' AND USER = 'test_user';
+SELECT @test_user_con1_id = @default_id + 1
+AS "Did we got the next higher PROCESSLIST ID?";
+Did we got the next higher PROCESSLIST ID?
1
-# Sleep some time
-SELECT @time < @time2;
-@time < @time2
+SELECT 0 <= @time < 10 AS "Has TIME a reasonable value?";
+Has TIME a reasonable value?
1
-SELECT ID = @my_proclist_id + 1 FROM INFORMATION_SCHEMA.PROCESSLIST
-WHERE USER = 'ddicttestuser1';
-ID = @my_proclist_id + 1
+SELECT COUNT(*) = 2 AS "Is HOST LIKE 'localhost%'?"
+FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE HOST LIKE 'localhost%';
+Is HOST LIKE 'localhost%'?
1
+SELECT COUNT(*) = 1 AS "Expect 1"
+FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = @test_user_con1_id
+AND USER = 'test_user' AND DB = 'information_schema'
+ AND Command = 'Sleep' AND State = '' AND INFO IS NULL;
+Expect 1
+1
+# Ensure that the user test_user sees only connections with his username
+# because he has not the PROCESS privilege.
+#----------------------------------------------------------------------------
+
+# ----- switch to connection con1 (user = test_user) -----
------ switch to connection ddicttestuser1 (user = ddicttestuser1) -----
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO
-<ID> ddicttestuser1 localhost information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> ddicttestuser1 localhost information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
+Id User Host db Command Time State Info Progress
+<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
+# Ensure that the user test_user sees all connections with his username.
+#----------------------------------------------------------------------------
+
+----- establish connection con2 (user = test_user) ------
+
+# ----- switch to connection default (user = root) -----
+
+# Poll till all connections of 'test_user' are in a state with COMMAND = 'Sleep'
+
+# ----- switch to connection con2 (user = test_user) -----
------ establish connection con2 (user = ddicttestuser1) ------
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO
-<ID> ddicttestuser1 localhost information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
-<ID> ddicttestuser1 localhost information_schema Sleep <TIME> NULL
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> ddicttestuser1 localhost information_schema Sleep <TIME> NULL
-<ID> ddicttestuser1 localhost information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
-
------ switch to connection default (user = root) -----
------ close connection con2 -----
+Id User Host db Command Time State Info Progress
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
+# ----- switch to connection default (user = root) -----
------ switch to connection ddicttestuser1 (user = ddicttestuser1) -----
+SELECT ID INTO @test_user_con2_id FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID <> @test_user_con1_id
+AND USER = 'test_user' AND DB = 'information_schema';
+# Ensure we get correct information about a connection during work
+#----------------------------------------------------------------------------
+# ----- switch to connection con2 (user = test_user) -----
# Send a long enough running statement to the server, but do not
-# wait till the result comes back. We will pull this later.
-SELECT sleep(2.5),'Command time';
+# wait till the result comes back.
+
+SELECT sleep(10), 17;
+# ----- switch to connection default (user = root) -----
------ switch to connection default (user = root) -----
-# Sleep some time
-SELECT @time > 0;
-@time > 0
+# Poll till connection con2 is in state 'User sleep'.
+
+SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
+SHOW FULL PROCESSLIST;
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema Query <TIME> NULL SHOW FULL PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema Query <TIME> User sleep SELECT sleep(10), 17 0.000
+SELECT STATE, TIME, INFO INTO @state, @time, @info
+FROM INFORMATION_SCHEMA.PROCESSLIST
+WHERE ID = @test_user_con2_id;
+SELECT 0 <= @time < 10 AS "Has TIME a reasonable value?";
+Has TIME a reasonable value?
1
-# Sleep some time
-SELECT @time < @time2;
-@time < @time2
+SELECT @state = 'User sleep' AS "Has STATE the expected value?";
+Has STATE the expected value?
1
+SELECT @info = 'SELECT sleep(10), 17' AS "Has INFO the expected value?";
+Has INFO the expected value?
+1
+# ----- switch to connection con2 (user = testuser) -----
------ switch to connection ddicttestuser1 (user = ddicttestuser1) -----
# Pull("reap") the result set from the statement executed with "send".
-sleep(2.5) Command time
-0 Command time
+sleep(10) 17
+0 17
+# ----- switch to connection default (user = root) -----
-# Send a long (21 KB code and runtime = 2 seconds) statement to the server,
-# but do not wait till the result comes back. We will pull this later.
-SELECT sleep(2),'BEGIN this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.END' AS "my_monster_statement";
+# Poll till all connections of 'test_user' are in a state with COMMAND = 'Sleep'
------ switch to connection default (user = root) -----
-# Sleep some time
-SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO
-<ID> ddicttestuser1 localhost information_schema <COMMAND> <TIME> <STATE> SELECT sleep(2),'BEGIN this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.END' AS "my_monster_statement"
-<ID> root localhost information_schema <COMMAND> <TIME> <STATE> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
-SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root localhost information_schema <COMMAND> <TIME> <STATE> SHOW FULL PROCESSLIST
-<ID> ddicttestuser1 localhost information_schema <COMMAND> <TIME> <STATE> SELECT sleep(2),'BEGIN this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.END' AS "my_monster_statement"
-SHOW PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root localhost information_schema <COMMAND> <TIME> <STATE> SHOW PROCESSLIST
-<ID> ddicttestuser1 localhost information_schema <COMMAND> <TIME> <STATE> SELECT sleep(2),'BEGIN this is the representative of a very long statement.this is the representativ
+# Ensure that we see that a connection "hangs" when colliding with a
+# WRITE TABLE LOCK
+#----------------------------------------------------------------------------
------ switch to connection ddicttestuser1 (user = ddicttestuser1) -----
-# Pull("reap") the result set from the monster statement executed with "send".
-sleep(2) my_monster_statement
-0 BEGIN this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.this is the representative of a very long statement.END
-
------ switch to connection default (user = root) -----
LOCK TABLE test.t1 WRITE;
+# ----- switch to connection con2 (user = test_user) -----
------ switch to connection ddicttestuser1 (user = ddicttestuser1) -----
# Send a statement to the server, but do not wait till the result
# comes back. We will pull this later.
+
SELECT COUNT(*) FROM test.t1;
+# ----- switch to connection default (user = root) -----
+
+# Poll till INFO is no more NULL and State = "Table Lock".
------ switch to connection default (user = root) -----
-# Sleep some time
SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
-ID USER HOST DB COMMAND TIME STATE INFO
-<ID> ddicttestuser1 localhost information_schema Query <TIME> Locked SELECT COUNT(*) FROM test.t1
-<ID> root localhost information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST
-SHOW FULL PROCESSLIST;
-Id User Host db Command Time State Info
-<ID> root localhost information_schema Query <TIME> NULL SHOW FULL PROCESSLIST
-<ID> ddicttestuser1 localhost information_schema Query <TIME> Locked SELECT COUNT(*) FROM test.t1
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema Query <TIME> Table lock SELECT COUNT(*) FROM test.t1 <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema Sleep <TIME> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema Execute <TIME> executing SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
UNLOCK TABLES;
+# ----- switch to connection con2 (user = test_user) -----
------ switch to connection ddicttestuser1 (user = ddicttestuser1) -----
# Pull("reap") the result set from the statement executed with "send".
+
COUNT(*)
0
+# Ensure that SHOW/SELECT processlist can handle extreme long commands
+#----------------------------------------------------------------------------
+
+# ----- switch to connection default (user = root) -----
+
+LOCK TABLE test.t1 WRITE;
+# ----- switch to connection con2 (user = test_user) -----
------ switch to connection default (user = root) -----
+# Send a long (~20 KB code) statement to the server, but do not wait
+# till the result comes back. We will pull this later.
------ close connection ddicttestuser1 -----
-DROP USER ddicttestuser1@'localhost';
+SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1;
+# ----- switch to connection default (user = root) -----
+
+# Poll till INFO is no more NULL and State = "Table Lock".
+
+# Expect result:
+# Statement Content of INFO
+# SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST Complete statement
+# SHOW FULL PROCESSLIST Complete statement
+# SHOW PROCESSLIST statement truncated after 100 char
+
+SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;
+ID USER HOST DB COMMAND TIME STATE INFO TIME_MS STAGE MAX_STAGE PROGRESS
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 <TIME_MS> 0 0 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL <TIME_MS> 0 0 0.000
+<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST <TIME_MS> 0 0 0.000
+SHOW FULL PROCESSLIST;
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW FULL PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END' AS "Long string" FROM test.t1 0.000
+SHOW PROCESSLIST;
+Id User Host db Command Time State Info Progress
+<ID> root <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SHOW PROCESSLIST 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> NULL 0.000
+<ID> test_user <HOST_NAME> information_schema <COMMAND> <TIME> <STATE> SELECT count(*),'BEGIN-This is the representative of a very long statement.This is the representativ 0.000
+UNLOCK TABLES;
+# ----- switch to connection con2 (user = test_user) -----
+
+# Pull("reap") the result set from the monster statement executed with "send".
+
+count(*) Long string
+0 BEGIN-This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.This is the representative of a very long statement.-END
+# ----- switch to connection default (user = root) -----
+
+----- disconnect con1 and con2 -----
+
+DROP USER test_user@'localhost';
DROP TABLE test.t1;
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index 22e3462bc98..345da7a0163 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -1219,7 +1219,7 @@ count(*)
623
explain select * from t1 where c between 1 and 2500;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range c c 5 NULL # Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range c c 5 NULL # Using where
update t1 set c=a;
explain select * from t1 where c between 1 and 2500;
id select_type table type possible_keys key key_len ref rows Extra
@@ -1914,7 +1914,7 @@ qq
*a *a*a *
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v,v_2 # 13 const # Using index condition
+1 SIMPLE t1 ref v,v_2 # 13 const # Using where
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
@@ -2090,7 +2090,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v v 303 const # Using index condition
+1 SIMPLE t1 ref v v 303 const # Using where
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
diff --git a/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result b/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result
index 051266c526e..bd8760b8f79 100644
--- a/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result
+++ b/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result
@@ -104,7 +104,7 @@ id 1
select_type PRIMARY
table <derived2>
type ALL
-possible_keys key0
+possible_keys NULL
key NULL
key_len NULL
ref NULL
@@ -308,7 +308,7 @@ id 1
select_type PRIMARY
table <derived2>
type ALL
-possible_keys key0
+possible_keys NULL
key NULL
key_len NULL
ref NULL
diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result
index 9acc1f424d4..1bd572d7231 100644
--- a/mysql-test/suite/innodb/r/innodb_mysql.result
+++ b/mysql-test/suite/innodb/r/innodb_mysql.result
@@ -2624,46 +2624,6 @@ create table t1 (a int primary key, b int) engine = innodb;
insert into t1 values (1,1),(2,1);
alter ignore table t1 add unique `main` (b);
drop table t1;
-#
-# Bug#56862 Execution of a query that uses index merge returns a wrong result
-#
-CREATE TABLE t1 (
-pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
-a int,
-b int,
-INDEX idx(a))
-ENGINE=INNODB;
-INSERT INTO t1(a,b) VALUES
-(11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500),
-(3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800),
-(6, 600), (18, 1800), (9, 900), (10, 1000), (7, 700),
-(13, 1300), (15, 1500), (19, 1900), (16, 1600), (20, 2000);
-INSERT INTO t1(a,b) SELECT a+20, b+2000 FROM t1;
-INSERT INTO t1(a,b) SELECT a+40, b+4000 FROM t1;
-INSERT INTO t1(a,b) SELECT a+80, b+8000 FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1 VALUES (1000000, 0, 0);
-SET SESSION sort_buffer_size = 1024*36;
-EXPLAIN
-SELECT COUNT(*) FROM
-(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
-WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 3537 Using sort_union(idx,PRIMARY); Using where
-SELECT COUNT(*) FROM
-(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
-WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
-COUNT(*)
-1537
-SET SESSION sort_buffer_size = DEFAULT;
-DROP TABLE t1;
End of 5.1 tests
#
# Test for bug #39932 "create table fails if column for FK is in different
diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test
index 850e6b1a0c3..c17b9465aa6 100644
--- a/mysql-test/suite/innodb/t/innodb_mysql.test
+++ b/mysql-test/suite/innodb/t/innodb_mysql.test
@@ -849,50 +849,6 @@ insert into t1 values (1,1),(2,1);
alter ignore table t1 add unique `main` (b);
drop table t1;
---echo #
---echo # Bug#56862 Execution of a query that uses index merge returns a wrong result
---echo #
-
-CREATE TABLE t1 (
- pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
- a int,
- b int,
- INDEX idx(a))
-ENGINE=INNODB;
-
-INSERT INTO t1(a,b) VALUES
- (11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500),
- (3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800),
- (6, 600), (18, 1800), (9, 900), (10, 1000), (7, 700),
- (13, 1300), (15, 1500), (19, 1900), (16, 1600), (20, 2000);
-INSERT INTO t1(a,b) SELECT a+20, b+2000 FROM t1;
-INSERT INTO t1(a,b) SELECT a+40, b+4000 FROM t1;
-INSERT INTO t1(a,b) SELECT a+80, b+8000 FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1 VALUES (1000000, 0, 0);
-
-SET SESSION sort_buffer_size = 1024*36;
-
-EXPLAIN
-SELECT COUNT(*) FROM
- (SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
- WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
-
-SELECT COUNT(*) FROM
- (SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
- WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
-
-SET SESSION sort_buffer_size = DEFAULT;
-
-DROP TABLE t1;
-
--echo End of 5.1 tests
--echo #
diff --git a/mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result b/mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result
index 051266c526e..bd8760b8f79 100644
--- a/mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result
+++ b/mysql-test/suite/innodb_plugin/r/innodb_lock_wait_timeout_1.result
@@ -104,7 +104,7 @@ id 1
select_type PRIMARY
table <derived2>
type ALL
-possible_keys key0
+possible_keys NULL
key NULL
key_len NULL
ref NULL
@@ -308,7 +308,7 @@ id 1
select_type PRIMARY
table <derived2>
type ALL
-possible_keys key0
+possible_keys NULL
key NULL
key_len NULL
ref NULL
diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result
index df23048f834..e9d636baf2e 100644
--- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result
+++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result
@@ -2411,41 +2411,4 @@ PACK_KEYS=0;
CREATE INDEX a ON t1 (a);
CREATE INDEX c on t1 (c);
DROP TABLE t1;
-CREATE TABLE t1 (
-pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
-a int,
-b int,
-INDEX idx(a))
-ENGINE=INNODB;
-INSERT INTO t1(a,b) VALUES
-(11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500),
-(3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800),
-(6, 600), (18, 1800), (9, 900), (10, 1000), (7, 700),
-(13, 1300), (15, 1500), (19, 1900), (16, 1600), (20, 2000);
-INSERT INTO t1(a,b) SELECT a+20, b+2000 FROM t1;
-INSERT INTO t1(a,b) SELECT a+40, b+4000 FROM t1;
-INSERT INTO t1(a,b) SELECT a+80, b+8000 FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1 VALUES (1000000, 0, 0);
-SET SESSION sort_buffer_size = 1024*36;
-EXPLAIN
-SELECT COUNT(*) FROM
-(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
-WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 3537 Using sort_union(idx,PRIMARY); Using where
-SELECT COUNT(*) FROM
-(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
-WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
-COUNT(*)
-1537
-SET SESSION sort_buffer_size = DEFAULT;
-DROP TABLE t1;
End of 5.1 tests
diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug52663.test b/mysql-test/suite/innodb_plugin/t/innodb_bug52663.test
index 927044fb2ca..b4f93f43394 100644
--- a/mysql-test/suite/innodb_plugin/t/innodb_bug52663.test
+++ b/mysql-test/suite/innodb_plugin/t/innodb_bug52663.test
@@ -1,5 +1,7 @@
--source include/have_innodb_plugin.inc
+--source include/long_test.inc
+
set session transaction isolation level read committed;
create table innodb_bug52663 (what varchar(5), id integer, count integer, primary key
diff --git a/mysql-test/suite/innodb_plugin/t/innodb_mysql.test b/mysql-test/suite/innodb_plugin/t/innodb_mysql.test
index 279802fcdb4..32bbdfa10b4 100644
--- a/mysql-test/suite/innodb_plugin/t/innodb_mysql.test
+++ b/mysql-test/suite/innodb_plugin/t/innodb_mysql.test
@@ -647,48 +647,4 @@ CREATE INDEX c on t1 (c);
DROP TABLE t1;
-#
-# Bug#56862 Execution of a query that uses index merge returns a wrong result
-#
-
-CREATE TABLE t1 (
- pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
- a int,
- b int,
- INDEX idx(a))
-ENGINE=INNODB;
-
-INSERT INTO t1(a,b) VALUES
- (11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500),
- (3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800),
- (6, 600), (18, 1800), (9, 900), (10, 1000), (7, 700),
- (13, 1300), (15, 1500), (19, 1900), (16, 1600), (20, 2000);
-INSERT INTO t1(a,b) SELECT a+20, b+2000 FROM t1;
-INSERT INTO t1(a,b) SELECT a+40, b+4000 FROM t1;
-INSERT INTO t1(a,b) SELECT a+80, b+8000 FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1(a,b) SELECT a,b FROM t1;
-INSERT INTO t1 VALUES (1000000, 0, 0);
-
-SET SESSION sort_buffer_size = 1024*36;
-
-EXPLAIN
-SELECT COUNT(*) FROM
- (SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
- WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
-
-SELECT COUNT(*) FROM
- (SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
- WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
-
-SET SESSION sort_buffer_size = DEFAULT;
-
-DROP TABLE t1;
-
--echo End of 5.1 tests
diff --git a/mysql-test/suite/maria/r/locking.result b/mysql-test/suite/maria/r/locking.result
new file mode 100644
index 00000000000..772e43f5983
--- /dev/null
+++ b/mysql-test/suite/maria/r/locking.result
@@ -0,0 +1,31 @@
+drop table if exists t1;
+CREATE TABLE t1 (
+`Vorgangsnr` int(10) unsigned NOT NULL AUTO_INCREMENT,
+`Datum_Eingang` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Erfassungs-/Buchungsdatum',
+`Warennummer` varchar(20) DEFAULT NULL,
+`BenutzerID` int(10) unsigned DEFAULT NULL,
+`Vermerke_Versand` varchar(1024) DEFAULT NULL,
+`Zubehör` varchar(250) DEFAULT NULL,
+`Datum_Annahme` varchar(12) DEFAULT NULL,
+`K_Lieferscheinnummer` int(10) unsigned DEFAULT NULL,
+`RMANr` int(10) unsigned DEFAULT '0',
+`K_Bestelldaten` varchar(1024) DEFAULT NULL COMMENT 'Bestellnr, Datum, Auftraggeber',
+PRIMARY KEY (`Vorgangsnr`),
+KEY `Datum_Eingang` (`Datum_Eingang`)
+) ENGINE=Aria AUTO_INCREMENT=250 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+alter table t1 disable keys;
+lock tables t1 write;
+INSERT INTO t1 (Datum_Eingang, BenutzerID, Zubehör, Datum_Annahme) VALUES ('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006');
+INSERT INTO t1 (Datum_Eingang, BenutzerID, Zubehör, Datum_Annahme) VALUES ('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006');
+unlock tables;
+select count(*) from t1;
+count(*)
+88
+check table t1 extended;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+alter table t1 enable keys;
+check table t1 extended;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
diff --git a/mysql-test/suite/maria/r/maria-recovery3.result b/mysql-test/suite/maria/r/maria-recovery3.result
index 4ce52425204..cab3fd55091 100644
--- a/mysql-test/suite/maria/r/maria-recovery3.result
+++ b/mysql-test/suite/maria/r/maria-recovery3.result
@@ -78,7 +78,7 @@ ERROR HY000: Lost connection to MySQL server during query
* recovery happens
check table t1 extended;
Table Op Msg_type Msg_text
-mysqltest.t1 check warning Size of indexfile is: 372 Should be: 8192
+mysqltest.t1 check warning Size of indexfile is: 372 Expected: 8192
mysqltest.t1 check status OK
* testing that checksum after recovery is as expected
Checksum-check
diff --git a/mysql-test/suite/maria/r/maria.result b/mysql-test/suite/maria/r/maria.result
index e0f1175d845..4ff0b57a230 100644
--- a/mysql-test/suite/maria/r/maria.result
+++ b/mysql-test/suite/maria/r/maria.result
@@ -22,6 +22,17 @@ CHECK TABLE t1;
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
+create table t1 (a int primary key auto_increment) engine=aria;
+insert into t1 values (1);
+update t1 set a=0 where a=1;
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check warning Found row where the auto_increment column has the value 0
+test.t1 check status OK
+select * from t1;
+a
+0
+drop table t1;
create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a));
check table t1;
Table Op Msg_type Msg_text
@@ -350,7 +361,8 @@ ALTER TABLE t1 ADD INDEX t1 (a, b, c, d, e);
ERROR 42000: Specified key was too long; max key length is 1208 bytes
DROP TABLE t1;
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
-INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+INSERT into t1 values (0,null,0), (0,null,1), (0,null,2), (0,null,3), (1,1,4);
+INSERT into t1 values (2,4,5), (7,8,4), (8,3,1), (9,7,2), (5,5,9);
create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
INSERT into t2 values (1,1,1), (2,2,2);
optimize table t1;
@@ -361,24 +373,24 @@ Table Op Msg_type Msg_text
test.t1 check status OK
show index from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
-t1 1 b 1 b A 5 NULL NULL YES BTREE
-t1 1 c 1 c A 5 NULL NULL YES BTREE
-t1 1 a 1 a A 1 NULL NULL BTREE
-t1 1 a 2 b A 5 NULL NULL YES BTREE
-t1 1 c_2 1 c A 5 NULL NULL YES BTREE
-t1 1 c_2 2 a A 5 NULL NULL BTREE
+t1 1 b 1 b A 10 NULL NULL YES BTREE
+t1 1 c 1 c A 10 NULL NULL YES BTREE
+t1 1 a 1 a A 10 NULL NULL BTREE
+t1 1 a 2 b A 10 NULL NULL YES BTREE
+t1 1 c_2 1 c A 10 NULL NULL YES BTREE
+t1 1 c_2 2 a A 10 NULL NULL BTREE
explain select * from t1,t2 where t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL a NULL NULL NULL 2
-1 SIMPLE t1 ref a a 4 test.t2.a 3
+1 SIMPLE t1 ref a a 4 test.t2.a 1
explain select * from t1,t2 force index(a) where t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL a NULL NULL NULL 2
-1 SIMPLE t1 ref a a 4 test.t2.a 3
+1 SIMPLE t1 ref a a 4 test.t2.a 1
explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL a NULL NULL NULL 2
-1 SIMPLE t1 ref a a 4 test.t2.a 3
+1 SIMPLE t1 ref a a 4 test.t2.a 1
explain select * from t1,t2 where t1.b=t2.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL b NULL NULL NULL 2 Using where
@@ -386,19 +398,19 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select * from t1,t2 force index(c) where t1.a=t2.a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ALL NULL NULL NULL NULL 2
-1 SIMPLE t1 ref a a 4 test.t2.a 3
+1 SIMPLE t1 ref a a 4 test.t2.a 1
explain select * from t1 where a=0 or a=2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 4 NULL 4 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range a a 4 NULL 5 Using where
explain select * from t1 force index (a) where a=0 or a=2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 4 NULL 4 Using index condition; Rowid-ordered scan
+1 SIMPLE t1 range a a 4 NULL 5 Using where
explain select * from t1 where c=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref c,c_2 c 5 const 1
+1 SIMPLE t1 ref c,c_2 c 5 const 2
explain select * from t1 use index() where c=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where
+1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where
drop table t1,t2;
create table t1 (a int not null auto_increment primary key, b varchar(255));
insert into t1 (b) values (repeat('a',100)),(repeat('b',100)),(repeat('c',100));
@@ -1131,7 +1143,7 @@ qq
*a *a*a *
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v,v_2 # 13 const # Using index condition
+1 SIMPLE t1 ref v,v_2 # 13 const # Using where
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
@@ -1307,7 +1319,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref v v 303 const # Using where; Using index
explain select * from t1 where v='a';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref v v 303 const # Using index condition
+1 SIMPLE t1 ref v v 303 const # Using where
select v,count(*) from t1 group by v limit 10;
v count(*)
a 1
@@ -2131,7 +2143,7 @@ c3 VARCHAR(10) NOT NULL,
KEY (c1),
KEY (c2)
) ENGINE=aria DEFAULT CHARSET=utf8 PACK_KEYS=0;
-Aria file: MYSQLD_DATADIR/test/t1
+Aria file: MYSQLD_DATADIR/test/t1
Record format: Block
Crashsafe: yes
Character set: utf8_general_ci (33)
diff --git a/mysql-test/suite/maria/r/maria3.result b/mysql-test/suite/maria/r/maria3.result
index 056147c69c0..47c02999087 100644
--- a/mysql-test/suite/maria/r/maria3.result
+++ b/mysql-test/suite/maria/r/maria3.result
@@ -305,6 +305,7 @@ select lower(variable_name) as Variable_name, Variable_value as Value from infor
Variable_name Value
aria_block_size 8192
aria_checkpoint_interval 30
+aria_checkpoint_log_activity 1048576
aria_force_start_after_recovery_failures 0
aria_group_commit none
aria_group_commit_interval 0
diff --git a/mysql-test/suite/maria/r/max_length.result b/mysql-test/suite/maria/r/max_length.result
new file mode 100644
index 00000000000..6db58622698
--- /dev/null
+++ b/mysql-test/suite/maria/r/max_length.result
@@ -0,0 +1,56 @@
+drop table if exists t1,t2;
+Warnings:
+Note 1051 Unknown table 't1'
+Note 1051 Unknown table 't2'
+create table t1 (id int(10) unsigned not null auto_increment primary key, v varchar(1000), b blob) row_format=page max_rows=2 engine=aria;
+create table t2 (id int(10) unsigned not null auto_increment primary key, v varchar(1000), b blob) row_format=page max_rows=20000000 engine=aria;
+lock tables t1 write,t2 write;
+show table status like "t_";
+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 Aria 10 Page 0 0 8192 268320768 8192 0 1 # # # latin1_swedish_ci NULL max_rows=2 row_format=PAGE
+t2 Aria 10 Page 0 0 8192 17592186011648 8192 0 1 # # # latin1_swedish_ci NULL max_rows=20000000 row_format=PAGE
+insert into t1 values(null, repeat("ab",100),repeat("def",1000));
+insert into t1 values(null, repeat("de",200),repeat("ghi",2000));
+insert into t1 values(null, repeat("fe",300),repeat("ghi",3000));
+insert into t1 values(null, repeat("gh",400),repeat("jkl",10000));
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+unlock tables;
+insert into t1 (v,b) select v,b from t2;
+ERROR HY000: The table 't1' is full
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check warning Datafile is almost full, 268230656 of 268320768 used
+test.t1 check status OK
+insert into t1 values(null, repeat("gh",400),repeat("jkl",10000));
+ERROR HY000: The table 't1' is full
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check warning Datafile is almost full, 268230656 of 268320768 used
+test.t1 check status OK
+truncate table t1;
+insert into t1 (v,b) select v,b from t2;
+ERROR HY000: The table 't1' is full
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check warning Datafile is almost full, 268230656 of 268320768 used
+test.t1 check status OK
+drop table t1,t2;
diff --git a/mysql-test/suite/maria/r/small_blocksize.result b/mysql-test/suite/maria/r/small_blocksize.result
new file mode 100644
index 00000000000..f418a1f92ef
--- /dev/null
+++ b/mysql-test/suite/maria/r/small_blocksize.result
@@ -0,0 +1,33 @@
+DROP TABLE if exists t1;
+Warnings:
+Note 1051 Unknown table 't1'
+CREATE TABLE t1 (col_longtext_ucs2 longtext, col_longtext_utf8 longtext, col_varchar_255_ucs2_key varchar(255), col_set_utf8 set ('a','b'), col_char_255_ucs2 char(255), col_char_255_ucs2_key char(255), col_enum_ucs2 enum ('a','b'), col_varchar_255_ucs2 varchar(255), col_longtext_ucs2_key longtext, col_longtext_utf8_key longtext, col_enum_utf8 enum ('a','b'), col_varchar_255_utf8_key varchar(1024), col_varchar_255_utf8 varchar(255), col_enum_ucs2_key enum ('a','b'), col_enum_utf8_key enum ('a','b'), col_set_utf8_key set ('a','b'), col_char_255_utf8 char(255), pk integer auto_increment, col_set_ucs2_key set ('a','b'), col_char_255_utf8_key char(255), col_set_ucs2 set ('a','b'), primary key (pk)) ENGINE=aria;
+INSERT INTO t1 ( col_char_255_utf8, col_varchar_255_utf8_key, col_longtext_utf8_key ) VALUES ( 'lggnqojgqectqlkvskffihliqcwoakzzzjvhkqlwjybkngdbubskflpmzegdrk', REPEAT( 'a', 627 ), 'mlggnqojgqectqlkvskffihliqcwoakzzzjvhkqlwjybkngdbubskflpmzegdrklnipcmzbtwdqfnyinqfohgtiwmvfpbuslgobjhslxnaybcyebhsrlipnuvalhmvhlwbwujtvjsdrbyapfzprnxfgtrukwhywtkaoupsaogxsjxhqjkidvnpeytjgndtnrrbm' );
+UPDATE t1 SET col_varchar_255_utf8 = REPEAT('a', 197 );
+UPDATE t1 SET col_char_255_utf8 = 'bmjihzjtxegprqfvmczyzbavjuozkyxrlxvqyzcfvsjrhcccqnecyohzhzbgsbqkqvzmtlhtlcgzheirkyfwczoolilkrfimfnuoapyylbghdhdgfebjjajfoigagozypqtrflrvdiwfgqalsqbmlllsanvtuuutiaastqtbzeoaawl';
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
+create table t1 (a int primary key auto_increment, e1 enum('a','b'), e2 enum('a','b'), vl int, bl int, c char(10), v1 varchar(10000), v2 varchar(10000), b1 blob, b2 blob) engine=aria;
+insert into t1 (vl,bl) values (10,10),(100,100),(1000,1000),(5000,5000),(8000,12000);
+update t1 set c="test", v1=repeat('a',vl),v2=repeat('b',vl/2),b1=repeat('c',bl),b2=repeat('d',bl);
+insert into t1 (vl,bl) values (10,10),(100,100),(1000,1000),(1000,5000);
+update t1 set c="test", v1=repeat('a',vl/4),v2=repeat('b',vl/5),b1=repeat('c',bl*2),b2=repeat('d',bl/2);
+insert into t1 (vl,bl) values (100,100);
+update t1 set c="test", v1=repeat('a',vl),v2=repeat('b',vl),b1=repeat('c',bl*2),b2=repeat('d',bl/2);
+update t1 set c="test", v1=repeat('a',vl/2),v2=repeat('b',vl/2),b1=repeat('c',bl/2),b2=repeat('d',bl/2);
+update t1 set c="test", v1=repeat('a',vl/4),v2=repeat('b',vl/4),b1=repeat('c',bl/4),b2=repeat('d',bl/4);
+update t1 set c="test", v1=repeat('a',vl/20),v2=repeat('b',vl),b1=repeat('c',bl/20),b2=repeat('d',bl/20);
+insert into t1 (vl,bl) values (100,100);
+update t1 set c="test", v1=repeat('a',vl/100),b1=repeat('c',bl/100);
+insert into t1 (vl,bl) values (100,100);
+update t1 set c="test", v1=repeat('a',vl),b1=repeat('c',bl);
+insert into t1 (vl,bl) values (100,100);
+update t1 set c="test", v1=repeat('a',10),v2=repeat('b',10);
+insert into t1 (vl,bl) values (100,100);
+update t1 set c="test", v1=repeat('a',2000),v2=repeat('b',2000);
+check table t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+drop table t1;
diff --git a/mysql-test/suite/maria/t/locking.test b/mysql-test/suite/maria/t/locking.test
new file mode 100644
index 00000000000..c20ca33e162
--- /dev/null
+++ b/mysql-test/suite/maria/t/locking.test
@@ -0,0 +1,43 @@
+#
+# Aria bugs that has to do with locking
+#
+--source include/have_maria.inc
+
+disable_warnings;
+drop table if exists t1;
+enable_warnings;
+
+#
+# Test generating data with insert select
+#
+
+CREATE TABLE t1 (
+ `Vorgangsnr` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `Datum_Eingang` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Erfassungs-/Buchungsdatum',
+ `Warennummer` varchar(20) DEFAULT NULL,
+ `BenutzerID` int(10) unsigned DEFAULT NULL,
+ `Vermerke_Versand` varchar(1024) DEFAULT NULL,
+ `Zubehör` varchar(250) DEFAULT NULL,
+ `Datum_Annahme` varchar(12) DEFAULT NULL,
+ `K_Lieferscheinnummer` int(10) unsigned DEFAULT NULL,
+ `RMANr` int(10) unsigned DEFAULT '0',
+ `K_Bestelldaten` varchar(1024) DEFAULT NULL COMMENT 'Bestellnr, Datum, Auftraggeber',
+ PRIMARY KEY (`Vorgangsnr`),
+ KEY `Datum_Eingang` (`Datum_Eingang`)
+) ENGINE=Aria AUTO_INCREMENT=250 DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC;
+
+alter table t1 disable keys;
+lock tables t1 write;
+
+let $loop=2;
+while ($loop)
+{
+ INSERT INTO t1 (Datum_Eingang, BenutzerID, Zubehör, Datum_Annahme) VALUES ('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006'),('2006-06-21 00:00:00', 713, 'ohne Zubehör', '21.06.2006');
+ dec $loop;
+}
+unlock tables;
+select count(*) from t1;
+check table t1 extended;
+alter table t1 enable keys;
+check table t1 extended;
+drop table t1;
diff --git a/mysql-test/suite/maria/t/maria.test b/mysql-test/suite/maria/t/maria.test
index e23821b8be9..ebeedbb23cc 100644
--- a/mysql-test/suite/maria/t/maria.test
+++ b/mysql-test/suite/maria/t/maria.test
@@ -42,6 +42,16 @@ CHECK TABLE t1;
drop table t1;
#
+# Test auto_increment warning
+#
+create table t1 (a int primary key auto_increment) engine=aria;
+insert into t1 values (1);
+update t1 set a=0 where a=1;
+check table t1;
+select * from t1;
+drop table t1;
+
+#
# Test problem with rows that are 65517-65520 bytes long
#
@@ -376,7 +386,8 @@ DROP TABLE t1;
#
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
-INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+INSERT into t1 values (0,null,0), (0,null,1), (0,null,2), (0,null,3), (1,1,4);
+INSERT into t1 values (2,4,5), (7,8,4), (8,3,1), (9,7,2), (5,5,9);
create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
INSERT into t2 values (1,1,1), (2,2,2);
optimize table t1;
diff --git a/mysql-test/suite/maria/t/max_length.test b/mysql-test/suite/maria/t/max_length.test
new file mode 100644
index 00000000000..68ad1e22aa9
--- /dev/null
+++ b/mysql-test/suite/maria/t/max_length.test
@@ -0,0 +1,52 @@
+# Test max data length
+# This test will use around 1.3G of disk space!
+
+--source include/have_maria.inc
+--source include/big_test.inc
+
+drop table if exists t1,t2;
+
+create table t1 (id int(10) unsigned not null auto_increment primary key, v varchar(1000), b blob) row_format=page max_rows=2 engine=aria;
+create table t2 (id int(10) unsigned not null auto_increment primary key, v varchar(1000), b blob) row_format=page max_rows=20000000 engine=aria;
+lock tables t1 write,t2 write;
+--replace_column 12 # 13 # 14 #
+show table status like "t_";
+insert into t1 values(null, repeat("ab",100),repeat("def",1000));
+insert into t1 values(null, repeat("de",200),repeat("ghi",2000));
+insert into t1 values(null, repeat("fe",300),repeat("ghi",3000));
+insert into t1 values(null, repeat("gh",400),repeat("jkl",10000));
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+insert into t1 (v,b) select v,b from t2;
+insert into t2 (v,b) select v,b from t1;
+unlock tables;
+
+--error ER_RECORD_FILE_FULL
+insert into t1 (v,b) select v,b from t2;
+check table t1;
+--error ER_RECORD_FILE_FULL
+insert into t1 values(null, repeat("gh",400),repeat("jkl",10000));
+check table t1;
+# Test also with inserting into empty table (different code)
+truncate table t1;
+--error ER_RECORD_FILE_FULL
+insert into t1 (v,b) select v,b from t2;
+check table t1;
+
+drop table t1,t2;
diff --git a/mysql-test/suite/maria/t/small_blocksize-master.opt b/mysql-test/suite/maria/t/small_blocksize-master.opt
new file mode 100644
index 00000000000..59fd35a7846
--- /dev/null
+++ b/mysql-test/suite/maria/t/small_blocksize-master.opt
@@ -0,0 +1 @@
+--aria-block-size=1024
diff --git a/mysql-test/suite/maria/t/small_blocksize.test b/mysql-test/suite/maria/t/small_blocksize.test
new file mode 100644
index 00000000000..0acf8df6e66
--- /dev/null
+++ b/mysql-test/suite/maria/t/small_blocksize.test
@@ -0,0 +1,34 @@
+DROP TABLE if exists t1;
+
+#
+# Test of extending updated rows.
+# This caused failures in lp:815022
+#
+CREATE TABLE t1 (col_longtext_ucs2 longtext, col_longtext_utf8 longtext, col_varchar_255_ucs2_key varchar(255), col_set_utf8 set ('a','b'), col_char_255_ucs2 char(255), col_char_255_ucs2_key char(255), col_enum_ucs2 enum ('a','b'), col_varchar_255_ucs2 varchar(255), col_longtext_ucs2_key longtext, col_longtext_utf8_key longtext, col_enum_utf8 enum ('a','b'), col_varchar_255_utf8_key varchar(1024), col_varchar_255_utf8 varchar(255), col_enum_ucs2_key enum ('a','b'), col_enum_utf8_key enum ('a','b'), col_set_utf8_key set ('a','b'), col_char_255_utf8 char(255), pk integer auto_increment, col_set_ucs2_key set ('a','b'), col_char_255_utf8_key char(255), col_set_ucs2 set ('a','b'), primary key (pk)) ENGINE=aria;
+INSERT INTO t1 ( col_char_255_utf8, col_varchar_255_utf8_key, col_longtext_utf8_key ) VALUES ( 'lggnqojgqectqlkvskffihliqcwoakzzzjvhkqlwjybkngdbubskflpmzegdrk', REPEAT( 'a', 627 ), 'mlggnqojgqectqlkvskffihliqcwoakzzzjvhkqlwjybkngdbubskflpmzegdrklnipcmzbtwdqfnyinqfohgtiwmvfpbuslgobjhslxnaybcyebhsrlipnuvalhmvhlwbwujtvjsdrbyapfzprnxfgtrukwhywtkaoupsaogxsjxhqjkidvnpeytjgndtnrrbm' );
+UPDATE t1 SET col_varchar_255_utf8 = REPEAT('a', 197 );
+UPDATE t1 SET col_char_255_utf8 = 'bmjihzjtxegprqfvmczyzbavjuozkyxrlxvqyzcfvsjrhcccqnecyohzhzbgsbqkqvzmtlhtlcgzheirkyfwczoolilkrfimfnuoapyylbghdhdgfebjjajfoigagozypqtrflrvdiwfgqalsqbmlllsanvtuuutiaastqtbzeoaawl';
+check table t1;
+drop table t1;
+
+create table t1 (a int primary key auto_increment, e1 enum('a','b'), e2 enum('a','b'), vl int, bl int, c char(10), v1 varchar(10000), v2 varchar(10000), b1 blob, b2 blob) engine=aria;
+
+insert into t1 (vl,bl) values (10,10),(100,100),(1000,1000),(5000,5000),(8000,12000);
+update t1 set c="test", v1=repeat('a',vl),v2=repeat('b',vl/2),b1=repeat('c',bl),b2=repeat('d',bl);
+insert into t1 (vl,bl) values (10,10),(100,100),(1000,1000),(1000,5000);
+update t1 set c="test", v1=repeat('a',vl/4),v2=repeat('b',vl/5),b1=repeat('c',bl*2),b2=repeat('d',bl/2);
+insert into t1 (vl,bl) values (100,100);
+update t1 set c="test", v1=repeat('a',vl),v2=repeat('b',vl),b1=repeat('c',bl*2),b2=repeat('d',bl/2);
+update t1 set c="test", v1=repeat('a',vl/2),v2=repeat('b',vl/2),b1=repeat('c',bl/2),b2=repeat('d',bl/2);
+update t1 set c="test", v1=repeat('a',vl/4),v2=repeat('b',vl/4),b1=repeat('c',bl/4),b2=repeat('d',bl/4);
+update t1 set c="test", v1=repeat('a',vl/20),v2=repeat('b',vl),b1=repeat('c',bl/20),b2=repeat('d',bl/20);
+insert into t1 (vl,bl) values (100,100);
+update t1 set c="test", v1=repeat('a',vl/100),b1=repeat('c',bl/100);
+insert into t1 (vl,bl) values (100,100);
+update t1 set c="test", v1=repeat('a',vl),b1=repeat('c',bl);
+insert into t1 (vl,bl) values (100,100);
+update t1 set c="test", v1=repeat('a',10),v2=repeat('b',10);
+insert into t1 (vl,bl) values (100,100);
+update t1 set c="test", v1=repeat('a',2000),v2=repeat('b',2000);
+check table t1;
+drop table t1;
diff --git a/mysql-test/suite/parts/r/partition_repair_myisam.result b/mysql-test/suite/parts/r/partition_repair_myisam.result
index a34627a91cb..f9dd05c2996 100644
--- a/mysql-test/suite/parts/r/partition_repair_myisam.result
+++ b/mysql-test/suite/parts/r/partition_repair_myisam.result
@@ -264,6 +264,7 @@ Table Op Msg_type Msg_text
test.t1_will_crash analyze status OK
OPTIMIZE TABLE t1_will_crash;
Table Op Msg_type Msg_text
+test.t1_will_crash optimize info Found row block followed by deleted block
test.t1_will_crash optimize warning Number of rows changed from 8 to 7
test.t1_will_crash optimize status OK
CHECK TABLE t1_will_crash;
diff --git a/mysql-test/suite/pbxt/r/derived.result b/mysql-test/suite/pbxt/r/derived.result
index b4c1762e81a..75d5fcf8b16 100644
--- a/mysql-test/suite/pbxt/r/derived.result
+++ b/mysql-test/suite/pbxt/r/derived.result
@@ -57,8 +57,9 @@ a b a b
3 c 3 c
explain select * from t1 as x1, (select * from t1) as x2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE x1 ALL NULL NULL NULL NULL 4
-1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
+1 PRIMARY x1 ALL NULL NULL NULL NULL 4
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 4
drop table if exists t2,t3;
select * from (select 1) as a;
1
@@ -112,8 +113,9 @@ a b
3 c
explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 1
-1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+2 DERIVED t2 ALL NULL NULL NULL NULL 1
+2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
drop table t1, t2;
create table t1(a int not null, t char(8), index(a));
SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20;
@@ -140,8 +142,9 @@ a t
20 20
explain select count(*) from t1 as tt1, (select * from t1) as tt2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE tt1 index NULL a 4 NULL 10000 Using index
-1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using join buffer (flat, BNL join)
+1 PRIMARY tt1 index NULL a 4 NULL 10000 Using index
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 10000 Using join buffer (flat, BNL join)
+2 DERIVED t1 ALL NULL NULL NULL NULL 10000
drop table t1;
SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b;
(SELECT * FROM (SELECT 1 as a) as a )
@@ -170,30 +173,30 @@ insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd'
insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
pla_id mat_id
-102 1
-101 1
100 1
-104 2
+101 1
+102 1
103 2
+104 2
105 3
SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
pla_id test
-102 1
-101 1
100 1
-104 2
+101 1
+102 1
103 2
+104 2
105 3
explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
-1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
+1 PRIMARY <derived2> ALL NULL $hj 7 test.m2.matintnum 9 Using where
2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
-1 PRIMARY <derived2> ref key0 key0 7 test.m2.matintnum 2
+1 PRIMARY <derived2> ALL NULL $hj 7 test.m2.matintnum 9 Using where
2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
2 DERIVED m1 eq_ref PRIMARY PRIMARY 3 test.mp.mat_id 1
drop table t1,t2;
@@ -231,8 +234,9 @@ count(*)
2
explain select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE A ALL NULL NULL NULL NULL 2 Using where
-1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.A.E2 1 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 THEMAX.E2 1 Using where
+2 DERIVED A ALL NULL NULL NULL NULL 2 Using where
3 DEPENDENT SUBQUERY B ALL NULL NULL NULL NULL 2 Using where
drop table t1;
create table t1 (a int);
@@ -322,7 +326,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
explain select a from (select a from t2 where a>1) tt;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
+2 DERIVED t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
drop table t2;
CREATE TABLE `t1` ( `itemid` int(11) NOT NULL default '0', `grpid` varchar(15) NOT NULL default '', `vendor` int(11) NOT NULL default '0', `date_` date NOT NULL default '0000-00-00', `price` decimal(12,2) NOT NULL default '0.00', PRIMARY KEY (`itemid`,`grpid`,`vendor`,`date_`), KEY `itemid` (`itemid`,`vendor`), KEY `itemid_2` (`itemid`,`date_`));
insert into t1 values (128, 'rozn', 2, now(), 10),(128, 'rozn', 1, now(), 10);
diff --git a/mysql-test/suite/pbxt/r/func_group.result b/mysql-test/suite/pbxt/r/func_group.result
index dc6ea214084..c3474e2f3ad 100644
--- a/mysql-test/suite/pbxt/r/func_group.result
+++ b/mysql-test/suite/pbxt/r/func_group.result
@@ -601,7 +601,7 @@ AME AME
explain
select min(a1) from t1 where a1 > 'KKK' or a1 < 'XXX';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index PRIMARY PRIMARY 3 NULL 15 Using where; Using index
+1 SIMPLE t1 range PRIMARY PRIMARY 0 NULL 1 Using where; Using index
explain
select min(a1) from t1 where a1 != 'KKK';
id select_type table type possible_keys key key_len ref rows Extra
diff --git a/mysql-test/suite/pbxt/r/func_in.result b/mysql-test/suite/pbxt/r/func_in.result
index b6b9e8be16e..167f75240a7 100644
--- a/mysql-test/suite/pbxt/r/func_in.result
+++ b/mysql-test/suite/pbxt/r/func_in.result
@@ -419,9 +419,15 @@ id select_type table type possible_keys key key_len ref rows Extra
select f2 from t2 where f2 in ('a','b');
f2
0
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
+Warning 1292 Truncated incorrect DOUBLE value: 'b'
explain select f2 from t2 where f2 in ('a','b');
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index t2f2 t2f2 5 NULL 3 Using where; Using index
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'a'
+Warning 1292 Truncated incorrect DOUBLE value: 'b'
select f2 from t2 where f2 in (1,'b');
f2
0
diff --git a/mysql-test/suite/pbxt/r/group_min_max.result b/mysql-test/suite/pbxt/r/group_min_max.result
index ab00cdeff59..0553be6da6b 100644
--- a/mysql-test/suite/pbxt/r/group_min_max.result
+++ b/mysql-test/suite/pbxt/r/group_min_max.result
@@ -876,10 +876,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 129 Using where; Using index for group-by
explain select a1,a2,b, max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL idx_t1_1 163 NULL 129 Using where; Using index for group-by
+1 SIMPLE t1 range NULL idx_t1_1 147 NULL 129 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range NULL idx_t1_1 163 NULL 129 Using where; Using index for group-by
+1 SIMPLE t1 range NULL idx_t1_1 147 NULL 129 Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t1 where (c > 'b111') and (c <= 'g112') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL idx_t1_1 163 NULL 129 Using where; Using index for group-by
@@ -924,7 +924,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
explain select a1,a2,b, max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
+1 SIMPLE t2 range NULL idx_t2_1 146 NULL # Using where; Using index for group-by
explain select a1,a2,b,min(c),max(c) from t2 where (c > 'b1') or (c <= 'g1') group by a1,a2,b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range NULL idx_t2_1 163 NULL # Using where; Using index for group-by
@@ -2267,7 +2267,7 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer1 JOIN t1 AS t1_outer2
ON t1_outer1.a = (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2)
AND t1_outer1.b = t1_outer2.b;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1_outer1 ref a a 5 const 1 Using index
+1 PRIMARY t1_outer1 ref a a 5 const 1 Using where; Using index
1 PRIMARY t1_outer2 index NULL a 10 NULL 15 Using where; Using index; Using join buffer (flat, BNL join)
2 SUBQUERY t1 index NULL a 10 NULL 15 Using index
EXPLAIN SELECT (SELECT (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) x
diff --git a/mysql-test/suite/pbxt/r/join_nested.result b/mysql-test/suite/pbxt/r/join_nested.result
index b4edf18f2f5..1a195cb13a8 100644
--- a/mysql-test/suite/pbxt/r/join_nested.result
+++ b/mysql-test/suite/pbxt/r/join_nested.result
@@ -1017,6 +1017,7 @@ id select_type table type possible_keys key key_len ref rows Extra
ATTENTION: the above EXPLAIN has several competing QEPs with identical
. costs. To combat the plan change it uses --sorted_result and
. and --replace tricks
+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);
EXPLAIN
@@ -1041,7 +1042,7 @@ ON t6.b >= 2 AND t5.b=t7.b
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
-(t1.a != 2),
+(t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -1089,7 +1090,7 @@ ON t6.b >= 2 AND t5.b=t7.b
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
-(t1.a != 2),
+(t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
diff --git a/mysql-test/suite/pbxt/r/key_diff.result b/mysql-test/suite/pbxt/r/key_diff.result
index 33bedfcc39e..99bc7e7f8ad 100644
--- a/mysql-test/suite/pbxt/r/key_diff.result
+++ b/mysql-test/suite/pbxt/r/key_diff.result
@@ -6,7 +6,12 @@ KEY (a),
KEY (b)
);
INSERT INTO t1 VALUES ('A','B'),('b','A'),('C','c'),('D','E'),('a','a');
-select * from t1,t1 as t2;
+INSERT INTO t1 VALUES
+('AA','BB'),('bb','AA'),('CC','cc'),('DD','EE'),('aa','aa');
+INSERT INTO t1 VALUES
+('AAA','BBB'),('bbb','AAA'),('CCC','ccc'),('DDD','EEE'),('aaa','aaa');
+select * from t1,t1 as t2
+where length(t1.A)=1 and length(t2.B)=1 ;
a b a b
A B A B
b A A B
@@ -33,11 +38,14 @@ b A a a
C c a a
D E a a
a a a a
-explain select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B;
+explain select t1.*,t2.* from t1,t1 as t2
+where t1.A=t2.B and length(t1.A)=1 and length(t2.B)=1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL a NULL NULL NULL 5
+1 SIMPLE t1 ALL a NULL NULL NULL 15 Using where
1 SIMPLE t2 ref b b 4 test.t1.a 1 Using where
-select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B order by binary t1.a,t2.a;
+select t1.*,t2.* from t1,t1 as t2
+where t1.A=t2.B and length(t1.A)=1 and length(t2.B)=1
+order by binary t1.a,t2.a;
a b a b
A B a a
A B b A
diff --git a/mysql-test/suite/pbxt/r/limit.result b/mysql-test/suite/pbxt/r/limit.result
index 9bbf54fcfe9..dd53cb7deec 100644
--- a/mysql-test/suite/pbxt/r/limit.result
+++ b/mysql-test/suite/pbxt/r/limit.result
@@ -23,7 +23,7 @@ a b
2 2
3 2
4 4
-delete from t1 where b=2 limit 1;
+delete from t1 where b=2 order by a limit 1;
select * from t1 order by a;
a b
0 0
diff --git a/mysql-test/suite/pbxt/r/negation_elimination.result b/mysql-test/suite/pbxt/r/negation_elimination.result
index 61889824865..5c6abad6b4c 100644
--- a/mysql-test/suite/pbxt/r/negation_elimination.result
+++ b/mysql-test/suite/pbxt/r/negation_elimination.result
@@ -4,7 +4,7 @@ insert into t1 values (NULL), (0), (1), (2), (3), (4), (5), (6), (7), (8), (9),
(10), (11), (12), (13), (14), (15), (16), (17), (18), (19);
explain select * from t1 where not(not(a));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index NULL a 5 NULL 21 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 2 Using where; Using index
select * from t1 where not(not(a));
a
1
@@ -327,7 +327,7 @@ a
0
explain select * from t1 where not((a < 5 or a < 10) and (not(a > 16) or a > 17));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index
select * from t1 where not((a < 5 or a < 10) and (not(a > 16) or a > 17));
a
10
@@ -342,7 +342,7 @@ a
19
explain select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index
select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17));
a
5
@@ -388,7 +388,7 @@ Table Op Msg_type Msg_text
test.t1 analyze status OK
explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "1"), not (a not in (1,2)), not(a != 2) from t1 where not(not(a)) having not(not(a));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 SIMPLE t1 index NULL a 5 NULL 5 100.00 Using where; Using index
+1 SIMPLE t1 index a a 5 NULL 5 40.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or `test`.`t1`.`a`) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like '1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where `test`.`t1`.`a` having `test`.`t1`.`a`
+Note 1003 select `test`.`t1`.`a` AS `a`,(`test`.`t1`.`a` <> 0) AS `not(not(a))`,((`test`.`t1`.`a` > 2) or `test`.`t1`.`a`) AS `not(a <= 2 and not(a))`,(`test`.`t1`.`a` like '1') AS `not(a not like "1")`,(`test`.`t1`.`a` in (1,2)) AS `not (a not in (1,2))`,(`test`.`t1`.`a` = 2) AS `not(a != 2)` from `test`.`t1` where (`test`.`t1`.`a` <> 0) having (`test`.`t1`.`a` <> 0)
drop table t1;
diff --git a/mysql-test/suite/pbxt/r/null_key.result b/mysql-test/suite/pbxt/r/null_key.result
index f7b1a496e80..7c9a278b581 100644
--- a/mysql-test/suite/pbxt/r/null_key.result
+++ b/mysql-test/suite/pbxt/r/null_key.result
@@ -258,7 +258,7 @@ INSERT INTO t1 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4
INSERT INTO t2 VALUES (1,NULL),(2,NULL),(3,1),(4,2),(5,NULL),(6,NULL),(7,3),(8,4),(9,NULL),(10,NULL);
explain select id from t1 where uniq_id is null;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref idx1 idx1 5 const 5 Using index condition
+1 SIMPLE t1 ref idx1 idx1 5 const 5 Using where
explain select id from t1 where uniq_id =1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const idx1 idx1 5 const 1
diff --git a/mysql-test/suite/pbxt/r/order_by.result b/mysql-test/suite/pbxt/r/order_by.result
index 4f56f433169..4fc7abec96c 100644
--- a/mysql-test/suite/pbxt/r/order_by.result
+++ b/mysql-test/suite/pbxt/r/order_by.result
@@ -514,7 +514,7 @@ id select_type table type possible_keys key key_len ref rows Extra
EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.skr = t3.uid order by t1.gid,t3.skr;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 2 test.t1.skr 1 Using index condition
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 2 test.t1.skr 1 Using where
drop table t1,t2,t3;
CREATE TABLE t1 (
`titre` char(80) NOT NULL default '',
diff --git a/mysql-test/suite/pbxt/r/partition_pruning.result b/mysql-test/suite/pbxt/r/partition_pruning.result
index e5e75c55ffb..ce66ba4358d 100644
--- a/mysql-test/suite/pbxt/r/partition_pruning.result
+++ b/mysql-test/suite/pbxt/r/partition_pruning.result
@@ -651,7 +651,7 @@ Variable_name Value
Handler_read_rnd_next 0
show status like 'Handler_read_key';
Variable_name Value
-Handler_read_key 10
+Handler_read_key 5
show status like 'Handler_read_prev';
Variable_name Value
Handler_read_prev 0
diff --git a/mysql-test/suite/pbxt/r/pbxt_locking.result b/mysql-test/suite/pbxt/r/pbxt_locking.result
index 5da337c62d1..fa823b9a7e2 100644
--- a/mysql-test/suite/pbxt/r/pbxt_locking.result
+++ b/mysql-test/suite/pbxt/r/pbxt_locking.result
@@ -13,9 +13,9 @@ id
update t1 set id = 8 where id = 5;
update t1 set id = 8 where id = 4;
show processlist;
-Id User Host db Command Time State Info
-x root x test Query x NULL show processlist
-x root x test Query x Searching rows for update update t1 set id = 8 where id = 4
+Id User Host db Command Time State Info Progress
+x root x test Query x NULL show processlist 0.000
+x root x test Query x Searching rows for update update t1 set id = 8 where id = 4 0.000
commit;
select * from t1;
id
@@ -49,9 +49,9 @@ id
update t1 set id = 8 where id < 4;
update t1 set id = 8 where id = 5;
show processlist;
-Id User Host db Command Time State Info
-x root x test Query x NULL show processlist
-x root x test Query x Searching rows for update update t1 set id = 8 where id = 5
+Id User Host db Command Time State Info Progress
+x root x test Query x NULL show processlist 0.000
+x root x test Query x Searching rows for update update t1 set id = 8 where id = 5 0.000
commit;
select * from t1;
id
diff --git a/mysql-test/suite/pbxt/r/ps_1general.result b/mysql-test/suite/pbxt/r/ps_1general.result
index d8a04d48acf..baa944eebab 100644
--- a/mysql-test/suite/pbxt/r/ps_1general.result
+++ b/mysql-test/suite/pbxt/r/ps_1general.result
@@ -465,9 +465,9 @@ def key 253 64 7 Y 0 31 8
def key_len 253 4096 1 Y 0 31 8
def ref 253 2048 0 Y 0 31 8
def rows 8 10 1 Y 32928 0 63
-def Extra 253 255 57 N 1 31 8
+def Extra 253 255 27 N 1 31 8
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using index condition; Rowid-ordered scan; Using filesort
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where; Using filesort
drop table if exists t2;
create table t2 (id smallint, name varchar(20)) ;
prepare stmt1 from ' insert into t2 values(?, ?) ' ;
diff --git a/mysql-test/suite/pbxt/r/range.result b/mysql-test/suite/pbxt/r/range.result
index 7d2d17bdc1e..368fd6b946c 100644
--- a/mysql-test/suite/pbxt/r/range.result
+++ b/mysql-test/suite/pbxt/r/range.result
@@ -277,7 +277,7 @@ INSERT INTO t1 VALUES
(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a,b a 5 NULL 2 Using index condition; Using where; Rowid-ordered scan
+1 SIMPLE t1 range a,b a 5 NULL 2 Using where
SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
a b
DROP TABLE t1;
@@ -922,7 +922,7 @@ INSERT INTO t1 VALUES
('A2','2005-12-01 08:00:00',1000);
EXPLAIN SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using index condition
+1 SIMPLE t1 ref PRIMARY PRIMARY 20 const 2 Using where
SELECT * FROM t1 WHERE item='A1' AND started<='2005-12-01 24:00:00';
item started price
Warnings:
diff --git a/mysql-test/suite/pbxt/r/skip_name_resolve.result b/mysql-test/suite/pbxt/r/skip_name_resolve.result
index 8ef52e75238..ad74a2dfcc4 100644
--- a/mysql-test/suite/pbxt/r/skip_name_resolve.result
+++ b/mysql-test/suite/pbxt/r/skip_name_resolve.result
@@ -9,6 +9,6 @@ select user();
user()
#
show processlist;
-Id User Host db Command Time State Info
-<id> root <host> test <command> <time> <state> <info>
-<id> root <host> test <command> <time> <state> <info>
+Id User Host db Command Time State Info Progress
+<id> root <host> test <command> <time> <state> <info> 0.000
+<id> root <host> test <command> <time> <state> <info> 0.000
diff --git a/mysql-test/suite/pbxt/r/status.result b/mysql-test/suite/pbxt/r/status.result
index 519a55301a3..b0bcca00608 100644
--- a/mysql-test/suite/pbxt/r/status.result
+++ b/mysql-test/suite/pbxt/r/status.result
@@ -100,22 +100,30 @@ Variable_name Value
Com_show_status 3
show status like 'hand%write%';
Variable_name Value
+Handler_tmp_write 0
Handler_write 5
show status like '%tmp%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 0
+Handler_tmp_update 0
+Handler_tmp_write 0
+Rows_tmp_read 5
show status like 'hand%write%';
Variable_name Value
+Handler_tmp_write 0
Handler_write 7
show status like '%tmp%';
Variable_name Value
Created_tmp_disk_tables 0
Created_tmp_files 0
Created_tmp_tables 0
+Handler_tmp_update 0
+Handler_tmp_write 0
+Rows_tmp_read 13
show status like 'com_show_status';
Variable_name Value
Com_show_status 8
rnd_diff tmp_table_diff
-20 8
+28 8
diff --git a/mysql-test/suite/pbxt/r/subselect.result b/mysql-test/suite/pbxt/r/subselect.result
index e183cf389c0..4cbbecf284f 100644
--- a/mysql-test/suite/pbxt/r/subselect.result
+++ b/mysql-test/suite/pbxt/r/subselect.result
@@ -199,10 +199,11 @@ select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
(select * from t2 where a>1) as tt;
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 <derived3> ALL NULL NULL NULL NULL 2 100.00
+3 DERIVED t2 ALL NULL NULL NULL NULL 2 100.00 Using where
2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using filesort
Warnings:
-Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`test`.`t2`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`a` > 1)
+Note 1003 select (select `test`.`t3`.`a` from `test`.`t3` where (`test`.`t3`.`a` < 8) order by 1 desc limit 1) AS `(select t3.a from t3 where a<8 order by 1 desc limit 1)`,`tt`.`a` AS `a` from (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`a` > 1)) `tt`
select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from t3) order by 1 desc limit 1);
a
2
@@ -223,7 +224,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t4.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t4`.`b` AS `b`,(select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
+Note 1003 select `test`.`t4`.`b` AS `b`,<expr_cache><`test`.`t4`.`a`>((select avg((`test`.`t2`.`a` + (select min(`test`.`t3`.`a`) from `test`.`t3` where (`test`.`t3`.`a` >= `test`.`t4`.`a`)))) from `test`.`t2`)) AS `(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)` from `test`.`t4`
select * from t3 where exists (select * from t2 where t2.b=t3.a);
a
7
@@ -269,7 +270,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 3 100.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2);
a
7
@@ -361,12 +362,12 @@ INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1');
INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1');
EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
+1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where; Using index
4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
-2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00
+2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using where
3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index
Warnings:
-Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where ('joce' = (select 'joce' from `test`.`t8` where 1))
+Note 1003 select `test`.`t8`.`pseudo` AS `pseudo`,(select `test`.`t8`.`email` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where (`test`.`t8`.`pseudo` = (select 'joce' from `test`.`t8` where 1))
SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM
t8 WHERE pseudo='joce');
ERROR 21000: Operand should contain 1 column(s)
@@ -534,18 +535,24 @@ SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT
numreponse (SELECT numeropost FROM t1 HAVING numreponse=1)
INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
+2 SUBQUERY t1 ref PRIMARY PRIMARY 3 const 2 100.00 Using index
+Warnings:
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select 1 from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
ERROR 21000: Subquery returns more than 1 row
EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where multiple equal(1, `test`.`t1`.`numeropost`)
+Note 1003 select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = '1')
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using index
+1 PRIMARY t1 const PRIMARY,numreponse PRIMARY 7 const,const 1 100.00 Using where; Using index
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
-Note 1003 select 3 AS `numreponse` from `test`.`t1` where ((3 = 3))
+Note 1003 select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = '1') and (`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where (`test`.`t1`.`numeropost` = '1'))))
drop table t1;
CREATE TABLE t1 (a int(1));
INSERT INTO t1 VALUES (1);
@@ -1232,7 +1239,7 @@ create table t1 (id int not null auto_increment primary key, salary int, key(sal
insert into t1 (salary) values (100),(1000),(10000),(10),(500),(5000),(50000);
explain extended SELECT id FROM t1 where salary = (SELECT MAX(salary) FROM t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ref salary salary 5 const 1 100.00 Using where
+1 PRIMARY t1 ref salary salary 5 const 0 0.00 Using where
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
Warnings:
Note 1003 select `test`.`t1`.`id` AS `id` from `test`.`t1` where (`test`.`t1`.`salary` = (select max(`test`.`t1`.`salary`) from `test`.`t1`))
@@ -1408,7 +1415,7 @@ INSERT INTO t1 VALUES ('z','?');
select * from t1 where s1 > (select max(s2) from t1);
ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
select * from t1 where s1 > any (select max(s2) from t1);
-ERROR HY000: Illegal mix of collations (latin1_german1_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '>'
+ERROR HY000: Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '<'
drop table t1;
create table t1(toid int,rd int);
create table t2(userid int,pmnew int,pmtotal int);
@@ -1484,7 +1491,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`s1` AS `s1`,(not(<expr_cache><`test`.`t1`.`s1`>(<in_optimizer>(`test`.`t1`.`s1`,<exists>(<index_lookup>(<cache>(`test`.`t1`.`s1`) in t2 on s1 checking NULL where (`test`.`t2`.`s1` < 'a2') having trigcond(<is_not_null_test>(`test`.`t2`.`s1`)))))))) AS `s1 NOT IN (SELECT s1 FROM t2 WHERE s1 < 'a2')` from `test`.`t1`
drop table t1,t2;
-create table t2 (a int, b int);
+create table t2 (a int, b int not null);
create table t3 (a int);
insert into t3 values (6),(7),(3);
select * from t3 where a >= all (select b from t2);
@@ -1497,7 +1504,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < (select max(`test`.`t2`.`b`) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,((select max(`test`.`t2`.`b`) from `test`.`t2`) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2);
a
explain extended select * from t3 where a >= some (select b from t2);
@@ -1505,7 +1512,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= (select min(`test`.`t2`.`b`) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= all (select b from t2 group by 1);
a
6
@@ -1516,7 +1523,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` < <max>(select `test`.`t2`.`b` from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select `test`.`t2`.`b` from `test`.`t2` group by 1) > <cache>(`test`.`t3`.`a`))))
select * from t3 where a >= some (select b from t2 group by 1);
a
explain extended select * from t3 where a >= some (select b from t2 group by 1);
@@ -1524,7 +1531,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` >= <min>(select `test`.`t2`.`b` from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(<min>(select `test`.`t2`.`b` from `test`.`t2` group by 1) <= <cache>(`test`.`t3`.`a`))))
select * from t3 where NULL >= any (select b from t2);
a
explain extended select * from t3 where NULL >= any (select b from t2);
@@ -1532,7 +1539,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= (select min(`test`.`t2`.`b`) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= any (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= any (select b from t2 group by 1);
@@ -1540,7 +1547,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= <min>(select `test`.`t2`.`b` from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select `test`.`t2`.`b` from `test`.`t2` group by 1) <= NULL)))
select * from t3 where NULL >= some (select b from t2);
a
explain extended select * from t3 where NULL >= some (select b from t2);
@@ -1548,7 +1555,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= (select min(`test`.`t2`.`b`) from `test`.`t2`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= NULL)))
select * from t3 where NULL >= some (select b from t2 group by 1);
a
explain extended select * from t3 where NULL >= some (select b from t2 group by 1);
@@ -1556,7 +1563,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(NULL >= <min>(select `test`.`t2`.`b` from `test`.`t2` group by 1))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select `test`.`t2`.`b` from `test`.`t2` group by 1) <= NULL)))
insert into t2 values (2,2), (2,1), (3,3), (3,1);
select * from t3 where a > all (select max(b) from t2 group by a);
a
@@ -1567,7 +1574,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 4 100.00 Using temporary
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(`test`.`t3`.`a` <= <max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`))))
+Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= <cache>(`test`.`t3`.`a`))))
drop table t2, t3;
CREATE TABLE `t1` ( `id` mediumint(9) NOT NULL auto_increment, `taskid` bigint(20) NOT NULL default '0', `dbid` int(11) NOT NULL default '0', `create_date` datetime NOT NULL default '0000-00-00 00:00:00', `last_update` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`id`)) ENGINE=MyISAM CHARSET=latin1 AUTO_INCREMENT=3 ;
INSERT INTO `t1` (`id`, `taskid`, `dbid`, `create_date`,`last_update`) VALUES (1, 1, 15, '2003-09-29 10:31:36', '2003-09-29 10:31:36'), (2, 1, 21, now(), now());
@@ -1618,7 +1625,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 UNION t1 ALL NULL NULL NULL NULL 1 100.00
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
-Note 1003 select `test`.`t1`.`s1` AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',('f' > <min>(select `test`.`t1`.`s1` from `test`.`t1` union select `test`.`t1`.`s1` from `test`.`t1`))))
+Note 1003 select `test`.`t1`.`s1` AS `s1` from `test`.`t1` where <nop>(<in_optimizer>('f',(<min>(select `test`.`t1`.`s1` from `test`.`t1` union select `test`.`t1`.`s1` from `test`.`t1`) < 'f')))
drop table t1;
CREATE TABLE t1 (number char(11) NOT NULL default '') ENGINE=MyISAM CHARSET=latin1;
INSERT INTO t1 VALUES ('69294728265'),('18621828126'),('89356874041'),('95895001874');
@@ -2824,7 +2831,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
2 DEPENDENT SUBQUERY 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`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where ((`test`.`t2`.`flag` = '0') and trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`)))) having (trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FROM t2 WHERE flag = 'N');
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
@@ -2836,7 +2843,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
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; Using temporary
Warnings:
-Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`two`,`test`.`t1`.`one`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
+Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two`,<expr_cache><`test`.`t1`.`one`,`test`.`t1`.`two`>(<in_optimizer>((`test`.`t1`.`one`,`test`.`t1`.`two`),<exists>(select `test`.`t2`.`one`,`test`.`t2`.`two` from `test`.`t2` where (`test`.`t2`.`flag` = '0') group by `test`.`t2`.`one`,`test`.`t2`.`two` having (trigcond(((<cache>(`test`.`t1`.`one`) = `test`.`t2`.`one`) or isnull(`test`.`t2`.`one`))) and trigcond(((<cache>(`test`.`t1`.`two`) = `test`.`t2`.`two`) or isnull(`test`.`t2`.`two`))) and trigcond(<is_not_null_test>(`test`.`t2`.`one`)) and trigcond(<is_not_null_test>(`test`.`t2`.`two`)))))) AS `test` from `test`.`t1`
DROP TABLE t1,t2;
set @@optimizer_switch=@save_optimizer_switch;
CREATE TABLE t1 (a char(5), b char(5));
@@ -2953,7 +2960,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 1 Using where
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -2965,7 +2972,7 @@ ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 Using index
-1 PRIMARY r const PRIMARY PRIMARY 4 const 1
+1 PRIMARY r eq_ref PRIMARY PRIMARY 4 const 1 Using where
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 1 Using where
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
@@ -4046,7 +4053,7 @@ CREATE TABLE t1 (a int, b int, KEY (a));
INSERT INTO t1 VALUES (1,1),(2,1);
EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT COUNT(*) FROM t1 GROUP BY b);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref a a 5 const 1 Using where; Using index
+1 PRIMARY t1 ref a a 5 const 0 Using where; Using index
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort
DROP TABLE t1;
CREATE TABLE t1 (id int NOT NULL, st CHAR(2), INDEX idx(id));
@@ -4217,8 +4224,8 @@ CREATE INDEX I1 ON t1 (a);
CREATE INDEX I2 ON t1 (b);
EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan
-1 PRIMARY t1 ref I2 I2 13 test.t1.a 1 Using where
+1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where
+1 PRIMARY t1 ref I1 I1 2 test.t1.b 1 Using where; Using index; FirstMatch(t1)
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
a b
CREATE TABLE t2 (a VARCHAR(1), b VARCHAR(10));
@@ -4227,15 +4234,15 @@ CREATE INDEX I1 ON t2 (a);
CREATE INDEX I2 ON t2 (b);
EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 index I1 I1 4 NULL 2 Using where; Using index; LooseScan
-1 PRIMARY t2 ref I2 I2 13 test.t2.a 1 Using where
+1 PRIMARY t2 ALL I2 NULL NULL NULL 2 Using where
+1 PRIMARY t2 ref I1 I1 4 test.t2.b 1 Using where; Using index; FirstMatch(t2)
SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
a b
EXPLAIN
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 index I1 I1 2 NULL 2 Using where; Using index; LooseScan
-1 PRIMARY t1 ref I2 I2 13 test.t1.a 1 Using where
+1 PRIMARY t1 ALL I2 NULL NULL NULL 2 Using where
+1 PRIMARY t1 ref I1 I1 2 test.t1.b 1 Using where; Using index; FirstMatch(t1)
SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1 WHERE LENGTH(a)<500);
a b
DROP TABLE t1,t2;
diff --git a/mysql-test/suite/pbxt/t/join_nested.test b/mysql-test/suite/pbxt/t/join_nested.test
index 3b72dc1e293..98ffcbc9a8a 100644
--- a/mysql-test/suite/pbxt/t/join_nested.test
+++ b/mysql-test/suite/pbxt/t/join_nested.test
@@ -587,6 +587,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
--echo . costs. To combat the plan change it uses --sorted_result and
--echo . and --replace tricks
+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);
@@ -614,7 +615,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
- (t1.a != 2),
+ (t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -653,7 +654,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
- (t1.a != 2),
+ (t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
diff --git a/mysql-test/suite/pbxt/t/key_diff.test b/mysql-test/suite/pbxt/t/key_diff.test
index 5e9d7bac9cc..fc93c7418ab 100644
--- a/mysql-test/suite/pbxt/t/key_diff.test
+++ b/mysql-test/suite/pbxt/t/key_diff.test
@@ -13,11 +13,19 @@ CREATE TABLE t1 (
);
INSERT INTO t1 VALUES ('A','B'),('b','A'),('C','c'),('D','E'),('a','a');
+INSERT INTO t1 VALUES
+ ('AA','BB'),('bb','AA'),('CC','cc'),('DD','EE'),('aa','aa');
+INSERT INTO t1 VALUES
+ ('AAA','BBB'),('bbb','AAA'),('CCC','ccc'),('DDD','EEE'),('aaa','aaa');
-select * from t1,t1 as t2;
-explain select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B;
+select * from t1,t1 as t2
+ where length(t1.A)=1 and length(t2.B)=1 ;
+explain select t1.*,t2.* from t1,t1 as t2
+ where t1.A=t2.B and length(t1.A)=1 and length(t2.B)=1;
#select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B;
-select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B order by binary t1.a,t2.a;
+select t1.*,t2.* from t1,t1 as t2
+ where t1.A=t2.B and length(t1.A)=1 and length(t2.B)=1
+order by binary t1.a,t2.a;
select * from t1 where a='a';
drop table t1;
diff --git a/mysql-test/suite/pbxt/t/limit.test b/mysql-test/suite/pbxt/t/limit.test
index 0844af8705d..a65d5060e4d 100644
--- a/mysql-test/suite/pbxt/t/limit.test
+++ b/mysql-test/suite/pbxt/t/limit.test
@@ -15,7 +15,7 @@ update t1 set b=2 where b=1 limit 2;
select * from t1 order by a; # PBXT: required for consistent result
update t1 set b=4 where b=1;
select * from t1 order by a; # PBXT: required for consistent result
-delete from t1 where b=2 limit 1;
+delete from t1 where b=2 order by a limit 1;
select * from t1 order by a; # PBXT: required for consistent result
delete from t1 limit 1;
select * from t1 order by a; # PBXT: required for consistent result
diff --git a/mysql-test/suite/pbxt/t/subselect.test b/mysql-test/suite/pbxt/t/subselect.test
index 3f4d6a9a870..5e9c6eee6a6 100644
--- a/mysql-test/suite/pbxt/t/subselect.test
+++ b/mysql-test/suite/pbxt/t/subselect.test
@@ -278,8 +278,9 @@ SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT *
SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a;
SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a;
INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
--- error 1242
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+-- error 1242
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
drop table t1;
@@ -928,7 +929,7 @@ drop table t1,t2;
#
# correct ALL optimisation
#
-create table t2 (a int, b int);
+create table t2 (a int, b int not null);
create table t3 (a int);
insert into t3 values (6),(7),(3);
select * from t3 where a >= all (select b from t2);
diff --git a/mysql-test/suite/rpl/r/rpl_idempotency.result b/mysql-test/suite/rpl/r/rpl_idempotency.result
index 76abd0f64c0..ed04335d5f0 100644
--- a/mysql-test/suite/rpl/r/rpl_idempotency.result
+++ b/mysql-test/suite/rpl/r/rpl_idempotency.result
@@ -1,6 +1,6 @@
include/master-slave.inc
[connection master]
-call mtr.add_suppression("Can.t find record in .t[12].* Error_code: 1032");
+call mtr.add_suppression("Can.t find record in .t[12].*");
call mtr.add_suppression("Slave: Cannot delete or update a parent row: a foreign key constraint fails .* Error_code: 1451");
call mtr.add_suppression("Slave: Cannot add or update a child row: a foreign key constraint fails .* Error_code: 1452");
call mtr.add_suppression("Slave SQL.*Could not execute Write_rows event on table test.* Duplicate entry .1. for key .PRIMARY.* Error_code: 1062");
diff --git a/mysql-test/suite/rpl/r/rpl_row_annotate_do.result b/mysql-test/suite/rpl/r/rpl_row_annotate_do.result
index 0ece93e7aa5..a7dc2a569a1 100644
--- a/mysql-test/suite/rpl/r/rpl_row_annotate_do.result
+++ b/mysql-test/suite/rpl/r/rpl_row_annotate_do.result
@@ -127,7 +127,7 @@ slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4
########################################################################
# INSERTs DELAYED ON MASTERs
########################################################################
-SET SESSION binlog_annotate_rows_events = ON;
+SET SESSION binlog_annotate_row_events = ON;
INSERT DELAYED INTO test1.t4 VALUES (1,1);
FLUSH TABLES;
SELECT * FROM test1.t4 ORDER BY a;
diff --git a/mysql-test/suite/rpl/r/rpl_row_annotate_dont.result b/mysql-test/suite/rpl/r/rpl_row_annotate_dont.result
index 8463256d5db..2a3b5b1870e 100644
--- a/mysql-test/suite/rpl/r/rpl_row_annotate_dont.result
+++ b/mysql-test/suite/rpl/r/rpl_row_annotate_dont.result
@@ -109,7 +109,7 @@ slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4
########################################################################
# INSERTs DELAYED ON MASTERs
########################################################################
-SET SESSION binlog_annotate_rows_events = ON;
+SET SESSION binlog_annotate_row_events = ON;
INSERT DELAYED INTO test1.t4 VALUES (1,1);
FLUSH TABLES;
SELECT * FROM test1.t4 ORDER BY a;
diff --git a/mysql-test/suite/rpl/r/rpl_stm_000001.result b/mysql-test/suite/rpl/r/rpl_stm_000001.result
index 3a67772d11a..afe4096b84c 100644
--- a/mysql-test/suite/rpl/r/rpl_stm_000001.result
+++ b/mysql-test/suite/rpl/r/rpl_stm_000001.result
@@ -48,7 +48,7 @@ select (@id := id) - id from t2;
kill @id;
drop table t2;
Got one of the listed errors
-include/wait_for_slave_sql_error_and_skip.inc [errno=1053]
+include/wait_for_slave_sql_error_and_skip.inc [errno=1927]
select count(*) from t1;
count(*)
5000
diff --git a/mysql-test/suite/rpl/t/rpl_idempotency.test b/mysql-test/suite/rpl/t/rpl_idempotency.test
index aa63ac47d81..1b02795dfc6 100644
--- a/mysql-test/suite/rpl/t/rpl_idempotency.test
+++ b/mysql-test/suite/rpl/t/rpl_idempotency.test
@@ -9,7 +9,7 @@ source include/have_innodb.inc;
# Add suppression for expected warning(s) in slaves error log
-call mtr.add_suppression("Can.t find record in .t[12].* Error_code: 1032");
+call mtr.add_suppression("Can.t find record in .t[12].*");
call mtr.add_suppression("Slave: Cannot delete or update a parent row: a foreign key constraint fails .* Error_code: 1451");
call mtr.add_suppression("Slave: Cannot add or update a child row: a foreign key constraint fails .* Error_code: 1452");
call mtr.add_suppression("Slave SQL.*Could not execute Write_rows event on table test.* Duplicate entry .1. for key .PRIMARY.* Error_code: 1062");
diff --git a/mysql-test/suite/rpl/t/rpl_row_annotate_do-slave.opt b/mysql-test/suite/rpl/t/rpl_row_annotate_do-slave.opt
index aa3af621897..18de9bd1e33 100644
--- a/mysql-test/suite/rpl/t/rpl_row_annotate_do-slave.opt
+++ b/mysql-test/suite/rpl/t/rpl_row_annotate_do-slave.opt
@@ -1 +1 @@
---log-slave-updates --replicate-annotate-rows-events --replicate-ignore-table=test1.xt1 --replicate-ignore-table=test1.xt2 \ No newline at end of file
+--log-slave-updates --replicate-annotate-row-events --replicate-ignore-table=test1.xt1 --replicate-ignore-table=test1.xt2
diff --git a/mysql-test/suite/rpl/t/rpl_row_annotate_do.test b/mysql-test/suite/rpl/t/rpl_row_annotate_do.test
index b61ce0ab6d8..4114f90b90b 100644
--- a/mysql-test/suite/rpl/t/rpl_row_annotate_do.test
+++ b/mysql-test/suite/rpl/t/rpl_row_annotate_do.test
@@ -1,7 +1,7 @@
###############################################################################
# WL47: Store in binlog text of statements that caused RBR events
# Wrapper for extra/rpl/rpl_row_annotate.test.
-# Intended to test that if the --replicate-annotate-rows-events option
+# Intended to test that if the --replicate-annotate-row-events option
# is switched on on slave then Annotate_events:
# - are reproduced on slave
# - are reproduced only once for "multi-table-maps" rbr queries
diff --git a/mysql-test/suite/rpl/t/rpl_row_annotate_dont.test b/mysql-test/suite/rpl/t/rpl_row_annotate_dont.test
index 56765c591aa..ef746e76b4d 100644
--- a/mysql-test/suite/rpl/t/rpl_row_annotate_dont.test
+++ b/mysql-test/suite/rpl/t/rpl_row_annotate_dont.test
@@ -1,7 +1,7 @@
###############################################################################
# WL47: Store in binlog text of statements that caused RBR events
# Wrapper for extra/rpl/rpl_row_annotate.test.
-# Intended to test that if the --replicate-annotate-rows-events option
+# Intended to test that if the --replicate-annotate-row-events option
# is switched off on slave then Annotate_events are not reproduced.
###############################################################################
diff --git a/mysql-test/suite/rpl/t/rpl_stm_000001.test b/mysql-test/suite/rpl/t/rpl_stm_000001.test
index 9841ecb040a..6b693b8dcb7 100644
--- a/mysql-test/suite/rpl/t/rpl_stm_000001.test
+++ b/mysql-test/suite/rpl/t/rpl_stm_000001.test
@@ -96,14 +96,15 @@ drop table t2;
connection master;
# The get_lock function causes warning for unsafe statement.
--disable_warnings
---error 1317,2013
+# 2013 = CR_SERVER_LOST
+--error ER_QUERY_INTERRUPTED,ER_CONNECTION_KILLED,2013
reap;
--enable_warnings
connection slave;
# The SQL slave thread should now have stopped because the query was killed on
# the master (so it has a non-zero error code in the binlog).
-# 1053 = ER_SERVER_SHUTDOWN
---let $slave_sql_errno= 1053
+# 1927 = ER_CONNECTION_KILLED
+--let $slave_sql_errno= 1927
--source include/wait_for_slave_sql_error_and_skip.inc
select count(*) from t1;
diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result
index de4d4dcbb93..693ea0d9174 100644
--- a/mysql-test/suite/vcol/r/vcol_misc.result
+++ b/mysql-test/suite/vcol/r/vcol_misc.result
@@ -139,17 +139,20 @@ create table t2 (c int, d int, v int as (d+1), index idx(c));
insert into t2(c,d) values
(20, 100), (20, 300), (30, 100), (30, 200), (40, 500),
(70, 100), (40, 300), (60, 100), (40, 100), (70, 100);
+insert into t2(c,d) values
+(120, 100), (150, 300), (130, 100), (130, 200), (140, 500),
+(170, 100), (180, 300), (160, 100), (40, 100), (170, 100);
set join_cache_level=6;
explain
select * from t1,t2 where t1.b=t2.c and d <= 100;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where
-1 SIMPLE t2 ref idx idx 5 test.t1.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+1 SIMPLE t2 ref idx idx 5 test.t1.b 2 Using where
select * from t1,t2 where t1.b=t2.c and d <= 100;
a b c d v
+3 30 30 100 101
4 20 20 100 101
1 20 20 100 101
-3 30 30 100 101
set join_cache_level=default;
drop table t1, t2;
create table t1 (a bigint, b bigint as (a > '2'));
diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result
index 129022dd7cc..fb63c6e6739 100644
--- a/mysql-test/suite/vcol/r/vcol_select_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result
@@ -44,7 +44,7 @@ a b c
1 -1 -1
explain select * from t3 where c>=-1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Rowid-ordered scan
+1 SIMPLE t3 range c c 5 NULL 1 Using where
# select_type=SIMPLE, type=ref
select * from t1,t3 where t1.c=t3.c and t3.c=-1;
a b c a b c
@@ -98,7 +98,8 @@ a b c
NULL NULL NULL
explain select * from (select a,b,c from t1) as t11;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5
+2 DERIVED t1 ALL NULL NULL NULL NULL 5
###
### Using aggregate functions with/without DISTINCT
###
@@ -136,11 +137,11 @@ id select_type table type possible_keys key key_len ref rows Extra
# SELECT * FROM tbl_name WHERE <vcol expr>
select * from t3 where c >= -2;
a b c
-1 -1 -1
2 -2 -2
+1 -1 -1
explain select * from t3 where c >= -2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Rowid-ordered scan
+1 SIMPLE t3 range c c 5 NULL 1 Using where
# SELECT * FROM tbl_name WHERE <non-vcol expr>
select * from t3 where a between 1 and 2;
a b c
@@ -160,11 +161,11 @@ id select_type table type possible_keys key key_len ref rows Extra
# SELECT * FROM tbl_name WHERE <indexed vcol expr>
select * from t3 where c between -2 and -1;
a b c
-1 -1 -1
2 -2 -2
+1 -1 -1
explain select * from t3 where c between -2 and -1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Rowid-ordered scan
+1 SIMPLE t3 range c c 5 NULL 1 Using where
# SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <non-indexed vcol>
select * from t3 where a between 1 and 2 order by b;
a b c
@@ -204,7 +205,7 @@ a b c
1 -1 -1
explain select * from t3 where c between -2 and -1 order by b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Rowid-ordered scan; Using filesort
+1 SIMPLE t3 range c c 5 NULL 1 Using where; Using filesort
# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <indexed vcol>
select * from t3 where b between -2 and -1 order by c;
a b c
@@ -220,7 +221,7 @@ a b c
1 -1 -1
explain select * from t3 where c between -2 and -1 order by c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using index condition
+1 SIMPLE t3 range c c 5 NULL 1 Using where
# SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol>
select sum(b) from t1 group by b;
sum(b)
diff --git a/mysql-test/suite/vcol/r/vcol_select_myisam.result b/mysql-test/suite/vcol/r/vcol_select_myisam.result
index 43ec4e90e88..6922f59bf7e 100644
--- a/mysql-test/suite/vcol/r/vcol_select_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result
@@ -44,7 +44,7 @@ a b c
1 -1 -1
explain select * from t3 where c>=-1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t3 range c c 5 NULL 2 Using where
# select_type=SIMPLE, type=ref
select * from t1,t3 where t1.c=t3.c and t3.c=-1;
a b c a b c
@@ -98,7 +98,8 @@ a b c
NULL NULL NULL
explain select * from (select a,b,c from t1) as t11;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 5
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 5
+2 DERIVED t1 ALL NULL NULL NULL NULL 5
###
### Using aggregate functions with/without DISTINCT
###
@@ -140,15 +141,15 @@ a b c
1 -1 -1
explain select * from t3 where c >= -2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 2 Using index condition; Rowid-ordered scan
+1 SIMPLE t3 range c c 5 NULL 2 Using where
# SELECT * FROM tbl_name WHERE <non-vcol expr>
select * from t3 where a between 1 and 2;
a b c
-2 -2 -2
1 -1 -1
+2 -2 -2
explain select * from t3 where a between 1 and 2;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 1 Using where
# SELECT * FROM tbl_name WHERE <non-indexed vcol expr>
select * from t3 where b between -2 and -1;
a b c
@@ -164,7 +165,7 @@ a b c
1 -1 -1
explain select * from t3 where c between -2 and -1;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Rowid-ordered scan
+1 SIMPLE t3 range c c 5 NULL 1 Using where
# SELECT * FROM tbl_name WHERE <non-vcol expr> ORDER BY <indexed vcol>
select * from t3 where a between 1 and 2 order by c;
a b c
@@ -172,7 +173,7 @@ a b c
1 -1 -1
explain select * from t3 where a between 1 and 2 order by c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan; Using filesort
+1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 1 Using where; Using filesort
# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-vcol>
select * from t3 where b between -2 and -1 order by a;
a b c
@@ -188,7 +189,7 @@ a b c
2 -2 -2
explain select * from t3 where c between -2 and -1 order by a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Rowid-ordered scan; Using filesort
+1 SIMPLE t3 range c c 5 NULL 1 Using where; Using filesort
# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <non-indexed vcol>
select * from t3 where b between -2 and -1 order by b;
a b c
@@ -204,7 +205,7 @@ a b c
1 -1 -1
explain select * from t3 where c between -2 and -1 order by b;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using index condition; Rowid-ordered scan; Using filesort
+1 SIMPLE t3 range c c 5 NULL 1 Using where; Using filesort
# SELECT * FROM tbl_name WHERE <non-indexed vcol expr> ORDER BY <indexed vcol>
select * from t3 where b between -2 and -1 order by c;
a b c
@@ -220,7 +221,7 @@ a b c
1 -1 -1
explain select * from t3 where c between -2 and -1 order by c;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t3 range c c 5 NULL 1 Using index condition
+1 SIMPLE t3 range c c 5 NULL 1 Using where
# SELECT sum(<non-indexed vcol>) FROM tbl_name GROUP BY <non-indexed vcol>
select sum(b) from t1 group by b;
sum(b)
diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test
index a0616d187da..f87cb5fbec8 100644
--- a/mysql-test/suite/vcol/t/vcol_misc.test
+++ b/mysql-test/suite/vcol/t/vcol_misc.test
@@ -151,6 +151,9 @@ create table t2 (c int, d int, v int as (d+1), index idx(c));
insert into t2(c,d) values
(20, 100), (20, 300), (30, 100), (30, 200), (40, 500),
(70, 100), (40, 300), (60, 100), (40, 100), (70, 100);
+insert into t2(c,d) values
+ (120, 100), (150, 300), (130, 100), (130, 200), (140, 500),
+ (170, 100), (180, 300), (160, 100), (40, 100), (170, 100);
set join_cache_level=6;
explain
diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test
index 028c64d6de7..4b775bc761f 100644
--- a/mysql-test/t/case.test
+++ b/mysql-test/t/case.test
@@ -170,3 +170,12 @@ select t1.a, (case t1.a when 0 then 0 else t1.b end) d from t1
drop table t1, t2;
--echo End of 5.0 tests
+
+#
+# lp:839387 Assertion `(Item_result)i != TIME_RESULT' failed with CASE + datetime
+#
+
+create table t1 (f1 time);
+insert t1 values ('00:00:00'),('00:01:00');
+select case t1.f1 when '00:00:00' then 1 end from t1;
+drop table t1;
diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test
index b1e2d23b654..42693a2f01e 100644
--- a/mysql-test/t/cast.test
+++ b/mysql-test/t/cast.test
@@ -37,7 +37,7 @@ select cast("2011-02-03 10:11:12.123456" as datetime(0));
select cast("2011-02-03 10:11:12.123456" as datetime(5));
select cast("2011-02-03 10:11:12.123456" as datetime(6));
select cast("2011-02-03 10:11:12" as datetime(6));
-select cast(cast(20010203101112.1 as double) as datetime(1));
+select cast(cast(20010203101112.5 as double) as datetime(1));
select cast(cast(010203101112.12 as double) as datetime(2));
select cast(cast(20010203101112.121314 as decimal(32,6)) as datetime(6));
select cast(20010203101112.121314 as datetime(6));
@@ -407,3 +407,8 @@ insert into t1 values ('11:22:33','2011-12-13','2011-12-13 11:22:33');
select cast(f1 as unsigned), cast(f2 as unsigned), cast(f3 as unsigned) from t1;
drop table t1;
+#
+# CAST(... AS DATE) and invalid dates
+#
+SELECT CAST(TIME('10:20:30') AS DATE) + INTERVAL 1 DAY;
+
diff --git a/mysql-test/t/comments.test b/mysql-test/t/comments.test
index 3a18a8bd483..08c74c99d0c 100644
--- a/mysql-test/t/comments.test
+++ b/mysql-test/t/comments.test
@@ -21,6 +21,17 @@ select 1 # The rest of the row will be ignored
# End of 4.1 tests
#
+# Testing of MariaDB executable comments
+#
+
+select 1 /*M! +1 */;
+select 1 /*M!50000 +1 */;
+select 1 /*M!50300 +1 */;
+select 2 /*M!99999 +1 */;
+--error ER_PARSE_ERROR
+select 2 /*M!0000 +1 */;
+
+#
# Bug#25411 (trigger code truncated)
#
diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test
index 75368925499..962cec95add 100644
--- a/mysql-test/t/derived.test
+++ b/mysql-test/t/derived.test
@@ -315,19 +315,3 @@ WHERE j = SUBSTRING('12', (SELECT * FROM (SELECT MIN(j) FROM t1) t2))) t3;
DROP TABLE t1;
--echo # End of 5.0 tests
-
---echo #
---echo # LP bug #793436: query with a derived table for which optimizer proves
---echo # that it contains not more than 1 row
---echo #
-
-CREATE TABLE t1 (a int, KEY (a)) ;
-INSERT INTO t1 VALUES (3), (1);
-CREATE TABLE t2 (a int);
-INSERT INTO t2 VALUES (3);
-
-EXPLAIN
-SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a;
-SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a;
-
-DROP TABLE t1,t2;
diff --git a/mysql-test/t/derived_opt.test b/mysql-test/t/derived_opt.test
new file mode 100644
index 00000000000..42f3ce296e1
--- /dev/null
+++ b/mysql-test/t/derived_opt.test
@@ -0,0 +1,206 @@
+# Initialize
+--disable_warnings
+drop table if exists t1,t2,t3;
+--enable_warnings
+
+set @exit_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+# The 'default' value within the scope of this test:
+set @save_optimizer_switch=@@optimizer_switch;
+
+CREATE TABLE t1 (a int not null, b char (10) not null);
+insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c');
+CREATE TABLE t2 (a int not null, b char (10) not null);
+insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e');
+CREATE TABLE t3 (a int not null, b char (10) not null);
+insert into t3 values (3,'f'),(4,'y'),(5,'z'),(6,'c');
+select * from t1 as x1, (select * from t1) as x2;
+explain select * from t1 as x1, (select * from t1) as x2;
+drop table if exists t2,t3;
+
+CREATE TABLE t2 (a int not null);
+insert into t2 values(1);
+select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
+explain select * from (select t1.*, t2.a as t2a from t1,t2 where t1.a=t2.a) t1;
+drop table t1, t2;
+
+create table t1(a int not null, t char(8), index(a));
+--disable_query_log
+begin;
+let $1 = 10000;
+while ($1)
+ {
+ eval insert into t1 values ($1,'$1');
+ dec $1;
+ }
+commit;
+--enable_query_log
+SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20;
+explain select count(*) from t1 as tt1, (select * from t1) as tt2;
+drop table t1;
+
+#
+# test->used_keys test for derived tables
+#
+create table t1 (mat_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, matintnum CHAR(6) NOT NULL, test MEDIUMINT UNSIGNED NULL);
+create table t2 (mat_id MEDIUMINT UNSIGNED NOT NULL, pla_id MEDIUMINT UNSIGNED NOT NULL);
+insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd', 4), (NULL, 'e', 5), (NULL, 'f', 6), (NULL, 'g', 7), (NULL, 'h', 8), (NULL, 'i', 9);
+insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
+
+SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+
+explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
+drop table t1,t2;
+
+#
+# deived tables with subquery inside all by one table
+#
+create table t1 (E1 INTEGER UNSIGNED NOT NULL, E2 INTEGER UNSIGNED NOT NULL, E3 INTEGER UNSIGNED NOT NULL, PRIMARY KEY(E1)
+);
+insert into t1 VALUES(1,1,1), (2,2,1);
+select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2;
+explain select count(*) from t1 INNER JOIN (SELECT A.E1, A.E2, A.E3 FROM t1 AS A WHERE A.E3 = (SELECT MAX(B.E3) FROM t1 AS B WHERE A.E2 = B.E2)) AS THEMAX ON t1.E1 = THEMAX.E2 AND t1.E1 = t1.E2;
+drop table t1;
+
+create table t1 (a int);
+insert into t1 values (1),(2);
+select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
+explain select * from ( select * from t1 union select * from t1) a,(select * from t1 union select * from t1) b;
+drop table t1;
+
+#
+# "Using index" in explain
+#
+create table t2 (a int, b int, primary key (a));
+insert into t2 values (1,7),(2,7);
+explain select a from t2 where a>1;
+explain select a from (select a from t2 where a>1) tt;
+drop table t2;
+
+#
+# prepared EXPLAIN
+#
+create table t1
+(
+ c1 tinyint, c2 smallint, c3 mediumint, c4 int,
+ c5 integer, c6 bigint, c7 float, c8 double,
+ c9 double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
+ c13 date, c14 datetime, c15 timestamp, c16 time,
+ c17 year, c18 bit, c19 bool, c20 char,
+ c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
+ c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
+ c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
+ c32 set('monday', 'tuesday', 'wednesday')
+) engine = MYISAM ;
+create table t2 like t1;
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+
+set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ;
+prepare stmt1 from @stmt ;
+execute stmt1 ;
+execute stmt1 ;
+explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
+deallocate prepare stmt1;
+drop tables t1,t2;
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # LP bug #793436: query with a derived table for which optimizer proves
+--echo # that it contains not more than 1 row
+--echo #
+
+CREATE TABLE t1 (a int, KEY (a)) ;
+INSERT INTO t1 VALUES (3), (1);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (3);
+
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a;
+SELECT * FROM (SELECT DISTINCT * FROM t2) t, t1 WHERE t1.a = t.a;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #800518: crash with a query over a derived table
+--echo # when a min/max optimization is applied
+--echo #
+
+CREATE TABLE t1 (a int, b int, c varchar(10), INDEX idx(a,b)) ;
+INSERT INTO t1 VALUES
+ (100, 3, 'xxx'), (200, 7, 'yyyyyyy'), (100, 1, 't'),
+ (200, 4, 'aaaa'), (100, 3, 'eee'), (100, 5, 'zzzzz');
+
+EXPLAIN
+SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100;
+SELECT MAX(b) FROM (SELECT * FROM t1) AS t WHERE a = 100;
+
+DROP TABLE t1;
+
+--echo #
+--echo # LP bug #799499: query over a materialized view
+--echo # accessed by a key
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (8);
+
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES
+ (262, NULL), (253, 190), (260, NULL), (250, 163), (188, 8),
+ (257,200), (256, NULL), (255, 8), (249, NULL), (259, 7);
+
+CREATE VIEW v1 AS SELECT a, MIN(b) AS b FROM t2 GROUP BY a;
+
+EXPLAIN
+SELECT * FROM v1, t1 WHERE v1.b=t1.a ORDER BY v1.a;
+SELECT * FROM v1, t1 WHERE v1.b=t1.a ORDER BY v1.a;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #800085: crash with a query using a simple derived table
+--echo # (fixed by the patch for bug 798621)
+--echo #
+
+CREATE TABLE t1 (f1 int, f2 varchar(32)) ;
+INSERT INTO t1 VALUES (NULL,'j'), (8,'c');
+
+CREATE TABLE t2 (f1 int);
+INSERT INTO t2 VALUES (1), (5);
+
+SELECT DISTINCT t.f1 FROM (SELECT * FROM t1) AS t, t2
+ WHERE t.f2='s' AND t.f2 LIKE '%a%' OR t.f1<>0 ORDER BY t.f2;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG##806524: Assertion `join->best_read < 1.7976931348623157e+308 with table_elimination=on and derived_merge=on
+--echo #
+CREATE TABLE t1 ( f4 int) ;
+CREATE TABLE t2 ( f4 int) ;
+CREATE TABLE t3 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+CREATE TABLE t4 ( f2 int, f4 int) ;
+
+SELECT *
+FROM ( SELECT * FROM t1 ) AS alias1
+RIGHT JOIN (
+ t2 AS alias2
+ LEFT JOIN (
+ SELECT t4.*
+ FROM ( SELECT * FROM t3 ) AS SQ1_alias1
+ RIGHT JOIN t4
+ ON t4.f2 = SQ1_alias1.f1
+ ) AS alias3
+ ON alias3.f4 != 0
+) ON alias3.f4 != 0;
+
+drop table t1,t2,t3,t4;
+
+# The following command must be the last one the file
+set optimizer_switch=@exit_optimizer_switch;
diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test
index 93c2eb48fcd..c1a9435ef6c 100644
--- a/mysql-test/t/derived_view.test
+++ b/mysql-test/t/derived_view.test
@@ -2,6 +2,12 @@
drop table if exists t1,t2;
drop view if exists v1,v2,v3,v4;
--enable_warnings
+
+set @exit_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+# The 'default' value within the scope of this test:
+set @save_optimizer_switch=@@optimizer_switch;
+
create table t1(f1 int, f11 int);
create table t2(f2 int, f22 int);
insert into t1 values(1,1),(2,2),(3,3),(5,5),(9,9),(7,7);
@@ -235,3 +241,1025 @@ SELECT * FROM v1 JOIN t2 ON v1.f1 = t2.f1;
DROP VIEW v1;
DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #794890: abort failure on multi-update with view
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (20), (7);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (7), (9), (7);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT a FROM t1;
+
+CREATE VIEW v2 AS SELECT t2.a FROM t2, v1 WHERE t2.a=t2.a;
+UPDATE v2 SET a = 2;
+SELECT * FROM t2;
+
+UPDATE t1,v2 SET t1.a = 3;
+SELECT * FROM t1;
+
+DELETE t1 FROM t1,v2;
+SELECT * FROM t1;
+
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #802023: MIN/MAX optimization
+--echo # for mergeable derived tables and views
+--echo #
+
+CREATE TABLE t1 (a int, b int, c varchar(32), INDEX idx(a,b));
+INSERT INTO t1 VALUES
+ (7, 74, 'yyyyyyy'), (9, 97, 'aaaaaaaaa'), (2, 23, 'tt'),
+ (5, 55, 'ddddd'), (2, 27, 'ss'), (7, 76, 'xxxxxxx'),
+ (7, 79, 'zzzzzzz'), (9, 92, 'bbbbbbbbb'), (2, 25, 'pp'),
+ (5, 53, 'eeeee'), (2, 23, 'qq'), (7, 76,'wwwwwww'),
+ (7, 74, 'uuuuuuu'), (9, 92, 'ccccccccc'), (2, 25, 'oo');
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT MIN(a) FROM t1 WHERE a >= 5;
+EXPLAIN
+SELECT MIN(a) FROM t1 WHERE a >= 5;
+
+SELECT MIN(a) FROM (SELECT * FROM t1) t WHERE a >= 5;
+EXPLAIN
+SELECT MIN(a) FROM(SELECT * FROM t1) t WHERE a >= 5;
+
+SELECT MIN(a) FROM v1 WHERE a >= 5;
+EXPLAIN
+SELECT MIN(a) FROM v1 WHERE a >= 5;
+
+SELECT MAX(b) FROM t1 WHERE a=7 AND b<75;
+EXPLAIN
+SELECT MAX(b) FROM t1 WHERE a=7 AND b<75;
+
+SELECT MAX(b) FROM (SELECT * FROM t1) t WHERE a=7 AND b<75;
+EXPLAIN
+SELECT MAX(b) FROM (SELECT * FROM t1) t WHERE a=7 AND b<75;
+
+SELECT MAX(b) FROM v1 WHERE a=7 AND b<75;
+EXPLAIN
+SELECT MAX(b) FROM v1 WHERE a=7 AND b<75;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # LP bug #800535: GROUP BY query with nested left join
+--echo # and a derived table in the nest
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (1), (2);
+
+CREATE TABLE t2 (a int NOT NULL);
+INSERT INTO t2 VALUES (1), (2);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (3,3), (4,4);
+
+EXPLAIN EXTENDED
+SELECT t.a FROM t1 LEFT JOIN
+ (t2 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+ GROUP BY t.a;
+SELECT t.a FROM t1 LEFT JOIN
+ (t2 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+ GROUP BY t.a;
+
+EXPLAIN EXTENDED
+SELECT t.a FROM t1 LEFT JOIN
+ (( SELECT * FROM t2 ) t JOIN t3 ON t3.b > 5) ON t.a >= 1
+ GROUP BY t.a;
+SELECT t.a FROM t1 LEFT JOIN
+ (( SELECT * FROM t2 ) t JOIN t3 ON t3.b > 5) ON t.a >= 1
+ GROUP BY t.a;
+
+CREATE VIEW v1 AS SELECT * FROM t2;
+
+EXPLAIN EXTENDED
+SELECT t.a FROM t1 LEFT JOIN
+ (v1 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+ GROUP BY t.a;
+SELECT t.a FROM t1 LEFT JOIN
+ (v1 t JOIN t3 ON t3.b > 5) ON t.a >= 1
+ GROUP BY t.a;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #803410: materialized view/dt accessed by two-component key
+--echo #
+
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('c');
+
+CREATE TABLE t2 (a varchar(1) , KEY (a)) ;
+INSERT INTO t2 VALUES ('c'), (NULL), ('r');
+
+CREATE TABLE t3 (a varchar(1), b varchar(1));
+INSERT INTO t3 VALUES
+ ('e', 'c'), ('c', 'c'), ('c', 'r'), ('g', 'a'), ('b', 'x'), ('b', 'y'),
+ ('h', 'w'), ('d', 'z'), ('k', 'v'), ('j', 's'), ('m', 'p'), ('l', 'q');
+
+CREATE VIEW v1 AS SELECT a, MIN(b) AS b FROM t3 GROUP BY a;
+
+EXPLAIN
+SELECT * FROM t1, t2, v1 WHERE t2.a=t1.a AND t2.a=v1.a AND t2.a=v1.b;
+SELECT * FROM t1, t2, v1 WHERE t2.a=t1.a AND t2.a=v1.a AND t2.a=v1.b;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+
+--echo #
+--echo # LP bug #802845: select from derived table with limit 0
+--echo #
+
+SELECT * FROM (SELECT 1 LIMIT 0) t;
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (7), (1), (3);
+
+SELECT * FROM (SELECT * FROM t1 LIMIT 0) t;
+
+DROP TABLE t1;
+
+--echo #
+--echo # LP bug #803851: materialized view + IN->EXISTS
+--echo #
+
+SET SESSION optimizer_switch='semijoin=off,derived_with_keys=on';
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (2,2), (3,3), (1,1);
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1), (2), (1);
+
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (3), (1), (2), (1);
+
+CREATE VIEW v1 AS SELECT a, MAX(b) AS b FROM t1 GROUP BY a;
+
+EXPLAIN EXTENDED
+SELECT * FROM t3
+ WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b);
+SELECT * FROM t3
+ WHERE t3.a IN (SELECT v1.a FROM v1, t2 WHERE t2.a = v1.b);
+
+SET SESSION optimizer_switch=@save_optimizer_switch;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #804515: materialized derived + ORDER BY
+--echo #
+
+CREATE TABLE t1 (f1 varchar(1), f2 varchar(1), KEY (f2));
+INSERT INTO t1 VALUES
+ ('r','x'), ('x','d'), ('x','r'), ('r','f'), ('x','x');
+
+CREATE TABLE t2 (f1 varchar(1), f2 varchar(1));
+INSERT INTO t2 VALUES ('s','x');
+
+CREATE TABLE t3 (f1 varchar(1), f2 varchar(1), KEY (f2));
+INSERT INTO t3 VALUES
+ (NULL,'x'), (NULL,'f'), ('t','p'), (NULL,'j'), ('g','c');
+
+CREATE TABLE t4 (f1 int, f2 varchar(1), KEY (f2,f1)) ;
+INSERT INTO t4 VALUES (1,'x'), (5,'r');
+
+EXPLAIN
+SELECT t.f1 AS f
+ FROM (SELECT DISTINCT t1.* FROM t1,t2 WHERE t2.f2 = t1.f2) t,t3,t4
+ WHERE t4.f2 = t3.f2 AND t4.f2 = t.f1 ORDER BY f;
+SELECT t.f1 AS f
+ FROM (SELECT DISTINCT t1.* FROM t1,t2 WHERE t2.f2 = t1.f2) t,t3,t4
+ WHERE t4.f2 = t3.f2 AND t4.f2 = t.f1 ORDER BY f;
+
+DROP TABLE t1,t2,t3,t4;
+
+--echo #
+--echo # LP bug #806431: join over materialized derived with key
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (0,0),(3,0),(1,0);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT a,b FROM t1 ;
+
+SET SESSION optimizer_switch='derived_with_keys=off';
+SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
+SELECT * FROM t1 AS t JOIN v1 AS v WHERE t.a = v.b AND t.b = v.b;
+
+SET SESSION optimizer_switch=@save_optimizer_switch;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo #
+--echo # LP bug #806477: left join over merged join with
+--echo # where condition containing f=f
+--echo #
+
+CREATE TABLE t1 (a int NOT NULL);
+INSERT INTO t1 VALUES (1), (50), (0);
+
+CREATE TABLE t2 (a int);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (76,2), (1,NULL);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT t3.b, v1.a
+ FROM t3 LEFT JOIN (t2, v1) ON t3.a <> 0
+ WHERE v1.a = v1.a OR t3.b <> 0;
+EXPLAIN EXTENDED
+SELECT t3.b, v1.a
+ FROM t3 LEFT JOIN (t2, v1) ON t3.a <> 0
+ WHERE v1.a = v1.a OR t3.b <> 0;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #806510: subquery with outer reference
+--echo # to a derived_table/view
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (4), (NULL);
+
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (8), (0);
+
+CREATE TABLE t3 (a int, b int) ;
+INSERT INTO t3 VALUES (7,8);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT * FROM t1 t
+ WHERE EXISTS (SELECT t3.a FROM t3, t2
+ WHERE t2.a = t3.b AND t.a != 0);
+EXPLAIN
+SELECT * FROM t1 t
+ WHERE EXISTS (SELECT t3.a FROM t3, t2
+ WHERE t2.a = t3.b AND t.a != 0);
+
+SELECT * FROM (SELECT * FROM t1) t
+ WHERE EXISTS (SELECT t3.a FROM t3, t2
+ WHERE t2.a = t3.b AND t.a != 0);
+EXPLAIN
+SELECT * FROM (SELECT * FROM t1) t
+ WHERE EXISTS (SELECT t3.a FROM t3, t2
+ WHERE t2.a = t3.b AND t.a != 0);
+
+SELECT * FROM v1 t
+ WHERE EXISTS (SELECT t3.a FROM t3, t2
+ WHERE t2.a = t3.b AND t.a != 0);
+EXPLAIN
+SELECT * FROM v1 t
+ WHERE EXISTS (SELECT t3.a FROM t3, t2
+ WHERE t2.a = t3.b AND t.a != 0);
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #806097: left join over a view + DISTINCT
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (252,6), (232,0), (174,232);
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (232), (174);
+
+CREATE TABLE t3 (c int);
+INSERT INTO t3 VALUES (1), (2);
+
+CREATE VIEW v1 AS SELECT t2.a FROM t3,t2;
+
+SELECT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0;
+
+SELECT DISTINCT t2.a FROM t1 LEFT JOIN (t3,t2) ON t1.b = 0;
+EXPLAIN
+SELECT DISTINCT t2.a FROM t1 LEFT JOIN (t3,t2) ON t1.b = 0;
+
+SELECT DISTINCT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0;
+EXPLAIN
+SELECT DISTINCT v1.a FROM t1 LEFT JOIN v1 ON t1.b = 0;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #806504: right join over a view/derived table
+--echo #
+
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0);
+
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (0), (0);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #809206: DISTINCT in derived table / view
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (0);
+
+CREATE TABLE t2 (a varchar(32), b int, KEY (a)) ;
+INSERT INTO t2 VALUES
+ ('j',28), ('c',29), ('i',26), ('c',29), ('k',27),
+ ('j',28), ('c',29), ('i',25), ('d',26), ('k',27),
+ ('n',28), ('d',29), ('m',26), ('e',29), ('p',27),
+ ('w',28), ('x',29), ('y',25), ('z',26), ('s',27);
+
+
+CREATE TABLE t3 (a varchar(32));
+INSERT INTO t3 VALUES ('j'), ('c');
+
+CREATE VIEW v1 AS SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
+
+SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
+EXPLAIN
+SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a;
+
+SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t;
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT t2.b FROM t1,t2,t3 WHERE t3.a = t2.a) t;
+
+SELECT * FROM v1;
+EXPLAIN
+SELECT * FROM v1;
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #809179: right join over a derived table / view
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (6,5);
+
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (1,0);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (6,5);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT t.a,t.b FROM t3 RIGHT JOIN (t1 AS t, t2) ON t2.b != 0
+ WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+EXPLAIN EXTENDED
+SELECT t.a,t.b FROM t3 RIGHT JOIN (t1 AS t, t2) ON t2.b != 0
+ WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+
+SELECT t.a,t.b FROM t3 RIGHT JOIN ((SELECT * FROM t1) AS t, t2) ON t2.b != 0
+ WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+EXPLAIN EXTENDED
+SELECT t.a,t.b FROM t3 RIGHT JOIN ((SELECT * FROM t1) AS t, t2) ON t2.b != 0
+ WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+
+SELECT t.a,t.b FROM t3 RIGHT JOIN (v1 AS t, t2) ON t2.b != 0
+ WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+EXPLAIN EXTENDED
+SELECT t.a,t.b FROM t3 RIGHT JOIN (v1 AS t, t2) ON t2.b != 0
+ WHERE (t.a,t.b) NOT IN (SELECT 7, 5);
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #794901: insert into a multi-table view
+--echo #
+
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int);
+
+CREATE VIEW v1 AS SELECT t1.a FROM t1,t2;
+CREATE VIEW v2 AS SELECT a FROM t2 GROUP BY a;
+CREATE VIEW v3 AS SELECT v1.a FROM v1,v2;
+
+-- error ER_NON_INSERTABLE_TABLE
+INSERT INTO v3(a) VALUES (1);
+
+DROP VIEW v1,v2,v3;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #793448: materialized view accessed by two-component key
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (9,3), (2,5);
+
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (9,3), (3,7), (9,1), (2,5), (2,4), (3,8);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,3), (9,7), (9,1), (2,4);
+
+CREATE VIEW v1(a,b) AS SELECT a, MAX(b) FROM t2 GROUP BY a;
+CREATE VIEW v2(a,b) AS SELECT a,b FROM t2 UNION SELECT a,b FROM t3;
+
+SELECT * FROM v1;
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+
+SELECT * FROM v2;
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #804686: query over a derived table using a view
+--echo # with a degenerated where condition
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (0,0), (1,0), (0,0), (1,1), (1,0);
+CREATE VIEW v1 AS SELECT a,b FROM t1;
+CREATE VIEW v2 AS SELECT a, MAX(b) AS b FROM t1 GROUP BY a;
+
+SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b<>0;
+SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b<>0;
+SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b;
+SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b;
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT b FROM v1 WHERE b = 0) t WHERE b;
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT b FROM v2 WHERE b = 0) t WHERE b;
+
+DROP VIEW v1,v2;
+DROP TABLE t1;
+
+--echo #
+--echo # LP bug #819716: crash with embedded tableless materialized derived
+--echo # with a variable
+--echo #
+
+set optimizer_switch='derived_merge=off';
+EXPLAIN
+SELECT * FROM (SELECT * FROM (SELECT @b) AS t) AS s;
+SELECT * FROM (SELECT * FROM (SELECT @b) AS t) AS s;
+set optimizer_switch='derived_merge=on';
+
+--echo #
+--echo # LP bug #823826: view over join + IS NULL in WHERE
+--echo #
+
+CREATE TABLE t1 (a int) ;
+INSERT INTO t1 VALUES (1), (1);
+
+CREATE TABLE t2 (b int) ;
+INSERT INTO t2 VALUES (9), (NULL), (7);
+
+CREATE VIEW v1 AS SELECT * FROM t1,t2;
+
+EXPLAIN
+SELECT * FROM (SELECT * FROM t1,t2) t WHERE b IS NULL;
+SELECT * FROM (SELECT * FROM t1,t2) t WHERE b IS NULL;
+
+EXPLAIN
+SELECT * FROM v1 WHERE b IS NULL;
+SELECT * FROM v1 WHERE b IS NULL;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #823835: a duplicate of #823189 with derived table
+--echo #
+
+CREATE TABLE t1 (a varchar(32)) ;
+INSERT INTO t1 VALUES ('r'), ('p');
+
+CREATE TABLE t2 (a int NOT NULL, b varchar(32)) ;
+INSERT INTO t2 VALUES (28,'j');
+
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (0), (0);
+
+EXPLAIN EXTENDED
+SELECT * FROM (SELECT * FROM t1) AS t
+WHERE EXISTS (SELECT t2.a FROM t3 RIGHT JOIN t2 ON (t3.a = t2.a)
+ WHERE t2.b < t.a);
+SELECT * FROM (SELECT * FROM t1) AS t
+WHERE EXISTS (SELECT t2.a FROM t3 RIGHT JOIN t2 ON (t3.a = t2.a)
+ WHERE t2.b < t.a);
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #824463: nested outer join using a merged view
+--echo # as an inner table
+--echo #
+
+CREATE TABLE t1 (b int, a int) ;
+
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (5), (6);
+
+CREATE TABLE t3 (a int , c int) ;
+INSERT INTO t3 VALUES (22,1), (23,-1);
+
+CREATE TABLE t4 (a int);
+
+CREATE TABLE t5 (d int) ;
+INSERT INTO t5 VALUES (0), (7), (3), (5);
+
+CREATE VIEW v2 AS SELECT * FROM t2;
+CREATE VIEW v3 AS SELECT * FROM t3;
+
+EXPLAIN EXTENDED
+SELECT STRAIGHT_JOIN *
+ FROM ( t2 AS s2
+ JOIN
+ ( t3 AS s3
+ LEFT JOIN
+ ( t4 LEFT JOIN t3 ON t4.a != 0 )
+ ON s3.a != 0)
+ ON s2.a != 0)
+ JOIN t5 ON s3.c != 0 AND t5.d = 0;
+SELECT STRAIGHT_JOIN *
+ FROM ( t2 AS s2
+ JOIN
+ ( t3 AS s3
+ LEFT JOIN
+ ( t4 LEFT JOIN t3 ON t4.a != 0 )
+ ON s3.a != 0)
+ ON s2.a != 0)
+ JOIN t5 ON s3.c != 0 AND t5.d = 0;
+
+EXPLAIN EXTENDED
+SELECT STRAIGHT_JOIN *
+ FROM t2 AS s2 , t5,
+ (t3 LEFT JOIN (t4 LEFT JOIN t3 AS s3 ON t4.a != 0) ON t3.a != 0)
+ WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+SELECT STRAIGHT_JOIN *
+ FROM t2 AS s2 , t5,
+ (t3 LEFT JOIN (t4 LEFT JOIN t3 AS s3 ON t4.a != 0) ON t3.a != 0)
+ WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+
+EXPLAIN EXTENDED
+SELECT STRAIGHT_JOIN *
+ FROM v2 AS s2 , t5,
+ (t3 LEFT JOIN (t4 LEFT JOIN v3 AS s3 ON t4.a != 0) ON t3.a != 0)
+ WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+SELECT STRAIGHT_JOIN *
+ FROM v2 AS s2 , t5,
+ (t3 LEFT JOIN (t4 LEFT JOIN v3 AS s3 ON t4.a != 0) ON t3.a != 0)
+ WHERE s2.a != 0 AND t3.c != 0 AND t5.d = 0;
+
+SELECT STRAIGHT_JOIN *
+ FROM ( ( t2 AS s2
+ LEFT JOIN
+ ( t3 AS s3
+ LEFT JOIN
+ ( t4 AS s4 JOIN t3 ON s4.a != 0)
+ ON s3.a != 0 )
+ ON s2.a != 0)
+ LEFT JOIN
+ t1 AS s1
+ ON s1.a != 0)
+ JOIN t5 ON s3.c != 0;
+SELECT STRAIGHT_JOIN *
+ FROM ( ( v2 AS s2
+ LEFT JOIN
+ ( v3 AS s3
+ LEFT JOIN
+ ( t4 AS s4 JOIN v3 ON s4.a != 0)
+ ON s3.a != 0 )
+ ON s2.a != 0)
+ LEFT JOIN
+ t1 AS s1
+ ON s1.a != 0)
+ JOIN t5 ON s3.c != 0;
+
+DROP VIEW v2,v3;
+DROP TABLE t1,t2,t3,t4,t5;
+
+--echo #
+--echo # LP bug #872735: derived used in a NOT IN subquery
+--echo #
+
+CREATE TABLE t1 (b int NOT NULL);
+INSERT INTO t1 VALUES (9), (7);
+
+CREATE TABLE t2 (a int NOT NULL) ;
+INSERT INTO t2 VALUES (1), (2);
+
+CREATE TABLE t3 (
+ a int NOT NULL , c int NOT NULL, d varchar(1) NOT NULL,
+ KEY (c,a) , PRIMARY KEY (a)
+);
+INSERT INTO t3 VALUES
+ (14,4,'a'), (15,7,'b'), (16,4,'c'), (17,1,'d'), (18,9,'e'),
+ (19,4,'f'), (20,8,'g');
+
+SET SESSION optimizer_switch='derived_merge=on,subquery_cache=off';
+
+--echo # The following two EXPLAINs must return the same execution plan
+EXPLAIN
+SELECT * FROM t1 , t2
+ WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM t3 t);
+EXPLAIN
+SELECT * FROM t1 , t2
+ WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t);
+
+SELECT * FROM t1 , t2
+ WHERE (t2.a ,t1.b) NOT IN (SELECT DISTINCT c,a FROM (SELECT * FROM t3) t);
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #874006: materialized view used in IN subquery
+--echo #
+
+CREATE TABLE t3 (a int NOT NULL, b varchar(1), c varchar(1));
+INSERT INTO t3 VALUES (19,NULL,NULL), (20,'r','r');
+
+CREATE TABLE t1 (a int, b varchar(1) , c varchar(1));
+INSERT INTO t1 VALUES (1,NULL,NULL), (5,'r','r'), (7,'y','y');
+
+CREATE TABLE t2 (a int NOT NULL , b int, c varchar(1));
+INSERT INTO t2 VALUES (4,3,'r');
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #873263: materialized view used in correlated IN subquery
+--echo #
+
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (5,4), (9,8);
+
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (4,5), (5,1);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+
+DROP VIEW v2;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #877316: query over a view with correlated subquery in WHERE
+--echo #
+
+CREATE TABLE t1 (a int, b int, PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (18,2), (19,9);
+
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (10,8), (5,10);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT t1.a FROM t1
+ WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < t1.b);
+EXPLAIN
+SELECT t1.a FROM t1
+ WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < t1.b);
+
+SELECT v1.a FROM v1
+ WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < v1.b);
+EXPLAIN
+SELECT v1.a FROM v1
+ WHERE EXISTS (SELECT t2.a FROM t2 WHERE t2.b < v1.b);
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #878199: join of two materialized views
+--echo #
+
+CREATE TABLE t1 (a int, b varchar(1)) ;
+INSERT INTO t1 VALUES (7,'c'), (3,'h'), (7,'c');
+
+CREATE TABLE t2 (b varchar(1)) ;
+INSERT INTO t2 VALUES ('p'), ('c'), ('j'), ('c'), ('p');
+
+CREATE VIEW v1 AS SELECT * FROM t1 GROUP BY a,b;
+
+CREATE VIEW v2 AS SELECT * FROM t2 GROUP BY b;
+
+SET SESSION optimizer_switch = 'derived_with_keys=on';
+
+SELECT v1.a FROM v1,v2 WHERE v2.b = v1.b ORDER BY 1;
+EXPLAIN
+SELECT v1.a FROM v1,v2 WHERE v2.b = v1.b ORDER BY 1;
+
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+
+
+--echo #
+--echo # Bug #743378: join over merged view employing BNL
+--echo #
+
+CREATE TABLE t1 ( d varchar(1) NOT NULL) ;
+INSERT INTO t1 VALUES ('j'),('v'),('c');
+
+CREATE TABLE t2 (h time NOT NULL, d varchar(1) NOT NULL) ;
+INSERT INTO t2 VALUES ('05:03:03','w'),('02:59:24','d'),('00:01:58','e');
+
+CREATE TABLE t3 (
+ b int NOT NULL, e varchar(1) NOT NULL, d varchar(1) NOT NULL, KEY (e,b)
+);
+INSERT INTO t3 VALUES (4,'x','x'),(9,'w','w'),(4,'d','d'),(8,'e','e');
+
+CREATE TABLE t4 (i int NOT NULL, m varchar(1) NOT NULL) ;
+INSERT INTO t4 VALUES (8,'m'),(9,'d'),(2,'s'),(4,'r'),(8,'m');
+
+CREATE TABLE t5 (
+ a int NOT NULL, c int NOT NULL, b int NOT NULL, f date NOT NULL,
+ g date NOT NULL, h time NOT NULL, j time NOT NULL, k datetime NOT NULL
+);
+
+INSERT INTO t5 VALUES
+ (1,4,0,'0000-00-00','0000-00-00','21:22:34','21:22:34','2002-02-13 17:30'),
+ (2,6,8,'2004-09-18','2004-09-18','10:50:38','10:50:38','2008-09-27 00:34');
+
+CREATE VIEW v3 AS SELECT t3.*, t4.i FROM t3, t4, t5;
+
+SET SESSION join_cache_level = 1;
+SET SESSION join_buffer_size = 512;
+
+EXPLAIN
+SELECT t2.d FROM t1,t2,v3 WHERE v3.e = t2.d AND v3.i < 3;
+SELECT t2.d FROM t1,t2,v3 WHERE v3.e = t2.d AND v3.i < 3;
+
+SET SESSION join_cache_level = DEFAULT;
+SET SESSION join_buffer_size = DEFAULT;
+
+DROP VIEW v3;
+DROP TABLE t1,t2,t3,t4,t5;
+
+--echo #
+--echo # Bug #879882: right join within mergeable derived table
+--echo #
+
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('c'), ('a');
+
+CREATE TABLE t2 (a int, b int, c varchar(1));
+INSERT INTO t2 VALUES (29,8,'c'), (39,7,'b');
+
+CREATE TABLE t3 (b int);
+
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b AND t.c = t1.a;
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b AND t.c = t1.a;
+
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b <> 0 AND t.c = t1.a;
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b <> 0 AND t.c = t1.a;
+
+INSERT INTO t3 VALUES (100), (200);
+
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b AND t.c = t1.a;
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b AND t.c = t1.a;
+
+EXPLAIN EXTENDED
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b <> 0 AND t.c = t1.a;
+SELECT t.b, t.c, t1.a
+FROM t1, (SELECT t2.b, t2.c FROM t3 RIGHT JOIN t2 ON t2.a = t3.b) AS t
+ WHERE t.b <> 0 AND t.c = t1.a;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #880724: materialized const view as inner table of outer join
+--echo #
+
+CREATE TABLE t1 (a int, b varchar(1));
+INSERT INTO t1 VALUES (9,NULL), (6,'r'), (7,'c');
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (6);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+
+SET SESSION optimizer_switch = 'derived_with_keys=on';
+SET SESSION join_cache_level = 4;
+
+EXPLAIN
+SELECT t1.b,v2.a FROM t1 LEFT JOIN v2 ON v2.a = t1.a;
+SELECT t1.b,v2.a FROM t1 LEFT JOIN v2 ON v2.a = t1.a;
+
+CREATE TABLE t3 (a int, b varchar(1));
+INSERT INTO t3 VALUES (8,'x'), (5,'r'), (9,'y');
+
+EXPLAIN
+SELECT * FROM t3
+ WHERE t3.b <> ANY (SELECT t1.b FROM t1 LEFT JOIN v2 ON v2.a = t1.a);
+SELECT * FROM t3
+ WHERE t3.b <> ANY (SELECT t1.b FROM t1 LEFT JOIN v2 ON v2.a = t1.a);
+
+SET SESSION join_cache_level = default;
+
+DROP VIEW v2;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #881449: OUTER JOIN usin a merged view within IN subquery
+--echo #
+
+CREATE TABLE t1 (a varchar(1)) ;
+INSERT INTO t1 VALUES ('y'), ('x');
+
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (1), (2);
+
+CREATE TABLE t3 (a int, b varchar(1)) ;
+INSERT INTO t3 VALUES (1,'x');
+
+CREATE VIEW v3 AS SELECT * FROM t3;
+
+SET SESSION optimizer_switch='semijoin=on';
+
+EXPLAIN
+SELECT * FROM t1 WHERE a IN (SELECT v3.b FROM t2 RIGHT JOIN v3 ON v3.a = t2.a);
+SELECT * FROM t1 WHERE a IN (SELECT v3.b FROM t2 RIGHT JOIN v3 ON v3.a = t2.a);
+
+set optimizer_switch= @save_optimizer_switch;
+
+DROP VIEW v3;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug #874035: view as an inner table of a materialized derived
+--echo #
+
+CREATE TABLE t2 (a int NOT NULL);
+INSERT INTO t2 VALUES (7), (4);
+
+CREATE TABLE t1 (b int NOT NULL);
+INSERT INTO t1 VALUES (5), (7);
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT * FROM t1;
+
+SET SESSION optimizer_switch='derived_merge=off';
+
+PREPARE st1 FROM
+'SELECT * FROM (SELECT * FROM t2 LEFT JOIN v1 ON t2.a = v1.b) AS t';
+EXECUTE st1;
+EXECUTE st1;
+DEALLOCATE PREPARE st1;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+SET SESSION optimizer_switch='derived_merge=on';
+
+--echo #
+--echo # LP bug #879939: assertion in ha_maria::enable_indexes
+--echo # with derived_with_keys=on
+--echo #
+
+CREATE TABLE t2 (a varchar(3));
+INSERT INTO t2 VALUES ('USA'), ('USA'), ('USA'), ('USA'), ('USA');
+
+CREATE TABLE t1 (a varchar(3), b varchar(35));
+INSERT INTO t1 VALUES
+ ('USA','Lansing'), ('USA','Laredo'), ('USA','Las Vegas'),
+ ('USA','Lexington-Fayett'), ('USA','Lincoln'), ('USA','Little Rock'),
+ ('USA','Livonia'), ('USA','Long Beach'), ('USA','Los Angeles'),
+ ('USA','Louisville'), ('USA','Lowell'), ('USA','Lubbock'),
+ ('USA','Macon'), ('USA','Madison'), ('USA','Manchester'),
+ ('USA','McAllen'), ('USA','Memphis'), ('USA','Mesa'),
+ ('USA','Mesquite'), ('USA','Metairie'), ('USA','Miami');
+
+CREATE TABLE t3 (a varchar(35));
+INSERT INTO t3 VALUES ('Miami');
+
+SET optimizer_switch = 'derived_with_keys=on';
+SET @@tmp_table_size=1024*4;
+explain SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
+SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
+SET @@tmp_table_size=1024*1024*16;
+SELECT * FROM (SELECT t1.* FROM t1, t2) AS t JOIN t3 ON t3.a = t.b;
+SET @@tmp_table_size=default;
+
+drop table t1,t2,t3;
+
+--echo #
+--echo # BUG#882994: Crash in QUICK_RANGE_SELECT::reset with derived_with_keys
+--echo #
+CREATE TABLE t2 (
+ pk varchar(33),
+ col_varchar_key varchar(3) NOT NULL,
+ col_varchar_nokey varchar(52) NOT NULL);
+
+INSERT INTO t2 VALUES ('NICSpanish','NIC','Spanish'),
+ ('NERHausa','NER','Hausa'),('NGAJoruba','NGA','Joruba'),
+ ('NIUNiue','NIU','Niue'),('NFKEnglish','NFK','English'),
+ ('NORNorwegian','NOR','Norwegian'),('CIVAkan','CIV','Akan'),
+ ('OMNArabic','OMN','Arabic'),('PAKPunjabi','PAK','Punjabi'),
+ ('PLWPalau','PLW','Palau'),('PANSpanish','PAN','Spanish'),
+ ('PNGPapuan Langua','PNG','Papuan Languages'), ('PRYSpanish','PRY','Spanish'),
+ ('PERSpanish','PER','Spanish'), ('PCNPitcairnese','PCN','Pitcairnese'),
+ ('MNPPhilippene La','MNP','Philippene Langu'),('PRTPortuguese','PRT','Portuguese'),
+ ('PRISpanish','PRI','Spanish'),('POLPolish','POL','Polish'),('GNQFang','GNQ','Fang');
+
+CREATE TABLE t1 ( col_varchar_nokey varchar(52) NOT NULL ) ;
+INSERT INTO t1 VALUES ('Chinese'),('English'),('French'),('German'),
+ ('Italian'),('Japanese'),('Korean'),('Polish'),('Portuguese'),('Spanish'),
+ ('Tagalog'),('Vietnamese');
+CREATE TABLE t3 ( col_varchar_key varchar(52)) ;
+INSERT INTO t3 VALUES ('United States');
+
+set @tmp_882994= @@max_heap_table_size;
+--disable_warnings
+set max_heap_table_size=1;
+--enable_warnings
+
+SELECT *
+FROM t3 JOIN
+( SELECT t2.* FROM t1, t2 ) AS alias2
+ON ( alias2.col_varchar_nokey = t3.col_varchar_key )
+ORDER BY CONCAT(alias2.col_varchar_nokey);
+
+set max_heap_table_size= @tmp_882994;
+drop table t1,t2,t3;
+
+# The following command must be the last one the file
+set optimizer_switch=@exit_optimizer_switch;
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index c4eb6bf829e..c244d08e308 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -13,4 +13,3 @@ kill : Bug#37780 2008-12-03 HHunger need some changes to be
query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
log_tables-big : Bug#48646 2010-11-15 mattiasj report already exists
read_many_rows_innodb : Bug#37635 2010-11-15 mattiasj report already exists
-main.subselect_mat_cost : MWL#89 tests that must be adjusted to the cost model introduced after the code review
diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test
index 1cfd78143c7..186a00af16a 100644
--- a/mysql-test/t/explain.test
+++ b/mysql-test/t/explain.test
@@ -152,7 +152,7 @@ DROP TABLE t1;
--echo # explain extended crash with subquery and ONLY_FULL_GROUP_BY sql_mode
--echo #
-CREATE TABLE t1 (f1 INT);
+CREATE TABLE t1 (f1 INT not null);
SELECT @@session.sql_mode INTO @old_sql_mode;
SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
diff --git a/mysql-test/t/feedback_plugin_install.opt b/mysql-test/t/feedback_plugin_install.opt
new file mode 100644
index 00000000000..a711ae94e69
--- /dev/null
+++ b/mysql-test/t/feedback_plugin_install.opt
@@ -0,0 +1 @@
+--loose-feedback
diff --git a/mysql-test/t/feedback_plugin_install.test b/mysql-test/t/feedback_plugin_install.test
new file mode 100644
index 00000000000..81343c436c3
--- /dev/null
+++ b/mysql-test/t/feedback_plugin_install.test
@@ -0,0 +1,15 @@
+--source include/not_embedded.inc
+
+if (`select length('$FEEDBACK_SO') = 0`) {
+ skip No feedback plugin;
+}
+
+--replace_regex /\.dll/.so/
+eval install plugin feedback soname '$FEEDBACK_SO';
+select plugin_status from information_schema.plugins where plugin_name='feedback';
+--replace_result https http
+--sorted_result
+select * from information_schema.feedback where variable_name like 'feed%'
+ and variable_name not like '%_uid';
+uninstall plugin feedback;
+
diff --git a/mysql-test/t/feedback_plugin_load.opt b/mysql-test/t/feedback_plugin_load.opt
new file mode 100644
index 00000000000..5fbb2f83954
--- /dev/null
+++ b/mysql-test/t/feedback_plugin_load.opt
@@ -0,0 +1,2 @@
+--loose-feedback
+--plugin-load=$FEEDBACK_SO
diff --git a/mysql-test/t/feedback_plugin_load.test b/mysql-test/t/feedback_plugin_load.test
new file mode 100644
index 00000000000..5ad301667b4
--- /dev/null
+++ b/mysql-test/t/feedback_plugin_load.test
@@ -0,0 +1,10 @@
+if (`select count(*) = 0 from information_schema.plugins where plugin_name = 'feedback' and plugin_status='active'`)
+{
+ --skip Feedback plugin is not active
+}
+
+select plugin_status from information_schema.plugins where plugin_name='feedback';
+--replace_result https http
+--sorted_result
+select * from information_schema.feedback where variable_name like 'feed%'
+ and variable_name not like '%_uid';
diff --git a/mysql-test/t/feedback_plugin_send.test b/mysql-test/t/feedback_plugin_send.test
new file mode 100644
index 00000000000..b49c0d0e252
--- /dev/null
+++ b/mysql-test/t/feedback_plugin_send.test
@@ -0,0 +1,24 @@
+source t/feedback_plugin_load.test;
+source include/big_test.inc;
+
+if (!$MTR_FEEDBACK_PLUGIN) {
+ skip MTR_FEEDBACK_PLUGIN is not set;
+}
+
+#
+# Yep. The plugin waits 5 minutes before sending anything,
+# and there's no way to force it to send anything sooner.
+# Let's wait, and hope that mtr is started with --parallel and
+# is doing some work in other workers.
+#
+sleep 310;
+source include/restart_mysqld.inc;
+
+replace_result https http;
+perl;
+ $log_error= $ENV{'MYSQLTEST_VARDIR'} . '/log/mysqld.1.err';
+ open(LOG, '<', $log_error) or die "open(< $log_error): $!";
+ /feedback plugin:.*/ && print "$&\n" while $_=<LOG>;
+ close LOG;
+EOF
+
diff --git a/mysql-test/t/flush_read_lock_kill.test b/mysql-test/t/flush_read_lock_kill.test
index 2d359383949..ada73755067 100644
--- a/mysql-test/t/flush_read_lock_kill.test
+++ b/mysql-test/t/flush_read_lock_kill.test
@@ -57,7 +57,7 @@ connection con1;
# debug build running without our --debug=make_global..., will be
# error 0 (no error). The only important thing to test is that on
# debug builds with our --debug=make_global... we don't hang forever.
---error 0,1317,2013
+--error 0,ER_CONNECTION_KILLED,2013
reap;
connection con2;
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index 7af9d3706e6..11cb4eedf05 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -428,6 +428,8 @@ DROP TABLE t1;
CREATE TABLE t1 (a VARCHAR(255), b INT, FULLTEXT(a), KEY(b));
INSERT INTO t1 VALUES('test', 1),('test', 1),('test', 1),('test', 1),
('test', 1),('test', 2),('test', 3),('test', 4);
+INSERT INTO t1 VALUES('test', 5),('test', 6),('test', 7),('test', 8),
+ ('test', 5),('test', 6),('test', 7),('test', 8);
EXPLAIN SELECT * FROM t1
WHERE MATCH(a) AGAINST('test' IN BOOLEAN MODE) AND b=1;
diff --git a/mysql-test/t/fulltext_plugin.test b/mysql-test/t/fulltext_plugin.test
index 31978dadc51..0e2f53d5b15 100644
--- a/mysql-test/t/fulltext_plugin.test
+++ b/mysql-test/t/fulltext_plugin.test
@@ -3,7 +3,8 @@
#
# BUG#39746 - Debug flag breaks struct definition (server crash)
#
-INSTALL PLUGIN simple_parser SONAME 'mypluglib.so';
+--replace_result .dll .so
+eval INSTALL PLUGIN simple_parser SONAME '$MYPLUGLIB_SO';
CREATE TABLE t1(a TEXT, b TEXT, FULLTEXT(a) WITH PARSER simple_parser);
ALTER TABLE t1 ADD FULLTEXT(b) WITH PARSER simple_parser;
DROP TABLE t1;
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index 742b0955dca..874b26f7549 100644
--- a/mysql-test/t/func_group.test
+++ b/mysql-test/t/func_group.test
@@ -1139,6 +1139,13 @@ INSERT INTO t1 VALUES (0000),(2001);
--disable_metadata
DROP TABLE t1;
+--echo #
+--echo # LP BUG#813418 - incorrect optimisation of max/min by index for
+--echo # negated BETWEEN
+CREATE TABLE t1 (a int, KEY (a));
+INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+SELECT MAX(a) FROM t1 WHERE a NOT BETWEEN 3 AND 9;
+drop table t1;
--echo #
--echo End of 5.1 tests
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 08469b37967..febec62f037 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -563,3 +563,23 @@ SELECT 1 IN (YEAR(FROM_UNIXTIME(NULL)) ,1);
--echo #
--echo End of 5.1 tests
+
+#
+# lp:817966 int_column IN (string_constant)
+#
+# rather illogically, when BIGINT field is compared to a string,
+# the string is converted to an integer, not to a double.
+# When some other integer field (not BIGINT) is compared to a string,
+# or when the BIGINT is not a field, but an expression, both
+# operands are compared as doubles. The latter behavior is correct,
+# according to the manual.
+#
+create table t1 (a bigint, b int);
+insert t1 values (1,1),(2,2),(3,3);
+select * from t1 where a in ('2.1');
+select * from t1 where b in ('2.1');
+select * from t1 where a='2.1';
+select * from t1 where b='2.1';
+select * from t1 where IF(1,a,a)='2.1';
+drop table t1;
+
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index 2d84202c6aa..dafc9e0e0f0 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -18,6 +18,8 @@ select sec_to_time(9001),sec_to_time(9001)+0,time_to_sec("15:12:22"),
select sec_to_time(9001.1), time_to_sec('15:12:22.123456'), time_to_sec(15.5566778899);
select sec_to_time(time_to_sec('-838:59:59'));
select sec_to_time('9001.1'), sec_to_time('1234567890123.123');
+select sec_to_time(-9001.1), sec_to_time(-9001.1) / 1,
+ sec_to_time(-9001.1) / 1e0, sec_to_time(-9001) div 1;
--replace_result e+042 e+42
select sec_to_time(90011e-1), sec_to_time(1234567890123e30);
select sec_to_time(1234567890123), sec_to_time('99999999999999999999999999999');
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index 44af2ca27a2..cf648fd9b9d 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -1302,3 +1302,21 @@ DROP TABLE t1;
--echo # End of 5.1 tests
+
+--echo #
+--echo # BUG#872702: Crash in add_ref_to_table_cond() when grouping by a PK
+--echo #
+CREATE TABLE t1 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (14),(15),(16),(17),(18),(19),(20);
+
+CREATE TABLE t2 (a int) ;
+
+SELECT a
+FROM t1
+WHERE a = (
+ SELECT t2.a
+ FROM t2
+) OR t1.a = 73
+GROUP BY 1;
+DROP TABLE t1, t2;
+
diff --git a/mysql-test/t/having.test b/mysql-test/t/having.test
index 2ed8b40b858..01342fdf5fa 100644
--- a/mysql-test/t/having.test
+++ b/mysql-test/t/having.test
@@ -591,3 +591,28 @@ DROP TABLE t1,t2;
--echo End of 5.1 tests
+
+--echo #
+--echo # LP bug #791761: MAX over an empty join + HAVING
+--echo #
+
+CREATE TABLE t1 (a int, b int , KEY (b)) ;
+INSERT INTO t1 VALUES (3,1);
+
+CREATE TABLE t2 (a int NOT NULL ) ;
+INSERT INTO t2 VALUES (29);
+
+SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) <> 6;
+SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a > 0 HAVING MAX(t1.b) IS NULL;
+
+EXPLAIN
+SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6;
+SELECT MAX(t1.b) FROM t1,t2 WHERE t2.a < 0 HAVING MAX(t1.b) <> 6;
+
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (NULL);
+
+SELECT MAX(t1.b) AS f FROM t1 JOIN t2 ON t2.a != 0
+ WHERE (SELECT f3 FROM t3) <> 0 HAVING f <> 6 ;
+
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/t/index_merge_myisam.test b/mysql-test/t/index_merge_myisam.test
index 5431c6dba2b..614c6595d61 100644
--- a/mysql-test/t/index_merge_myisam.test
+++ b/mysql-test/t/index_merge_myisam.test
@@ -125,5 +125,29 @@ set optimizer_switch=default;
drop table t0, t1;
+
+--echo #
+--echo # BUG#834514 Assertion `!table || (!table->read_set || bitmap_is_set(...' with aggregates
+--echo #
+CREATE TABLE t1 ( a int , b int, c int, KEY (b), PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (1,4,0),(5,0,0),(6,7,0),(7,7,0),(8,1,0),(9,7,0),(10,1,0);
+
+CREATE TABLE t2 ( b int, c int, KEY (c,b)) ;
+INSERT INTO t2 VALUES (7,0),(1,0),(7,0),(1,0);
+
+CREATE TABLE t3 ( a int ) ;
+
+SELECT COUNT(DISTINCT t2.b), CONCAT(t1.c)
+FROM t1, t2
+WHERE (t2.c = t1.c)
+AND (
+ t1.b IN ( 4 )
+ OR t1.a = 137
+ AND EXISTS ( SELECT a FROM t3 )
+)
+GROUP BY 2;
+
+DROP TABLE t1,t2,t3;
+
set optimizer_switch= @optimizer_switch_save;
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index 2c9f84e823a..49e535aad53 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -15,6 +15,12 @@
-- source include/have_innodb.inc
+set @innodb_test_tmp=@@optimizer_switch;
+set optimizer_switch =
+ if(@innodb_test_dont_touch_optimizer_switch,
+ @@optimizer_switch,
+ 'mrr=on,mrr_sort_keys=on,index_condition_pushdown=on');
+
# Save the original values of some variables in order to be able to
# estimate how much they have changed during the tests. Previously this
# test assumed that e.g. rows_deleted is 0 here and after deleting 23
@@ -2549,6 +2555,8 @@ SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig;
-- enable_query_log
+set optimizer_switch=@innodb_test_tmp;
+
#######################################################################
# #
# Please, DO NOT TOUCH this file as well as the innodb.result file. #
diff --git a/mysql-test/t/innodb_bug878769.test b/mysql-test/t/innodb_bug878769.test
new file mode 100644
index 00000000000..157c7827dde
--- /dev/null
+++ b/mysql-test/t/innodb_bug878769.test
@@ -0,0 +1,56 @@
+--source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+
+--echo #
+--echo # Bug #878769: valgrind complains when using join cache
+--echo # to join an InnoDB table without primary key
+--echo #
+
+CREATE TABLE t1 (
+ col_int_key int(11), col_time_key time, col_varchar_key varchar(1),
+ KEY (col_int_key), KEY (col_varchar_key,col_int_key)
+) ENGINE=InnoDB;
+INSERT IGNORE INTO t1 VALUES
+ (7,'10:19:31','d'),(1,'14:40:36','r'),(7,'04:37:47','f'),(9,'19:34:06','y'),
+ (2,'00:00:00','m'),(4,'00:13:25','q'),(0,'03:47:16',NULL),(4,'01:41:48','d'),
+ (8,'00:00:00','g'),(NULL,'22:32:04','x'),(NULL,'16:44:14','f'),
+ (0,'17:38:37','p'),(NULL,'08:46:48','j'),(8,'14:11:27','c');
+
+CREATE TABLE t2 (
+ col_int_nokey int(11), col_int_key int(11),
+ col_datetime_key datetime, col_datetime_nokey datetime,
+ col_varchar_key varchar(1), col_varchar_nokey varchar(1),
+ KEY (col_int_key), KEY (col_varchar_key,col_int_key)
+);
+INSERT IGNORE INTO t2 VALUES
+ (150,62,'2008-01-03 10:33:32','2008-01-03 10:33:32','v','v'),
+ (2,1,'2007-10-09 19:53:04','2007-10-09 19:53:04',NULL,NULL),
+ (5,0,'2001-11-08 21:02:12','2001-11-08 21:02:12','x','x'),
+ (3,7,'2003-04-01 00:00','2003-04-01 00:00','i','i'),
+ (1,7,'1900-01-01 00:00','1900-01-01 00:00:00','e','e'),
+ (NULL,7,'2005-04-04 01:21','2005-04-04 01:21','s','s'),
+ (2,1,'1900-01-01 00:00','1900-01-01 00:00','j','j'),
+ (8,0,'2004-04-28 21:44','2004-04-28 21:44','a','a'),
+ (6,8,'2001-04-18 00:00','2001-04-18 00:00:00','y','y'),
+ (8,1,'2008-12-18 19:39:55','2008-12-18 19:39:55',NULL,NULL),
+ (3,1,'2000-08-01 12:19:39','2000-08-01 12:19:39','r','r'),
+ (3,9,'2004-09-25 21:29:06','2004-09-25 21:29:06','v','v');
+
+set session optimizer_switch='mrr=on,mrr_sort_keys=on';
+set session join_cache_level=6;
+
+EXPLAIN
+SELECT t1.col_time_key, t1.col_varchar_key
+ FROM t2 STRAIGHT_JOIN t1 ON t1.col_int_key = t2.col_int_key
+GROUP BY 1,2;
+SELECT t1.col_time_key, t1.col_varchar_key
+ FROM t2 STRAIGHT_JOIN t1 ON t1.col_int_key = t2.col_int_key
+GROUP BY 1,2;
+
+set session optimizer_switch=default;
+set session join_cache_level=default;
+
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/innodb_icp.test b/mysql-test/t/innodb_icp.test
index 3a4ecd3a7de..0fb42355f96 100644
--- a/mysql-test/t/innodb_icp.test
+++ b/mysql-test/t/innodb_icp.test
@@ -7,7 +7,11 @@
set @save_storage_engine= @@storage_engine;
set storage_engine=InnoDB;
+set @innodb_icp_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
--source include/icp_tests.inc
+set optimizer_switch=@innodb_icp_tmp;
set storage_engine= @save_storage_engine;
diff --git a/mysql-test/t/innodb_mrr.test b/mysql-test/t/innodb_mrr.test
index 2ae8744bca0..996ceca0d2c 100644
--- a/mysql-test/t/innodb_mrr.test
+++ b/mysql-test/t/innodb_mrr.test
@@ -7,6 +7,9 @@ drop table if exists t1,t2,t3,t4;
set @save_storage_engine= @@storage_engine;
set storage_engine=InnoDB;
+set @innodb_mrr_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
--source include/mrr_tests.inc
set storage_engine= @save_storage_engine;
@@ -417,6 +420,7 @@ DROP TABLE t1,t2;
--echo #
--echo # Testcase backport: Bug#43249
+--echo # (Note: Fixed by patch for BUG#42580)
--echo #
CREATE TABLE t1(c1 TIME NOT NULL, c2 TIME NULL, c3 DATE, PRIMARY KEY(c1), UNIQUE INDEX(c2)) engine=innodb;
INSERT INTO t1 VALUES('8:29:45',NULL,'2009-02-01');
@@ -454,4 +458,5 @@ select count(*) from (
) X;
set join_cache_level=@_save_join_cache_level;
+set optimizer_switch= @innodb_mrr_tmp;
drop table t1;
diff --git a/mysql-test/t/innodb_mrr_cpk.test b/mysql-test/t/innodb_mrr_cpk.test
index 69eeef9618f..a157ddd792f 100644
--- a/mysql-test/t/innodb_mrr_cpk.test
+++ b/mysql-test/t/innodb_mrr_cpk.test
@@ -17,6 +17,9 @@
drop table if exists t0,t1,t2,t3;
--enable_warnings
+set @innodb_mrr_cpk_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
set @save_join_cache_level=@@join_cache_level;
set join_cache_level=6;
@@ -133,5 +136,6 @@ drop table t1,t2;
set @@join_cache_level= @save_join_cache_level;
set storage_engine=@save_storage_engine;
+set optimizer_switch=@innodb_mrr_cpk_tmp;
drop table t0;
diff --git a/mysql-test/t/innodb_no_mrricp.test b/mysql-test/t/innodb_no_mrricp.test
new file mode 100644
index 00000000000..e81d5207249
--- /dev/null
+++ b/mysql-test/t/innodb_no_mrricp.test
@@ -0,0 +1,10 @@
+
+set @innodb_with_mrricp=@@optimizer_switch;
+set optimizer_switch='mrr=off,mrr_sort_keys=off,index_condition_pushdown=off';
+set @innodb_test_dont_touch_optimizer_switch=1;
+
+--source t/innodb.test
+
+set @innodb_test_dont_touch_optimizer_switch=NULL;
+set optimizer_switch=@innodb_with_mrricp;
+
diff --git a/mysql-test/t/innodb_release_row_locks_early-master.opt b/mysql-test/t/innodb_release_row_locks_early-master.opt
deleted file mode 100644
index 57ce087cd25..00000000000
--- a/mysql-test/t/innodb_release_row_locks_early-master.opt
+++ /dev/null
@@ -1 +0,0 @@
---innodb-release-locks-early=1
diff --git a/mysql-test/t/innodb_release_row_locks_early.test b/mysql-test/t/innodb_release_row_locks_early.test
deleted file mode 100644
index b4e99a1c4f8..00000000000
--- a/mysql-test/t/innodb_release_row_locks_early.test
+++ /dev/null
@@ -1,136 +0,0 @@
---source include/have_debug_sync.inc
---source include/have_innodb.inc
---source include/have_log_bin.inc
-
---disable_warnings
-DROP TABLE IF EXISTS t1;
---enable_warnings
-
-CREATE TABLE t1 (k INT NOT NULL, a INT NOT NULL, b INT NOT NULL, c INT NOT NULL, PRIMARY KEY(k)) ENGINE=InnoDB;
-INSERT INTO t1 (k, a, b, c) VALUES (1, 0, 0, 0);
-INSERT INTO t1 (k, a, b, c) VALUES (2, 0, 0, 0);
-INSERT INTO t1 (k, a, b, c) VALUES (3, 0, 0, 0);
-INSERT INTO t1 (k, a, b, c) VALUES (4, 0, 0, 0);
-
-RESET MASTER;
-SET DEBUG_SYNC= 'RESET';
-
-# Two transactions A,B that update the same row.
-# A releases row locks during the prepare phase, and waits using DEBUG_SYNC.
-# B then updates the same row.
-# Verify that
-# - B's update can proceed while A is waiting for commit, showing that
-# locks are released early.
-# - B cannot be binlogged before A.
-
-connect(c1,127.0.0.1,root,,test,$MASTER_MYPORT,);
-connect(c2,127.0.0.1,root,,test,$MASTER_MYPORT,);
-
-connection c1;
---echo # Connection c1
-# Fix binlog format (otherwise SHOW BINLOG EVENTS will fluctuate).
-SET binlog_format= mixed;
-
-# First verify that row locks are released early.
-BEGIN;
-UPDATE t1 SET a=10 WHERE k=1;
-# Wait until c2 starts COMMIT, to verify that we release our locks in prepare.
-SET DEBUG_SYNC="commit_after_release_LOCK_prepare_ordered SIGNAL c1_prepared WAIT_FOR c2_committing";
-send COMMIT;
-
- connection c2;
- --echo # Connection c2
- SET binlog_format= mixed;
- SET DEBUG_SYNC="now WAIT_FOR c1_prepared";
- BEGIN;
- SELECT * FROM t1 WHERE k=1 FOR UPDATE;
- UPDATE t1 SET a=20 WHERE k=1;
- SET DEBUG_SYNC="now SIGNAL c2_committing";
- COMMIT;
-
-connection c1;
---echo # Connection c1
-reap;
-
-# Now verify that binlog order is correct.
-BEGIN;
-UPDATE t1 SET a=10 WHERE k=2;
-# This time wait until c2 is binlogged. This should time out, as we must not
-# allow c2 to finish commit before c1.
-SET DEBUG_SYNC="commit_after_release_LOCK_prepare_ordered SIGNAL c1_prepared WAIT_FOR c2_committed TIMEOUT 2";
-send COMMIT;
-
- connection c2;
- --echo # Connection c2
- SET DEBUG_SYNC="now WAIT_FOR c1_prepared";
- BEGIN;
- SELECT * FROM t1 WHERE k=2 FOR UPDATE;
- UPDATE t1 SET a=20 WHERE k=2;
- SET DEBUG_SYNC="binlog_after_log_and_order SIGNAL c2_committed";
- send COMMIT;
-
-connection c1;
---echo # Connection c1
---echo # This should warn about DEBUG_SYNC timeout
-reap;
-
-connection c2;
---echo # Connection c2
-reap;
-
---replace_column 2 # 5 #
---replace_regex /xid=[0-9]+/xid=XX/
-SHOW BINLOG EVENTS LIMIT 2,12;
-
-
-connection c1;
---echo # Connection c1
-# Now the same thing, but using autocommit.
-RESET MASTER;
-# First verify that row locks are released early.
-# Wait until c2 starts COMMIT, to verify that we release our locks in prepare.
-SET DEBUG_SYNC="commit_after_release_LOCK_prepare_ordered SIGNAL c1_prepared WAIT_FOR c2_committing";
-send UPDATE t1 SET a=10 WHERE k=3;
-
- connection c2;
- --echo # Connection c2
- SET DEBUG_SYNC="now WAIT_FOR c1_prepared";
- SELECT * FROM t1 WHERE k=3 FOR UPDATE;
- SET DEBUG_SYNC="commit_after_release_LOCK_prepare_ordered SIGNAL c2_committing";
- UPDATE t1 SET a=20 WHERE k=3;
-
-connection c1;
---echo # Connection c1
-reap;
-
-# Now verify that binlog order is correct, this time with autocommit.
-# This time wait until c2 is binlogged. This should time out, as we must not
-# allow c2 to finish commit before c1.
-SET DEBUG_SYNC="commit_after_release_LOCK_prepare_ordered SIGNAL c1_prepared WAIT_FOR c2_committed TIMEOUT 2";
-send UPDATE t1 SET a=10 WHERE k=4;
-
- connection c2;
- --echo # Connection c2
- SET DEBUG_SYNC="now WAIT_FOR c1_prepared";
- SELECT * FROM t1 WHERE k=4 FOR UPDATE;
- SET DEBUG_SYNC="binlog_after_log_and_order SIGNAL c2_committed";
- send UPDATE t1 SET a=20 WHERE k=4;
-
-connection c1;
---echo # Connection c1
---echo # This should warn about DEBUG_SYNC timeout
-reap;
-
-connection c2;
---echo # Connection c2
-reap;
-
---replace_column 2 # 5 #
---replace_regex /xid=[0-9]+/xid=XX/
-SHOW BINLOG EVENTS LIMIT 1,12;
-
-
-SELECT * FROM t1 ORDER BY k;
-
-DROP TABLE t1;
-SET DEBUG_SYNC= 'RESET';
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index 1578f50a78b..82e67904e9f 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -2,6 +2,7 @@
# Initialization
--disable_warnings
drop table if exists t1,t2,t3;
+drop view if exists v1,v2;
--enable_warnings
#
@@ -922,6 +923,23 @@ DEALLOCATE PREPARE stmt;
DROP TABLE t1;
--echo #
+--echo # Bug LP:798597: Incorrect "Duplicate entry" error with views and
+--echo # GROUP BY
+--echo #
+
+CREATE TABLE t1 ( f1 int NOT NULL , f2 int NOT NULL ) ;
+INSERT INTO t1 VALUES (214,0),(6,6);
+CREATE TABLE t2 ( f2 int) ;
+INSERT INTO t2 VALUES (88),(88);
+CREATE ALGORITHM=MERGE VIEW v1 AS SELECT t1.f1, t2.f2 FROM (t2 LEFT JOIN t1 ON (t2.f2 <> t1.f1)) WHERE (t1.f2 <= 0) ;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT t1.f1, t2.f2 FROM (t2 LEFT JOIN t1 ON (t2.f2 <> t1.f1)) WHERE (t1.f2 <= 0 or t1.f2 is null) ;
+SELECT f1 , MIN(f2) FROM v1 GROUP BY f1;
+SELECT f1 , MIN(f2) FROM v2 GROUP BY f1;
+drop table t1,t2;
+drop view v1,v2;
+
+
+--echo #
--echo # BUG#47217 Lost optimization caused slowdown & wrong result.
--echo #
CREATE TABLE t1 (pk INT, v VARCHAR(2), PRIMARY KEY(pk));
@@ -997,3 +1015,13 @@ SELECT STRAIGHT_JOIN * FROM t1 JOIN t2 ON t2.f2 = t1.f1
DROP TABLE t1,t2;
+#
+# Item_equal used cmp_item::get_comparator() incorrectly
+#
+create table t1 (i time key);
+insert into t1 values ('1:1:1'), ('2:2:2');
+create table t2 (i time);
+insert into t2 values ('1:1:1');
+select t2.i from t1 left join t2 on t2.i = t1.i where t1.i = '1:1:1';
+drop table t1,t2;
+
diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test
index 0073d1e45b0..116f19b55eb 100644
--- a/mysql-test/t/join_cache.test
+++ b/mysql-test/t/join_cache.test
@@ -4,9 +4,13 @@ DROP DATABASE IF EXISTS world;
--enable_warnings
set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @local_join_cache_test_optimizer_switch_default=@@optimizer_switch;
set names utf8;
CREATE DATABASE world;
@@ -1216,7 +1220,9 @@ CREATE TABLE t2 (a int, b int, INDEX idx(a));
INSERT INTO t1 VALUES (5,30), (3,20), (7,40), (2,10), (8,30), (1,10), (4,20);
INSERT INTO t2 VALUES (7,10), (1,20), (2,20), (8,20), (8,10), (1,20);
INSERT INTO t2 VALUES (1,10), (4,20), (3,20), (7,20), (7,10), (1,20);
-
+INSERT INTO t2 VALUES (17,10), (11,20), (12,20), (18,20), (18,10), (11,20);
+INSERT INTO t2 VALUES (11,10), (14,20), (13,20), (17,20), (17,10), (11,20);
+
set join_buffer_size=32;
set join_cache_level=8;
@@ -1237,6 +1243,7 @@ CREATE TABLE t1 (a int NOT NULL);
INSERT INTO t1 VALUES (2), (4), (3), (5), (1);
CREATE TABLE t2 (a int NOT NULL, b int NOT NULL, INDEX i_a(a));
INSERT INTO t2 VALUES (4,10), (2,10), (2,30), (2,20), (4,20);
+INSERT INTO t2 VALUES (14,10), (12,10), (15,30), (12,20), (14,20);
EXPLAIN
SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t2.b IS NULL;
@@ -1560,6 +1567,9 @@ create table t2 (id1 int, id2 int, index idx2 (id1));
insert into t2 values
(20, 100), (30, 400), (20, 400), (30, 200), (10, 300), (10, 200), (40, 100),
(40, 200), (30, 300), (10, 400), (20, 200), (20, 300);
+insert into t2 values
+ (21, 10), (31, 400), (21, 400), (31, 200), (11, 300), (11, 200), (41, 100),
+ (41, 200), (31, 300), (11, 400), (21, 200), (21, 300);
set join_cache_level=6;
@@ -1598,14 +1608,26 @@ insert into t2 values
(30, 'bbb'), (10, 'b'), (70, 'bbbbbbb'), (60, 'bbbbbb'),
(31, 'bbb'), (11, 'b'), (71, 'bbbbbbb'), (61, 'bbbbbb'),
(32, 'bbb'), (12, 'b'), (72, 'bbbbbbb'), (62, 'bbbbbb');
+insert into t2 values
+ (130, 'bbb'), (110, 'b'), (170, 'bbbbbbb'), (160, 'bbbbbb'),
+ (131, 'bbb'), (111, 'b'), (171, 'bbbbbbb'), (161, 'bbbbbb'),
+ (132, 'bbb'), (112, 'b'), (172, 'bbbbbbb'), (162, 'bbbbbb');
insert into t3 values
(4000, 'dddd'), (3000, 'ddd'), (1000, 'd'), (8000, 'dddddddd'),
(4001, 'dddd'), (3001, 'ddd'), (1001, 'd'), (8001, 'dddddddd'),
(4002, 'dddd'), (3002, 'ddd'), (1002, 'd'), (8002, 'dddddddd');
+insert into t3 values
+ (14000, 'dddd'), (13000, 'ddd'), (11000, 'd'), (18000, 'dddddddd'),
+ (14001, 'dddd'), (13001, 'ddd'), (11001, 'd'), (18001, 'dddddddd'),
+ (4002, 'dddd'), (3002, 'ddd'), (1002, 'd'), (8002, 'dddddddd');
insert into t4 values
(200, 'cc'), (600, 'cccccc'), (300, 'ccc'), (500, 'ccccc'),
(201, 'cc'), (601, 'cccccc'), (301, 'ccc'), (501, 'ccccc'),
(202, 'cc'), (602, 'cccccc'), (302, 'ccc'), (502, 'ccccc');
+insert into t4 values
+ (1200, 'cc'), (1600, 'cccccc'), (1300, 'ccc'), (1500, 'ccccc'),
+ (1201, 'cc'), (1601, 'cccccc'), (1301, 'ccc'), (1501, 'ccccc'),
+ (1202, 'cc'), (1602, 'cccccc'), (1302, 'ccc'), (1502, 'ccccc');
--disable_result_log
--disable_warnings
@@ -2260,7 +2282,9 @@ CREATE TABLE t1 (b int);
INSERT INTO t1 VALUES (NULL),(3);
CREATE TABLE t2 (a int, b int, KEY (b));
-INSERT INTO t2 VALUES (100,NULL),(150,200);
+INSERT INTO t2 VALUES
+ (100,NULL),(150,200),(50,150),(250,350),(180,210),(100,150),
+ (101,NULL),(151,200),(51,150),(251,350),(181,210),(101,150);
set join_cache_level = 5;
explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
@@ -2288,6 +2312,7 @@ INSERT INTO t1 VALUES (NULL),("some varchar");
CREATE TABLE t2 (a int, b varchar(100), KEY (b));
INSERT INTO t2 VALUES (100,NULL),(150,"varchar"),(200,NULL),(250,"long long varchar");
+INSERT INTO t2 VALUES (100,NULL),(150,"long varchar"),(200,"varchar"),(250,"long long long varchar");
set join_cache_level = 5;
explain SELECT t2.a FROM t1 LEFT JOIN t2 ON t2.b = t1.b;
@@ -2389,6 +2414,17 @@ INSERT INTO t3 VALUES
(1,0,'2002-07-13','06:34:26','v','v'), (9,3,'2003-01-03','18:07:38','m','m'),
(1,5,'2006-04-02','13:55:23','z','z'), (3,9,'2006-10-19','20:32:28','n','n'),
(8,1,'2005-06-08','11:57:44','d','d'), (231,107,'2006-12-26','03:10:35','a','a');
+INSERT INTO t3 VALUES
+ (103,108,'2008-12-04','00:00:00','a','v'), (103,108,'2009-03-28','00:00:00','b','f'),
+ (103,105,'1900-01-01','00:55:47','c','v'), (102,108,'2009-10-02','00:00:00','d','s'),
+ (100,108,'1900-01-01','20:51:59','e','a'), (100,106,'2008-06-04','09:47:27','f','p'),
+ (108,107,'2009-01-13','21:58:29','g','z'), (105,102,'1900-01-01','22:45:53','h','a'),
+ (109,105,'2008-01-28','14:06:48','i','h'), (105,107,'2004-09-18','22:17:16','j','h'),
+ (104,102,'2006-10-14','14:59:37','k','v'), (102,109,'1900-01-01','23:37:40','l','v'),
+ (1033,1142,'2000-11-28','14:14:01','m','b'), (105,103,'2008-04-04','02:54:19','n','y'),
+ (100,100,'2002-07-13','06:34:26','o','v'), (109,103,'2003-01-03','18:07:38','p','m'),
+ (100,105,'2006-04-02','13:55:23','q','z'), (103,109,'2006-10-19','20:32:28','s','n'),
+ (108,100,'2005-06-08','11:57:44','t','d'), (1231,1107,'2006-12-26','03:10:35','v','a');
CREATE TABLE t1 SELECT * FROM t3;
DELETE FROM t1 WHERE i > 8;
@@ -2421,7 +2457,15 @@ CREATE TABLE t1 (
INSERT INTO t1 VALUES
(10,8,'v'), (11,8,'f'), (12,5,'v'), (13,8,'s'), (14,8,'a'),
(15,6,'p'), (16,7,'z'), (17,2,'a'), (18,5,'h'), (19,7,'h'),
- (25,3,'m'), (26,5,'z'), (27,9,'n'), (28,1,'d'), (29,107,'a');
+ (25,3,'m'), (26,5,'a'), (27,9,'n'), (28,1,'d'), (29,107,'a');
+INSERT INTO t1 VALUES
+ (110,8,'x'), (111,8,'y'), (112,5,'v'), (113,8,'z'), (114,8,'i'),
+ (115,6,'j'), (116,7,'t'), (117,2,'b'), (118,5,'j'), (119,7,'w'),
+ (125,3,'q'), (126,5,'o'), (127,9,'n'), (128,1,'e'), (129,107,'c');
+INSERT INTO t1 VALUES
+ (210,8,'b'), (211,8,'c'), (212,5,'d'), (213,8,'e'), (214,8,'g'),
+ (215,6,'f'), (216,7,'h'), (217,2,'i'), (218,5,'j'), (219,7,'k'),
+ (225,3,'l'), (226,5,'m'), (227,9,'n'), (228,1,'o'), (229,107,'p');
CREATE TABLE t2 (
pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
@@ -2431,7 +2475,7 @@ INSERT INTO t2 VALUES
(10,8,'v'), (11,8,'f'), (12,5,'v'), (13,8,'s'), (14,8,'a'),
(15,6,'p'), (16,7,'z'), (17,2,'a'), (18,5,'h'), (19,7,'h'),
(20,2,'v'), (21,9,'v'), (22,142,'b'), (23,3,'y'), (24,0,'v'),
- (25,3,'m'), (26,5,'z'), (27,9,'n'), (28,1,'d'), (29,107,'a');
+ (25,3,'m'), (26,5,'b'), (27,9,'n'), (28,1,'d'), (29,107,'a');
CREATE TABLE t3 (
pk int NOT NULL, i int NOT NULL, v varchar(1) NOT NULL,
@@ -2445,23 +2489,29 @@ INSERT INTO t3 VALUES
SET SESSION join_cache_level=1;
EXPLAIN
-SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
-SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
SET SESSION join_cache_level=6;
EXPLAIN
-SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
-SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
SET SESSION join_cache_level=4;
EXPLAIN
-SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
-SELECT t2.v FROM t1, t2, t3 WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v
+SELECT t2.v FROM t1, t2, t3
+WHERE t3.v <> t2.v AND t3.pk = t2.i AND t1.v = t3.v AND t1.pk*2<100
GROUP BY t2.v ORDER BY t1.pk,t2.v;
DROP TABLE t1,t2,t3;
@@ -2527,6 +2577,11 @@ INSERT INTO t2 VALUES
(1, 12, 102), (8, 81, 801), (7, 70, 700), (12, 120, 1200),
(8, 82, 802), (1, 13, 103), (1, 14, 104), (3, 31, 301),
(1, 15, 105), (8, 83, 803), (7, 71, 701);
+INSERT INTO t2 VALUES
+ (108, 80, 800), (101, 10, 100), (101, 11, 101), (103, 30, 300),
+ (101, 12, 102), (108, 81, 801), (107, 70, 700), (1012, 120, 1200),
+ (108, 82, 802), (101, 13, 103), (101, 14, 104), (103, 31, 301),
+ (101, 15, 105), (108, 83, 803), (107, 71, 701);
SET SESSION join_cache_level = 4;
SET SESSION join_buffer_size = 192;
@@ -2563,6 +2618,12 @@ INSERT INTO t2 VALUES
('abcdefjhjk',1015414784), ('or',4), ('now',0), ('abcdefjhjk',-32702464),
('abcdefjhjk',4), ('time',1078394880), ('f',4), ('m',-1845559296),
('ff', 5), ('abcdefjhjk',-1074397184);
+INSERT INTO t2 VALUES
+ ('dig',5), ('were',-1631322112), ('is',3), ('abcdefjhjl',3),
+ ('abcdefjh',4), ('told',-824573952), ('tt',0),('vv',-1711013888),
+ ('abcdefjhjj',1015414784), ('and',4), ('here',0), ('abcdefjhjm',-32702464),
+ ('abcdefjhji',4), ('space',1078394880), ('fs',4), ('mn',-1845559296),
+ ('fq', 5), ('abcdefjhjp',-1074397184);
EXPLAIN
SELECT t1.v,t2.i FROM t1,t2 WHERE t2.v = t1.v;
@@ -2610,6 +2671,13 @@ INSERT INTO t2 VALUES
(11,6,'yes'), (12,NULL,'will'), (13,NULL,'o'), (14,NULL,'k'), (15,NULL,'she'),
(16,-1450835968,'abcdefjhjkl'), (17,-975831040,'abcdefjhjkl'), (18,NULL,'z'),
(19,-343932928,'t');
+INSERT INTO t2 VALUES
+ (101,6,'yes'), (102,NULL,'will'), (103,NULL,'o'), (104,NULL,'k'), (105,NULL,'she'),
+ (106,-1450835968,'abcdefjhjkl'), (107,-975831040,'abcdefjhjkl'), (108,NULL,'z'),
+ (100,-343932928,'t'),
+ (111,6,'yes'), (112,NULL,'will'), (113,NULL,'o'), (114,NULL,'k'), (115,NULL,'she'),
+ (116,-1450835968,'abcdefjhjkl'), (117,-975831040,'abcdefjhjkl'), (118,NULL,'z'),
+ (119,-343932928,'t');
CREATE TABLE t3 (
pk int NOT NULL PRIMARY KEY,
@@ -2626,6 +2694,15 @@ INSERT INTO t3 VALUES
(26,NULL,'all'), (27,1443168256,'c'), (28,1427046400,'right'),
(31,7,'abcdefjhjkl'), (32,6,'y'), (33,NULL,'to'), (34,7,'n'), (35,7,'look'),
(36,NULL,'all'), (37,1443168256,'c'), (38,1427046400,'right');
+INSERT INTO t3 VALUES
+(101,7,'abcdefjhjkl'),(102,6,'y'), (103,NULL,'to'),(104,7,'n'),(105,7,'look'),
+(106,NULL,'all'), (107,1443168256,'c'), (108,1427046400,'right'),
+(111,7,'abcdefjhjkl'), (112,6,'y'), (113,NULL,'to'), (114,7,'n'), (115,7,'look'),
+(116,NULL,'all'), (117,1443168256,'c'), (118,1427046400,'right'),
+(121,7,'abcdefjhjkl'), (122,6,'y'), (123,NULL,'to'), (124,7,'n'), (125,7,'look'),
+(126,NULL,'all'), (127,1443168256,'c'), (128,1427046400,'right'),
+(131,7,'abcdefjhjkl'), (132,6,'y'), (133,NULL,'to'), (134,7,'n'), (135,7,'look'),
+(136,NULL,'all'), (137,1443168256,'c'), (138,1427046400,'right');
SET SESSION join_buffer_size = 192;
@@ -2661,6 +2738,10 @@ INSERT INTO t2 VALUES
(10, 'a'), (20, 'c'), (30, 'aa'), (4, 'bb'),
(11, 'a'), (21, 'c'), (31, 'aa'), (41, 'cc'),
(12, 'a'), (22, 'c'), (32, 'bb'), (42, 'aa');
+INSERT INTO t2 VALUES
+ (110, 'a'), (120, 'c'), (130, 'aa'), (14, 'bb'),
+ (111, 'a'), (121, 'c'), (131, 'aa'), (141, 'cc'),
+ (112, 'a'), (122, 'c'), (132, 'bb'), (142, 'aa');
SELECT * FROM t1,t2 WHERE t2.a=t1.a;
@@ -2762,6 +2843,9 @@ INSERT IGNORE INTO t3 VALUES (9,0,0,2), (1,0,0,7);
CREATE TABLE t4 (pk int, a4 int, INDEX idx(a4)) ;
INSERT IGNORE INTO t4 VALUES (2,NULL), (8,0);
+INSERT IGNORE INTO t4 VALUES (12,10), (18,20);
+INSERT IGNORE INTO t4 VALUES (22,11), (28,21);
+INSERT IGNORE INTO t4 VALUES (32,12), (38,22);
CREATE TABLE t5 (pk int, a5 int) ;
INSERT IGNORE INTO t5 VALUES (2,0), (8,0);
@@ -2937,7 +3021,10 @@ INSERT INTO t1 VALUES
INSERT INTO t2 VALUES
(1,'Bbbb'), (2,'BBB'), (3,'bbbb'), (4,'AaA'), (5,'CC'),
(6,'cC'), (7,'CCC'), (8,'AAA'), (9,'bBbB'), (10,'aaaa'),
- (11,'a'), (12,'dd'), (13,'EE'), (14,'ee'), (15,'D');
+ (11,'a'), (12,'dd'), (13,'EE'), (14,'ee'), (15,'D'),
+ (101,'Bbbb'), (102,'BBB'), (103,'bbbb'), (104,'AaA'), (105,'CC'),
+ (106,'cC'), (107,'CCC'), (108,'AAA'), (109,'bBbB'), (110,'aaaa'),
+ (111,'a'), (112,'dd'), (113,'EE'), (114,'ee'), (115,'D');
SET SESSION join_cache_level = 4;
@@ -2980,7 +3067,7 @@ SELECT * FROM t1,t2
WHERE t1.f1 = t2.f4 AND (t1.f3 = 1 AND t2.f3 = 4 OR t1.f3 = 2 AND t2.f3 = 6);
SET SESSION join_cache_level = DEFAULT;
-SET SESSION optimizer_switch = DEFAULT;
+SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default;
DROP TABLE t1,t2;
@@ -3006,7 +3093,7 @@ EXPLAIN SELECT * FROM t1,t2
WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0, 100) ORDER BY t1.f2 LIMIT 1;
SELECT * FROM t1,t2
WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1;
-SET SESSION optimizer_switch = DEFAULT;
+SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default;
SET SESSION optimizer_switch = 'index_condition_pushdown=on';
EXPLAIN SELECT * FROM t1,t2
@@ -3014,7 +3101,7 @@ EXPLAIN SELECT * FROM t1,t2
SELECT * FROM t1,t2
WHERE t2.f3 = t1.f2 AND t1.f1 IN (9, 0 ,100) ORDER BY t1.f2 LIMIT 1;
-SET SESSION optimizer_switch = DEFAULT;
+SET SESSION optimizer_switch = @local_join_cache_test_optimizer_switch_default;
DROP TABLE t1,t2;
@@ -3059,7 +3146,10 @@ CREATE TABLE t2 ( f1 varchar(10) , f2 int(11) , KEY (f1));
INSERT INTO t2 VALUES
('hgtofubn',1), ('GDOXZ',91), ('n',2), ('fggxgalh',88),
('hgtofu',1), ('GDO',101), ('n',3), ('fggxga',55),
- ('hgtofu',3), ('GDO',33), ('nn',3), ('fggxgarrr',77);
+ ('hgtofu',3), ('GDO',33), ('nn',3), ('fggxgarrr',77),
+ ('jgtofu',3), ('JDO',33), ('mn',3), ('jggxgarrr',77),
+ ('igtofu',3), ('IDO',33), ('ln',3), ('iggxgarrr',77);
+
SET SESSION join_cache_level=3;
@@ -3081,7 +3171,9 @@ INSERT INTO t1 VALUES ('o'), ('u');
CREATE TABLE t2 (a int, v varchar(1), INDEX idx (v)) ;
INSERT INTO t2 VALUES
(8,NULL), (10,'b'), (5,'k'), (4,NULL),
- (1,NULL), (11,'u'), (7,NULL), (2,'d');
+ (1,NULL), (11,'u'), (7,NULL), (2,'d'),
+ (18,'u'), (11,'b'), (15,'k'), (12,'d'),
+ (18,'x'), (11,'y'), (15,'l'), (12,'e');
SET SESSION join_buffer_size = 255;
@@ -3100,5 +3192,38 @@ SET SESSION join_buffer_size = DEFAULT;
DROP TABLE t1,t2;
+--echo #
+--echo # Bug #802860: crash on join cache + derived + duplicate_weedout
+--echo #
+
+SET SESSION optimizer_switch=
+ 'semijoin=on,materialization=off,firstmatch=off,loosescan=off,derived_with_keys=on';
+
+CREATE TABLE t1 (a int) ;
+INSERT IGNORE INTO t1 VALUES (0), (1), (0);
+
+CREATE TABLE t2 (a int) ;
+INSERT IGNORE INTO t2 VALUES (0), (3), (0), (2);
+
+SET SESSION join_cache_level = 0;
+
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+ WHERE t.a IN (SELECT t2.a FROM t2);
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+ WHERE t.a IN (SELECT t2.a FROM t2);
+
+SET SESSION join_cache_level = 1;
+
+EXPLAIN
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+ WHERE t.a IN (SELECT t2.a FROM t2);
+SELECT * FROM (SELECT DISTINCT * FROM t1) t
+ WHERE t.a IN (SELECT t2.a FROM t2);
+
+SET SESSION join_cache_level = DEFAULT;
+
+DROP TABLE t1, t2;
+
# this must be the last command in the file
set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/join_nested.test b/mysql-test/t/join_nested.test
index e36d861f8bb..b617331de38 100644
--- a/mysql-test/t/join_nested.test
+++ b/mysql-test/t/join_nested.test
@@ -454,6 +454,7 @@ SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
ON t3.a=1 AND t2.b=t4.b
WHERE t1.a <= 2;
+INSERT INTO t2 VALUES (-1,9,0), (-3,10,0), (-2,8,0), (-4,11,0), (-5,15,0);
CREATE INDEX idx_b ON t2(b);
EXPLAIN EXTENDED
@@ -461,12 +462,12 @@ SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
(t1,t2)
- ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
+ ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0;
SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b
FROM (t3,t4)
LEFT JOIN
(t1,t2)
- ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b;
+ ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0;
EXPLAIN EXTENDED
SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
@@ -477,7 +478,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t2
LEFT JOIN
(t3, t4)
- ON t3.a=1 AND t2.b=t4.b,
+ ON t3.a=1 AND t2.b=t4.b AND t2.a>0,
t5
LEFT JOIN
(
@@ -504,6 +505,8 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
(t8.b=t9.b OR t8.c IS NULL) AND
(t9.a=1);
+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);
CREATE INDEX idx_b ON t5(b);
@@ -516,7 +519,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t2
LEFT JOIN
(t3, t4)
- ON t3.a=1 AND t2.b=t4.b,
+ ON t3.a=1 AND t2.b=t4.b AND t2.a>0 AND t4.a>0,
t5
LEFT JOIN
(
@@ -525,7 +528,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t8
ON t7.b=t8.b AND t6.b < 10
)
- ON t6.b >= 2 AND t5.b=t7.b
+ ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
@@ -543,6 +546,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
(t8.b=t9.b OR t8.c IS NULL) AND
(t9.a=1);
+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
@@ -554,16 +558,16 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
t2
LEFT JOIN
(t3, t4)
- ON t3.a=1 AND t2.b=t4.b,
+ ON t3.a=1 AND t2.b=t4.b AND t2.a>0 AND t4.a>0,
t5
LEFT JOIN
(
(t6, t7)
LEFT JOIN
t8
- ON t7.b=t8.b AND t6.b < 10
+ ON t7.b=t8.b AND t6.b < 10 AND t8.a>=0
)
- ON t6.b >= 2 AND t5.b=t7.b
+ ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
@@ -581,6 +585,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
(t8.b=t9.b OR t8.c IS NULL) AND
(t9.a=1);
+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);
@@ -606,7 +611,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
- (t1.a != 2),
+ (t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -641,7 +646,7 @@ SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,
)
ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND
(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND
- (t1.a != 2),
+ (t1.a != 2) AND t1.a>0,
t9
WHERE t0.a=1 AND
t0.b=t1.b AND
@@ -1236,5 +1241,35 @@ SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a
DROP TABLE t1, t2, t3;
+#
+# LP BUG#817360: Nested left joins + not-exist optimization
+#
+
+CREATE TABLE t1 (a int NOT NULL );
+INSERT INTO t1 VALUES (9), (9);
+
+CREATE TABLE t2 (a int NOT NULL );
+INSERT INTO t2 VALUES (9);
+
+CREATE TABLE t3 (a int NOT NULL, b int);
+INSERT INTO t3 VALUES (19,9);
+
+CREATE TABLE t4 (b int) ;
+
+SELECT * FROM t1 LEFT JOIN
+ ((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ ON t1.a=t2.a;
+SELECT * FROM t1 LEFT JOIN
+ ((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ ON t1.a=t2.a
+ WHERE t3.a IS NULL;
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN
+ ((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b)
+ ON t1.a=t2.a
+ WHERE t3.a IS NULL;
+
+DROP TABLE t1,t2,t3,t4;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/join_nested_jcl6.test b/mysql-test/t/join_nested_jcl6.test
index 5737cfe115f..809755b1fbf 100644
--- a/mysql-test/t/join_nested_jcl6.test
+++ b/mysql-test/t/join_nested_jcl6.test
@@ -3,8 +3,10 @@
#
set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
+set @@optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set join_cache_level=6;
show variables like 'join_cache_level';
@@ -24,6 +26,9 @@ INSERT INTO t5 VALUES (1,1,0), (2,2,0), (3,3,0);
INSERT INTO t6 VALUES (1,2,0), (3,2,0), (6,1,0);
INSERT INTO t7 VALUES (1,1,0), (2,2,0);
INSERT INTO t8 VALUES (0,2,0), (1,2,0);
+INSERT INTO t6 VALUES (-1,12,0), (-3,13,0), (-6,11,0), (-4,14,0);
+INSERT INTO t7 VALUES (-1,11,0), (-2,12,0), (-3,13,0), (-4,14,0), (-5,15,0);
+INSERT INTO t8 VALUES (-3,13,0), (-1,12,0), (-2,14,0), (-5,15,0), (-4,16,0);
EXPLAIN
SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
@@ -33,10 +38,10 @@ SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
(t6, t7)
LEFT JOIN
t8
- ON t7.b=t8.b AND t6.b < 10
+ ON t7.b=t8.b AND t6.b < 10
)
ON t6.b >= 2 AND t5.b=t7.b AND
- (t8.a > 0 OR t8.c IS NULL);
+ (t8.a > 0 OR t8.c IS NULL) AND t6.a>0 AND t7.a>0;
SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
FROM t5
@@ -48,7 +53,7 @@ SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b
ON t7.b=t8.b AND t6.b < 10
)
ON t6.b >= 2 AND t5.b=t7.b AND
- (t8.a > 0 OR t8.c IS NULL);
+ (t8.a > 0 OR t8.c IS NULL) AND t6.a>0 AND t7.a>0;
DELETE FROM t5;
DELETE FROM t6;
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index 28526a30ae7..f88759c7b67 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -1064,6 +1064,8 @@ insert into t2 select if(t1.a is null, 10, t1.a) from t1;
create table t3 (a int, b int, index idx(a));
insert into t3 values (1, 100), (3, 301), (4, 402), (1, 102), (1, 101);
+insert into t3 values (11, 100), (33, 301), (44, 402), (11, 102), (11, 101);
+insert into t3 values (22, 100), (53, 301), (64, 402), (22, 102), (22, 101);
analyze table t1,t2,t3;
@@ -1106,3 +1108,104 @@ GROUP BY t2.f1, t2.f2;
DROP TABLE t1,t2;
--echo End of 5.1 tests
+
+--echo #
+--echo # LP bug #813447: LEFT JOIN with single-row inner table and
+--echo # a subquery in ON expression
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0);
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (0);
+
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (0), (0);
+
+SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3);
+EXPLAIN EXTENDED
+SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3);
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #817384 Wrong result with outer join + subquery in ON
+--echo # clause +unique key
+--echo #
+
+CREATE TABLE t1 ( c int NOT NULL , b char(1) NOT NULL ) ;
+INSERT INTO t1 VALUES (1,'b');
+
+CREATE TABLE t2 ( a int NOT NULL , b char(1) NOT NULL , PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (1,'a');
+
+create table t3 (c1 char(1), c2 char(2));
+insert into t3 values ('c','d');
+insert into t3 values ('c','d');
+
+
+EXPLAIN SELECT t2.b
+FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3);
+SELECT t2.b
+FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3);
+
+EXPLAIN SELECT t2.b
+FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1;
+SELECT t2.b
+FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #825035: second execution of PS with outer join
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (1),(2),(3),(4);
+
+CREATE TABLE t2 (a int);
+
+PREPARE stmt FROM
+"SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a";
+
+EXECUTE stmt;
+EXECUTE stmt;
+
+DEALLOCATE PREPARE stmt;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #838633: second execution of PS with outer join
+--echo # converted to inner join
+--echo #
+
+CREATE TABLE t1 ( b int NOT NULL ) ;
+INSERT INTO t1 VALUES (9),(10);
+
+CREATE TABLE t2 ( b int NOT NULL, PRIMARY KEY (b)) ;
+INSERT INTO t2 VALUES
+ (75),(76),(77),(78),(79),(80),(81),(82),(83),(84),(85),(86),(87),(88),(89),
+ (10), (90),(91),(92),(93),(94),(95),(96),(97),(98),(99),(100);
+
+CREATE TABLE t3 ( a int, b int NOT NULL , PRIMARY KEY (b)) ;
+INSERT INTO t3 VALUES
+ (0,6),(0,7),(0,8),(2,9),(0,10),(2,21),(0,22),(2,23),(2,24),(2,25);
+
+SET SESSION join_cache_level=4;
+
+EXPLAIN EXTENDED
+SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b;
+
+PREPARE stmt FROM
+'SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b';
+
+EXECUTE stmt;
+EXECUTE stmt;
+
+DEALLOCATE PREPARE stmt;
+
+SET SESSION join_cache_level=default;
+
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/t/join_outer_jcl6.test b/mysql-test/t/join_outer_jcl6.test
index be98e7503ad..025e44493af 100644
--- a/mysql-test/t/join_outer_jcl6.test
+++ b/mysql-test/t/join_outer_jcl6.test
@@ -3,8 +3,10 @@
#
set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set join_cache_level=6;
show variables like 'join_cache_level';
diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test
index b199a1224c3..f51b9723142 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -99,7 +99,7 @@ select ((@id := kill_id) - kill_id) from t3;
kill @id;
connection conn1;
--- error 1317,2013
+-- error ER_QUERY_INTERRUPTED,ER_CONNECTION_KILLED,2013
reap;
connection default;
@@ -337,5 +337,35 @@ SELECT 1;
###########################################################################
+--echo #
+--echo # Test kill USER
+--echo #
+
+grant ALL on test.* to test@localhost;
+grant ALL on test.* to test2@localhost;
+connect (con3, localhost, test,,);
+connect (con4, localhost, test2,,);
+connection default;
+--enable_info
+kill hard query user test2@nohost;
+kill soft query user test@localhost;
+kill hard query user test@localhost;
+kill soft connection user test2;
+kill hard connection user test@localhost;
+--disable_info
+revoke all privileges on test.* from test@localhost;
+revoke all privileges on test.* from test2@localhost;
+drop user test@localhost;
+drop user test2@localhost;
+
+connection con3;
+--error 2013,2006
+select 1;
+connection con4;
+--error 2013,2006
+select 1;
+connection default;
+
+
# Restore global concurrent_insert value. Keep in the end of the test file.
set @@global.concurrent_insert= @old_concurrent_insert;
diff --git a/mysql-test/t/maria_icp.test b/mysql-test/t/maria_icp.test
index beb13544ced..d8af34daf2e 100644
--- a/mysql-test/t/maria_icp.test
+++ b/mysql-test/t/maria_icp.test
@@ -6,8 +6,12 @@
set @save_storage_engine= @@storage_engine;
set storage_engine=Maria;
+set @maria_icp_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
--source include/icp_tests.inc
set storage_engine= @save_storage_engine;
+set optimizer_switch=@maria_icp_tmp;
+
diff --git a/mysql-test/t/maria_mrr.test b/mysql-test/t/maria_mrr.test
index 233186fe5bd..4cd4c277a7f 100644
--- a/mysql-test/t/maria_mrr.test
+++ b/mysql-test/t/maria_mrr.test
@@ -7,6 +7,9 @@
drop table if exists t1,t2,t3,t4;
--enable_warnings
+set @maria_mrr_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
set @mrr_buffer_size_save= @@mrr_buffer_size;
set @save_storage_engine= @@storage_engine;
@@ -71,7 +74,9 @@ CREATE TABLE t3(
PRIMARY KEY (pk), INDEX idx (v, i)
) ENGINE=ARIA;
INSERT INTO t3 SELECT * FROM t1;
-INSERT INTO t3 VALUES (88, 442, 'y'), (99, 445, 'w') ;
+INSERT INTO t3 VALUES
+ (88, 442, 'y'), (99, 445, 'w'), (87, 442, 'z'), (98, 445, 'v'), (86, 442, 'x'),
+ (97, 445, 't'), (85, 442, 'b'), (96, 445, 'l'), (84, 442, 'a'), (95, 445, 'k');
SELECT COUNT(t1.v) FROM t1, t2 IGNORE INDEX (idx), t3 IGNORE INDEX (idx)
WHERE t3.v = t2.v AND t3.i < t2.i AND t3.pk > 0 AND t2.pk > 0;
@@ -102,11 +107,8 @@ CREATE TABLE t1 (
) ENGINE=Aria;
INSERT INTO t1 VALUES
-(1,'z'),
-(2,'abcdefjhjkl'),
-(3,'in'),
-(4,'abcdefjhjkl'),
-(6,'abcdefjhjkl');
+ (1,'z'), (2,'abcdefjhjkl'), (3,'in'), (4,'abcdefjhjkl'), (6,'abcdefjhjkl'),
+ (11,'zx'), (12,'abcdefjhjm'), (13,'jn'), (14,'abcdefjhjp'), (16,'abcdefjhjr');
CREATE TABLE t2 (
col_varchar_10_latin1 varchar(10) DEFAULT NULL
@@ -201,4 +203,6 @@ WHERE
set join_cache_level=@_save_join_cache_level;
set join_buffer_size=@_save_join_buffer_size;
+set optimizer_switch=@maria_mrr_tmp;
+
drop table t1;
diff --git a/mysql-test/t/mrr_icp_extra.test b/mysql-test/t/mrr_icp_extra.test
new file mode 100644
index 00000000000..f1b21154449
--- /dev/null
+++ b/mysql-test/t/mrr_icp_extra.test
@@ -0,0 +1,239 @@
+
+set @mrr_icp_extra_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+SET NAMES latin1;
+CREATE TABLE t1
+(s1 char(10) COLLATE latin1_german1_ci,
+ s2 char(10) COLLATE latin1_swedish_ci,
+ KEY(s1),
+ KEY(s2));
+
+INSERT INTO t1 VALUES ('a','a');
+INSERT INTO t1 VALUES ('b','b');
+INSERT INTO t1 VALUES ('c','c');
+INSERT INTO t1 VALUES ('d','d');
+INSERT INTO t1 VALUES ('e','e');
+INSERT INTO t1 VALUES ('f','f');
+INSERT INTO t1 VALUES ('g','g');
+INSERT INTO t1 VALUES ('h','h');
+INSERT INTO t1 VALUES ('i','i');
+INSERT INTO t1 VALUES ('j','j');
+
+EXPLAIN SELECT * FROM t1 WHERE s1='a';
+EXPLAIN SELECT * FROM t1 WHERE s2='a';
+EXPLAIN SELECT * FROM t1 WHERE s1='a' COLLATE latin1_german1_ci;
+EXPLAIN SELECT * FROM t1 WHERE s2='a' COLLATE latin1_german1_ci;
+
+EXPLAIN SELECT * FROM t1 WHERE s1 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci;
+EXPLAIN SELECT * FROM t1 WHERE s2 BETWEEN 'a' AND 'b' COLLATE latin1_german1_ci;
+
+EXPLAIN SELECT * FROM t1 WHERE s1 IN ('a','b' COLLATE latin1_german1_ci);
+EXPLAIN SELECT * FROM t1 WHERE s2 IN ('a','b' COLLATE latin1_german1_ci);
+
+EXPLAIN SELECT * FROM t1 WHERE s1 LIKE 'a' COLLATE latin1_german1_ci;
+EXPLAIN SELECT * FROM t1 WHERE s2 LIKE 'a' COLLATE latin1_german1_ci;
+
+DROP TABLE t1;
+
+--echo #
+--echo #
+
+CREATE TABLE t2 (a varchar(32), b int(11), c float, d double,
+UNIQUE KEY a (a,b,c), KEY b (b), KEY c (c));
+CREATE TABLE t1 (a varchar(32), b char(3), UNIQUE KEY a (a,b), KEY b (b));
+CREATE TABLE t3 (a varchar(32), b char(3), UNIQUE KEY a (a,b));
+INSERT INTO t3 SELECT * FROM t1;
+EXPLAIN
+SELECT d FROM t1, t2
+WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
+ORDER BY t2.c LIMIT 1;
+SELECT d FROM t1, t2
+WHERE t2.b=14 AND t2.a=t1.a AND 5.1<t2.c AND t1.b='DE'
+ORDER BY t2.c LIMIT 1;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo #
+create table t1(a int, b int, index(b));
+insert into t1 values (2, 1), (1, 1), (4, NULL), (3, NULL), (6, 2), (5, 2);
+insert into t1 values (2, 11), (1, 11), (4, 14), (3, 14), (6, 12), (5, 12);
+explain select * from t1 where b=1 or b is null order by a;
+select * from t1 where b=1 or b is null order by a;
+explain select * from t1 where b=2 or b is null order by a;
+select * from t1 where b=2 or b is null order by a;
+drop table t1;
+
+--echo #
+--echo #
+CREATE TABLE t1 (
+FieldKey varchar(36) NOT NULL default '',
+LongVal bigint(20) default NULL,
+StringVal mediumtext,
+KEY FieldKey (FieldKey),
+KEY LongField (FieldKey,LongVal),
+KEY StringField (FieldKey,StringVal(32))
+);
+INSERT INTO t1 VALUES ('0',3,'0'),('0',2,'1'),('0',1,'2'),('1',2,'1'),('1',1,'3'), ('1',0,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('2',3,'0'),('2',2,'1'),('2',1,'2'),('3',2,'1'),('3',1,'2'),('3','3','3');
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (LongField, StringField) WHERE FieldKey > '2' ORDER BY LongVal;
+EXPLAIN SELECT * FROM t1 IGNORE INDEX (FieldKey, LongField) WHERE FieldKey > '2' ORDER BY LongVal;
+SELECT * FROM t1 WHERE FieldKey > '2' ORDER BY LongVal;
+DROP TABLE t1;
+--echo #
+--echo #
+CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
+INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
+INSERT into t2 values (1,1,1), (2,2,2);
+optimize table t1;
+explain select * from t1 force index (a) where a=0 or a=2;
+select * from t1 force index (a) where a=0 or a=2;
+drop table t1;
+--echo #
+--echo #
+create table t1
+(
+ pk1 int not null,
+ pk2 int not null,
+
+ key1 int not null,
+ key2 int not null,
+
+ pktail1ok int not null,
+ pktail2ok int not null,
+ pktail3bad int not null,
+ pktail4bad int not null,
+ pktail5bad int not null,
+
+ pk2copy int not null,
+ badkey int not null,
+
+ filler1 char (200),
+ filler2 char (200),
+ key (key1),
+ key (key2),
+
+ /* keys with tails from CPK members */
+ key (pktail1ok, pk1),
+ key (pktail2ok, pk1, pk2),
+ key (pktail3bad, pk2, pk1),
+ key (pktail4bad, pk1, pk2copy),
+ key (pktail5bad, pk1, pk2, pk2copy),
+
+ primary key (pk1, pk2)
+);
+
+--disable_query_log
+set autocommit=0;
+let $1=10000;
+while ($1)
+{
+ eval insert into t1 values ($1 div 10,$1 mod 100, $1/100,$1/100, $1/100,$1/100,$1/100,$1/100,$1/100, $1 mod 100, $1/1000,'filler-data-$1','filler2');
+ dec $1;
+}
+set autocommit=1;
+--enable_query_log
+explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
+select * from t1 where pk1 = 1 and pk2 < 80 and key1=0;
+drop table t1;
+
+--echo #
+--echo #
+CREATE TABLE t1 (
+f1 int,
+f4 varchar(32),
+f5 int,
+PRIMARY KEY (f1),
+KEY (f4)
+);
+INSERT INTO t1 VALUES
+(5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6),
+(530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1),
+(535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2),
+(540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0),
+(956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0),
+(961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL),
+(966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0),
+(971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0),
+(976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7),
+(981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1),
+(986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7),
+(991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4),
+(996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2);
+EXPLAIN
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+SELECT * FROM t1
+WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
+drop table t1;
+
+--echo #
+--echo #
+--source include/varchar.inc
+
+--echo #
+--echo #
+--disable_warnings
+drop database if exists world;
+--enable_warnings
+CREATE DATABASE world;
+
+use world;
+
+--source include/world_schema.inc
+
+--disable_query_log
+--disable_result_log
+--disable_warnings
+--source include/world.inc
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+
+--replace_column 9 #
+explain
+SELECT * FROM City
+WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
+AND (Population > 101000 AND Population < 102000);
+
+--replace_column 9 #
+explain
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+
+SELECT * FROM City
+WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR
+(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000));
+
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 7000000;
+
+--replace_column 9 #
+explain
+SELECT * FROM City
+WHERE Name LIKE 'M%' AND Population > 7000000;
+
+--replace_column 6 # 7 # 9 #
+explain
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'K' AND Population > 500000 AND Country LIKE 'C%';
+
+--replace_column 6 # 7 # 9 #
+explain
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+SELECT * FROM City
+WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
+
+drop database world;
+use test;
+
+set @mrr_icp_extra_tmp=@@optimizer_switch;
+
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index e912eb754f4..2f3eff31ff5 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -350,7 +350,7 @@ DROP TABLE t1;
#
CREATE TABLE t1 (a int not null, b int, c int, key(b), key(c), key(a,b), key(c,a));
-INSERT into t1 values (0, null, 0), (0, null, 1), (0, null, 2), (0, null,3), (1,1,4);
+INSERT into t1 values (0,null,0), (0,null,1), (0,null,2), (0,null,3), (1,1,4);
create table t2 (a int not null, b int, c int, key(b), key(c), key(a));
INSERT into t2 values (1,1,1), (2,2,2);
optimize table t1;
@@ -358,7 +358,13 @@ show index from t1;
explain select * from t1,t2 where t1.a=t2.a;
explain select * from t1,t2 force index(a) where t1.a=t2.a;
explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a;
+INSERT into t1 values (2,4,5), (7,8,4), (8,3,1), (9,7,2), (5,5,9);
+optimize table t1;
+show index from t1;
explain select * from t1,t2 where t1.b=t2.b;
+delete from t1 where t1.a>1;
+optimize table t1;
+show index from t1;
explain select * from t1,t2 force index(c) where t1.a=t2.a;
explain select * from t1 where a=0 or a=2;
explain select * from t1 force index (a) where a=0 or a=2;
diff --git a/mysql-test/t/myisam_icp.test b/mysql-test/t/myisam_icp.test
index 30a8b208230..bbff6c30e56 100644
--- a/mysql-test/t/myisam_icp.test
+++ b/mysql-test/t/myisam_icp.test
@@ -2,6 +2,9 @@
# ICP/MyISAM tests (Index Condition Pushdown)
#
+set @myisam_icp_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
--source include/icp_tests.inc
--disable_warnings
@@ -192,3 +195,66 @@ drop table if exists t0, t1, t1i, t1m;
drop table t0, t1, t1i, t1m;
--enable_parsing
+
+--echo #
+--echo # BUG#826935 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed
+--echo #
+CREATE TABLE t1 ( a int, b varchar(1024), c int, KEY (c), KEY (c,a)) ;
+INSERT INTO t1 VALUES
+ (NULL,'x','-678428672'),
+ (NULL,'ok',NULL),
+ (796262400,'byluovkgwoukfxedyeffsedajyqkyhpaqqpozn', NULL),
+ (7,'STQUF',146014208),
+ (955711488,'WWVOR','-1515388928');
+SELECT b FROM t1 WHERE a != 1 AND c IS NULL ORDER BY 1;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#870046: ICP for a GROUP BY query
+--echo #
+
+CREATE TABLE t1 (a int, b varchar(1), c varchar(1), INDEX idx(b));
+INSERT INTO t1 VALUES (2,'x','x'), (5,'x','y');
+
+SET SESSION optimizer_switch='index_condition_pushdown=off';
+EXPLAIN
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+SET SESSION optimizer_switch='index_condition_pushdown=on';
+EXPLAIN
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+SELECT a, MIN(c) FROM t1 WHERE b = 'x' AND c > 'x' GROUP BY a;
+
+DROP TABLE t1;
+
+--echo #
+--echo # BUG#887026: Wrong result with ICP, outer join, subquery in maria-5.3-icp
+--echo #
+
+CREATE TABLE t1 (c varchar(1));
+INSERT INTO t1 VALUES ('c'), ('c');
+
+CREATE TABLE t2 (c varchar(1), b int);
+INSERT INTO t2 VALUES ('d', NULL),('d', NULL);
+
+CREATE TABLE t3 (c varchar(1));
+INSERT INTO t3 VALUES ('c');
+INSERT INTO t3 VALUES ('c');
+
+CREATE TABLE t4 ( b int, c varchar(1), KEY (b));
+INSERT INTO t4 VALUES (7,'c');
+INSERT INTO t4 VALUES (7,'c');
+
+--echo # Must be t1,t2,t3,t4, with t4 having Full-scan-on-NULL but not Using index condition
+explain
+SELECT * FROM t1 LEFT JOIN t2 ON t1.c=t2.b
+WHERE
+ t2.b NOT IN (SELECT t4.b FROM t3 STRAIGHT_JOIN t4 WHERE t4.b <= 2 AND t4.c = t3.c);
+
+SELECT * FROM t1 LEFT JOIN t2 ON t1.c=t2.b
+WHERE
+ t2.b NOT IN (SELECT t4.b FROM t3 STRAIGHT_JOIN t4 WHERE t4.b <= 2 AND t4.c = t3.c);
+
+DROP TABLE t1,t2,t3,t4;
+
+set optimizer_switch=@myisam_icp_tmp;
diff --git a/mysql-test/t/myisam_mrr.test b/mysql-test/t/myisam_mrr.test
index 82457ee4366..1e070ec9a34 100644
--- a/mysql-test/t/myisam_mrr.test
+++ b/mysql-test/t/myisam_mrr.test
@@ -6,6 +6,8 @@
drop table if exists t0, t1, t2, t3;
--enable_warnings
+set @myisam_mrr_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set @mrr_buffer_size_save= @@mrr_buffer_size;
set mrr_buffer_size=79;
@@ -197,6 +199,14 @@ INSERT INTO t1 VALUES
(22,142,'b','b'),(23,3,'y','y'),(24,0,'v','v'),
(25,3,'m','m'),(26,5,'z','z'),(27,9,'n','n'),
(28,1,'d','d'),(29,107,'a','a');
+INSERT INTO t1 VALUES
+ (110,8,'v','v'),(111,8,'f','f'), (112,5,'v','v'),
+ (113,8,'s','s'),(114,8,'a','a'),(115,6,'p','p'),
+ (116,7,'z','z'),(117,2,'a','a'),(118,5,'h','h'),
+ (119,7,'h','h'),(120,2,'v','v'),(121,9,'v','v'),
+ (122,142,'b','b'),(123,3,'y','y'),(124,0,'v','v'),
+ (125,3,'m','m'),(126,5,'z','z'),(127,9,'n','n'),
+ (128,1,'d','d'),(129,107,'a','a');
SELECT COUNT(*)
FROM
@@ -218,3 +228,45 @@ set join_cache_level= @save_join_cache_level;
set join_buffer_size= @save_join_buffer_size;
drop table t1;
+
+--echo #
+--echo # BUG#730133: Wrong result with jkl = 7, BKA, ICP in maria-5.3 + compound index
+--echo #
+set @tmp_730133_jcl= @@join_cache_level;
+set join_cache_level = 7;
+
+set @tmp_730133_os= @@optimizer_switch;
+set optimizer_switch= 'join_cache_hashed=off,join_cache_bka=on,index_condition_pushdown=on,optimize_join_buffer_size=on';
+
+CREATE TABLE t1 (f1 int, f2 int, f3 int, f4 int, f5 int, KEY (f4,f3));
+INSERT IGNORE INTO t1 VALUES ('2','9','5','0','0'),('4','7','0','0','0'),
+ ('6','97','190','0','0'),('7','3','6','0','0'),('11','101','186','0','0'),
+ ('14','194','226','0','0'),('15','148','133','0','0'),
+ ('16','9','6','0','0'),('17','9','3','0','0'),('18','1','8','0','0'),
+ ('19','1','5','0','0'),('20','5','7','0','0');
+
+explain
+SELECT COUNT(alias2.f2)
+FROM
+ t1 STRAIGHT_JOIN
+ t1 AS alias3 STRAIGHT_JOIN
+ t1 AS alias2 FORCE KEY (f4)
+WHERE
+ alias2.f4=alias3.f5 AND
+ alias2.f3 > alias3.f1;
+
+SELECT COUNT(alias2.f2)
+FROM
+ t1 STRAIGHT_JOIN
+ t1 AS alias3 STRAIGHT_JOIN
+ t1 AS alias2 FORCE KEY (f4)
+WHERE
+ alias2.f4=alias3.f5 AND
+ alias2.f3 > alias3.f1;
+
+set @@join_cache_level= @tmp_730133_jcl;
+set @@optimizer_switch= @tmp_730133_os;
+drop table t1;
+
+## This must be last line in the file:
+set optimizer_switch= @myisam_mrr_tmp;
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index d1ae90be864..d1dd648d5c7 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -6,7 +6,7 @@
#
--disable_warnings
-drop table if exists t1;
+drop table if exists t1,t2,t3;
--enable_warnings
#
@@ -124,6 +124,13 @@ drop table t1;
--exec echo "use" > $file
--exec $MYSQL < $file 2>&1
+# Test exceutable comments
+--exec echo "SELECT 1 /*! +1 */;" > $file
+--exec echo "SELECT 1 /*M! +1 */;" >> $file
+--exec echo "SELECT 1 /*!00000 +1 */;" >> $file
+--exec echo "SELECT 1 /*M!00000 +1 */" >> $file
+--exec $MYSQL < $file 2>&1
+
--remove_file $file
#
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 99537618011..a28dff09bce 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -661,6 +661,10 @@ a int(10), b varchar(30), c datetime, d blob, e text);
insert into t1 values (NULL), (10), (20);
insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thirty");
--exec $MYSQL_DUMP --skip-comments --xml --no-create-info test
+
+# Test if UNIQUE_CHECK is done correctly
+--exec $MYSQL_DUMP --skip-comments --no-create-info test
+--exec $MYSQL_DUMP --skip-comments test
drop table t1, t2;
diff --git a/mysql-test/t/negation_elimination.test b/mysql-test/t/negation_elimination.test
index 0e0d8891e1f..312be8ccdb4 100644
--- a/mysql-test/t/negation_elimination.test
+++ b/mysql-test/t/negation_elimination.test
@@ -65,6 +65,35 @@ select * from t1 where not((a < 5 and a < 10) and (not(a > 16) or a > 17));
explain select * from t1 where ((a between 5 and 15) and (not(a like 10)));
select * from t1 where ((a between 5 and 15) and (not(a like 10)));
+--echo # XOR (Note: XOR is negated by negating one of the operands)
+
+--echo # Should return 6,7
+SELECT * FROM t1 WHERE ((a > 5) XOR (a > 7));
+
+--echo # Should return 0..5,8..19
+SELECT * FROM t1 WHERE ((NOT (a > 5)) XOR (a > 7));
+SELECT * FROM t1 WHERE ((a > 5) XOR (NOT (a > 7)));
+SELECT * FROM t1 WHERE NOT ((a > 5) XOR (a > 7));
+
+--echo # Should return 6,7
+SELECT * FROM t1 WHERE NOT ((NOT (a > 5)) XOR (a > 7));
+SELECT * FROM t1 WHERE NOT ((a > 5) XOR (NOT (a > 7)));
+
+--echo # Should return 0..5,8..19
+SELECT * FROM t1 WHERE NOT ((NOT (a > 5)) XOR (NOT (a > 7)));
+
+--echo # Should have empty result
+SELECT * FROM t1 WHERE (NULL XOR (a > 7));
+SELECT * FROM t1 WHERE NOT (NULL XOR (a > 7));
+
+--echo # Should be simplified to "...WHERE (a XOR a)
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT ((NOT a) XOR (a));
+
+--echo # Should be simplified to "...WHERE (a XOR a)
+EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT (a XOR (NOT a));
+
+--echo # End XOR
+
delete from t1 where a > 3;
select a, not(not(a)) from t1;
explain extended select a, not(not(a)), not(a <= 2 and not(a)), not(a not like "1"), not (a not in (1,2)), not(a != 2) from t1 where not(not(a)) having not(not(a));
diff --git a/mysql-test/t/old-mode.test b/mysql-test/t/old-mode.test
index 6d0fe64bbb8..cf2167c8027 100644
--- a/mysql-test/t/old-mode.test
+++ b/mysql-test/t/old-mode.test
@@ -15,3 +15,13 @@ checksum table t1, t2;
checksum table t1, t2 quick;
checksum table t1, t2 extended;
drop table t1,t2;
+
+#
+# Test that SHOW PROCESSLIST doesn't have the Progress column
+#
+
+--replace_column 1 <Id> 3 <Host> 6 <Time>
+# Embedded server is hardcoded to show "Writing to net" as STATE.
+--replace_result "Writing to net" "NULL"
+--replace_regex /localhost[:0-9]*/localhost/
+SHOW PROCESSLIST;
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index 1b7d22cc677..ebcc762bd59 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -440,6 +440,7 @@ drop table t1;
create table t1(a int, b int, index(b));
insert into t1 values (2, 1), (1, 1), (4, NULL), (3, NULL), (6, 2), (5, 2);
+insert into t1 values (12, 11), (11, 11), (14, 3), (13, 5), (16, 12), (15, 12);
explain select * from t1 where b=1 or b is null order by a;
select * from t1 where b=1 or b is null order by a;
explain select * from t1 where b=2 or b is null order by a;
diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test
index 7e574fd6a42..9db3ff93634 100644
--- a/mysql-test/t/partition_error.test
+++ b/mysql-test/t/partition_error.test
@@ -696,11 +696,13 @@ FLUSH TABLES;
--remove_file $MYSQLD_DATADIR/test/t1.par
--replace_result $MYSQLD_DATADIR ./
CHECK TABLE t1;
---error ER_UNKNOWN_ERROR
+--replace_result $MYSQLD_DATADIR ./
+--error 29
SELECT * FROM t1;
--echo # Note that it is currently impossible to drop a partitioned table
--echo # without the .par file
---error ER_BAD_TABLE_ERROR
+--replace_result $MYSQLD_DATADIR ./
+--error 29
DROP TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.frm
--remove_file $MYSQLD_DATADIR/test/t1#P#p0.MYI
diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test
index db544d4643f..f1ec8964769 100644
--- a/mysql-test/t/partition_pruning.test
+++ b/mysql-test/t/partition_pruning.test
@@ -872,6 +872,7 @@ drop table t1;
create table t1 (a int not null, b int not null, key(a), key(b))
partition by hash(a) partitions 4;
insert into t1 values (1,1),(2,2),(3,3),(4,4);
+insert into t1 values (5,5),(6,6),(7,7),(8,8);
explain partitions
select * from t1 X, t1 Y
diff --git a/mysql-test/t/plugin_innodb.test b/mysql-test/t/plugin_innodb.test
new file mode 100644
index 00000000000..fb5dd84b997
--- /dev/null
+++ b/mysql-test/t/plugin_innodb.test
@@ -0,0 +1,27 @@
+--source include/not_embedded.inc
+--source include/have_example_plugin.inc
+--source include/have_innodb.inc
+
+if (!`select count(*) from information_schema.plugins
+ where plugin_name = 'innodb' and plugin_status = 'active' and
+ plugin_library is null`) {
+ skip Need compiled-in InnoDB;
+}
+
+
+--replace_regex /\.dll/.so/
+eval install plugin example soname '$HA_EXAMPLE_SO';
+create table t1(a int) engine=example;
+drop table t1;
+
+alter table mysql.plugin engine=innodb;
+--echo restart
+--source include/restart_mysqld.inc
+
+create table t1(a int) engine=example;
+select * from t1;
+drop table t1;
+
+alter table mysql.plugin engine=myisam;
+uninstall plugin example;
+
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 7206235e3e2..746d6bad896 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -3,7 +3,7 @@
#
--disable_warnings
-drop table if exists t1, t2, t3;
+drop table if exists t1, t2, t3, t10, t100;
--enable_warnings
CREATE TABLE t1 (
@@ -554,6 +554,18 @@ INSERT INTO t1 VALUES
'd8c4177d09f8b11f5.52725521'),
('d8c4177d24ccef970.14957924','d8c4177d09f8b11f5.52725521',10,11,
'd8c4177d09f8b11f5.52725521');
+INSERT INTO t1 VALUES
+('d8c4177d09f8b11f5.52725522','oxrootid',1,40,'d8c4177d09f8b11f5.52725522'),
+('d8c4177d151affab2.81582771','d8c4177d09f8b11f5.52725521',2,3,
+ 'd8c4177d09f8b11f5.52725522'),
+('d8c4177d206a333d2.74422678','d8c4177d09f8b11f5.52725521',4,5,
+ 'd8c4177d09f8b11f5.52725522'),
+('d8c4177d225791924.30714721','d8c4177d09f8b11f5.52725521',6,7,
+ 'd8c4177d09f8b11f5.52725522'),
+('d8c4177d2380fc201.39666694','d8c4177d09f8b11f5.52725521',8,9,
+ 'd8c4177d09f8b11f5.52725522'),
+('d8c4177d24ccef970.14957925','d8c4177d09f8b11f5.52725521',10,11,
+ 'd8c4177d09f8b11f5.52725522');
EXPLAIN
SELECT s.oxid FROM t1 v, t1 s
@@ -1402,3 +1414,49 @@ insert into t1 values ('2000-03-09 15:56:59'),('2000-05-05 23:24:28'),('2000-06-
select min(f1) from t1 where f1 >= '2006-05-25 07:00:20' and f1 between '2003-11-23 10:00:09' and '2010-01-01 01:01:01' and f1 > '2001-01-01 01:01:01';
drop table t1;
+--echo #
+--echo # BUG#11765831: 'RANGE ACCESS' MAY INCORRECTLY FILTER
+--echo # AWAY QUALIFYING ROWS
+--echo #
+
+CREATE TABLE t10(
+ K INT NOT NULL AUTO_INCREMENT,
+ I INT, J INT,
+ PRIMARY KEY(K),
+ KEY(I,J)
+);
+INSERT INTO t10(I,J) VALUES (6,1),(6,2),(6,3),(6,4),(6,5),
+ (6,6),(6,7),(6,8),(6,9),(6,0);
+
+CREATE TABLE t100 LIKE t10;
+INSERT INTO t100(I,J) SELECT X.I, X.K+(10*Y.K) FROM t10 AS X,t10 AS Y;
+
+# Insert offending value:
+INSERT INTO t100(I,J) VALUES(8,26);
+
+let $query= SELECT * FROM t100 WHERE I <> 6 OR (I <> 8 AND J = 5);
+
+#Verify that 'range' access will be used
+--echo
+--eval EXPLAIN $query
+
+# Only row 101,8,26 should be returned
+--echo
+--eval $query
+
+DROP TABLE t10,t100;
+
+--echo #
+--echo # lp:817363: Wrong result with sort_union and multipart key in maria-5.3
+--echo #
+CREATE TABLE t1 (a int NOT NULL , b int, c int, d varchar(32), KEY (d,b), PRIMARY KEY (a)) ;
+INSERT INTO t1 VALUES (7,7,NULL,'e'),(8,1,0,'p'),(9,7,1,'s'),(10,1,1,'j'),(12,2,0,'c'),(13,0,0,'a'),(14,1,1,'q');
+
+SELECT c FROM t1 WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
+SELECT c FROM t1 ignore index (d) WHERE d='q' OR d>='q' OR a > 97 OR (d IN ('j','s','i') AND b = 102);
+
+SELECT * FROM t1 ignore index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
+SELECT * FROM t1 force index(d) WHERE d = 'q' OR d >= 'q' OR (d IN ( 'j' , 's' , 'i' ) AND ( b = 102 ));
+
+DROP TABLE t1;
+
diff --git a/mysql-test/t/range_mrr_icp.test b/mysql-test/t/range_mrr_icp.test
new file mode 100644
index 00000000000..724da8aea3b
--- /dev/null
+++ b/mysql-test/t/range_mrr_icp.test
@@ -0,0 +1,7 @@
+set @mrr_icp_extra_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+--source t/range.test
+
+set optimizer_switch=@mrr_icp_extra_tmp;
+
diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test
index 1f7065dcb0a..2ffa2d8eb49 100755
--- a/mysql-test/t/range_vs_index_merge.test
+++ b/mysql-test/t/range_vs_index_merge.test
@@ -1029,5 +1029,34 @@ SELECT * FROM t1,t2,t3
DROP TABLE t1,t2,t3;
+#
+# LP bug #823301: index merge union with prossible index scan
+#
+#
+
+CREATE TABLE t1 (
+ a int, b int, c int, d int,
+ PRIMARY KEY(b), INDEX idx1(d), INDEX idx2(d,b,c)
+);
+INSERT INTO t1 VALUES
+ (0,58,7,7),(0,63,2,0),(0,64,186,8),(0,65,1,-2), (0,71,190,-3),
+ (0,72,321,-7),(0,73,0,3),(0,74,5,25),(0,75,5,3);
+
+SET SESSION optimizer_switch='index_merge_sort_union=off';
+EXPLAIN
+SELECT * FROM t1
+ WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+SELECT * FROM t1
+ WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+SET SESSION optimizer_switch='index_merge_sort_union=on';
+EXPLAIN
+SELECT * FROM t1
+ WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+SELECT * FROM t1
+ WHERE t1.b>7 AND t1.d>1 AND t1.d<>8 OR t1.d>=7 AND t1.d<8 OR t1.d>7;
+SET SESSION optimizer_switch=DEFAULT;
+
+DROP TABLE t1;
+
#the following command must be the last one in the file
set session optimizer_switch='index_merge_sort_intersection=default';
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 3cebb8fffd0..9fbfef53eb6 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -1961,6 +1961,7 @@ CREATE TABLE t2 ( a BLOB, INDEX (a(20)) );
INSERT INTO t1 VALUES ('one'),('two'),('three'),('four'),('five');
INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
+INSERT INTO t2 VALUES ('one'),('two'),('three'),('four'),('five');
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 USE INDEX (a) ON t1.a=t2.a;
EXPLAIN SELECT * FROM t1 LEFT JOIN t2 FORCE INDEX (a) ON t1.a=t2.a;
@@ -4146,7 +4147,8 @@ INSERT INTO t3 VALUES
(4,'z'), (3,'zzz'), (5,'zzzzz'), (3,'z'), (4,'zzz'), (3,'zzzz'),
(9,'zzzzz'), (2,'zzz'), (1,'zzzz'), (9,'zzz'), (1,'zzzz'), (5,'zzzzz'),
(4,'zzz'), (3,'zzzz'), (5,'zzzz'), (3,'zzz'), (4,'zz'), (3,'zzzzz');
-
+
+set @tmp= @@optimizer_switch;
SET SESSION optimizer_switch='index_condition_pushdown=off';
EXPLAIN SELECT * from t1,t2,t3 WHERE t3.a3=t1.a1 AND t2.a2=t1.a1;
@@ -4166,7 +4168,7 @@ SELECT * FROM t1,t2,t3
WHERE t2.a2=t1.a1 AND t3.a3=t2.a2 AND
LENGTH(CONCAT(CONCAT(t1.b1,t2.b2),t3.b3)) <= 7;
-SET SESSION optimizer_switch=DEFAULT;
+SET SESSION optimizer_switch=@tmp;
DROP TABLE t1,t2,t3;
@@ -4228,3 +4230,16 @@ SELECT * FROM t1 WHERE a = b;
DROP TABLE t1;
+--echo #
+--echo # lp:822760 Wrong result with view + invalid dates
+--echo #
+CREATE TABLE t1 (f1 date);
+INSERT IGNORE INTO t1 VALUES ('0000-00-00');
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+SELECT * FROM t1 HAVING f1 = 'zz';
+SELECT * FROM t1 HAVING f1 <= 'aa' ;
+SELECT * FROM t1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+SELECT * FROM t1 WHERE f1 = 'zz' AND f1 <= 'aa' ;
+SELECT * FROM v1 HAVING f1 = 'zz' AND f1 <= 'aa' ;
+DROP TABLE t1;
+DROP VIEW v1;
diff --git a/mysql-test/t/select_jcl6.test b/mysql-test/t/select_jcl6.test
index 9f9a3a40e0f..295efa632db 100644
--- a/mysql-test/t/select_jcl6.test
+++ b/mysql-test/t/select_jcl6.test
@@ -3,8 +3,10 @@
#
set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
+set @@optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set join_cache_level=6;
show variables like 'join_cache_level';
diff --git a/mysql-test/t/select_safe.test b/mysql-test/t/select_safe.test
index 481779e76d7..5691de956cb 100644
--- a/mysql-test/t/select_safe.test
+++ b/mysql-test/t/select_safe.test
@@ -58,6 +58,8 @@ SELECT * from t1;
#
analyze table t1;
insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a");
+insert into t1 values (null,"b"),(null,"b"),(null,"c"),(null,"c"),(null,"d"),(null,"d"),(null,"e"),(null,"e"),(null,"a"),(null,"e");
+insert into t1 values (null,"x"),(null,"x"),(null,"y"),(null,"y"),(null,"z"),(null,"z"),(null,"v"),(null,"v"),(null,"a"),(null,"v");
explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b;
set MAX_SEEKS_FOR_KEY=1;
explain select STRAIGHT_JOIN * from t1,t1 as t2 where t1.b=t2.b;
diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test
index 505df0fe8dc..46e454363cc 100644
--- a/mysql-test/t/status.test
+++ b/mysql-test/t/status.test
@@ -353,6 +353,23 @@ DROP FUNCTION f1;
# End of 5.1 tests
+#
+# Test of internal temporary table status variables
+#
+
+flush status;
+create table t1 (a int not null auto_increment primary key, g int, b blob);
+insert into t1 (g,b) values (1,'a'), (2, 'b'), (3, 'b'), (1, 'c');
+select * from t1;
+select b, count(*) from t1 group by b;
+select g, count(*) from t1 group by g;
+show status like 'Row%';
+show status like 'Handler%';
+show status like '%tmp%';
+drop table t1;
+
+# End of 5.3 tests
+
# Restore global concurrent_insert value. Keep in the end of the test file.
--connection default
set @@global.concurrent_insert= @old_concurrent_insert;
diff --git a/mysql-test/t/status_user.test b/mysql-test/t/status_user.test
index d42f81b20e5..802e2207d3d 100644
--- a/mysql-test/t/status_user.test
+++ b/mysql-test/t/status_user.test
@@ -85,5 +85,25 @@ select connected_time <> 0, busy_time <> 0, bytes_received <> 0,
bytes_sent <> 0, binlog_bytes_written <> 0
from information_schema.client_statistics;
+#
+# Test of in transaction
+#
+
+create table t1 (a int) engine=innodb;
+select @@in_transaction;
+begin;
+select @@in_transaction;
+insert into t1 values (1);
+select @@in_transaction;
+commit;
+select @@in_transaction;
+set @@autocommit=0;
+select @@in_transaction;
+insert into t1 values (2);
+select @@in_transaction;
+set @@autocommit=1;
+select @@in_transaction;
+drop table t1;
+
# Cleanup
set @@global.general_log=@save_general_log;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 3f843cdf534..13856ab31cc 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -12,8 +12,10 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t11,t12;
drop view if exists v2;
--enable_warnings
-set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
+set @subselect_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
+ "semijoin=on,firstmatch=on,loosescan=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
select (select 2);
explain extended select (select 2);
@@ -290,8 +292,9 @@ SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT *
SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a;
SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a;
INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test');
--- error ER_SUBQUERY_NO_1_ROW
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
+-- error ER_SUBQUERY_NO_1_ROW
+SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1');
EXPLAIN EXTENDED SELECT MAX(numreponse) FROM t1 WHERE numeropost='1';
EXPLAIN EXTENDED SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1');
drop table t1;
@@ -501,6 +504,54 @@ SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
drop table t1,t2,t3;
+--echo # check correct NULL Processing for normal IN/ALL/ANY
+--echo # and 2 ways of max/min optimization
+create table t1 (a int);
+insert into t1 values (1), (100), (NULL), (1000);
+create table t2 (a int not null);
+
+--echo # subselect returns empty set (for NULL and non-NULL left part)
+select a, a in (select * from t2) from t1;
+select a, a > any (select * from t2) from t1;
+select a, a > all (select * from t2) from t1;
+select a from t1 where a in (select * from t2);
+select a from t1 where a > any (select * from t2);
+select a from t1 where a > all (select * from t2);
+select a from t1 where a in (select * from t2 group by a);
+select a from t1 where a > any (select * from t2 group by a);
+select a from t1 where a > all (select * from t2 group by a);
+
+insert into t2 values (1),(200);
+
+--echo # sebselect returns non-empty set without NULLs
+select a, a in (select * from t2) from t1;
+select a, a > any (select * from t2) from t1;
+select a, a > all (select * from t2) from t1;
+select a from t1 where a in (select * from t2);
+select a from t1 where a > any (select * from t2);
+select a from t1 where a > all (select * from t2);
+select a from t1 where a in (select * from t2 group by a);
+select a from t1 where a > any (select * from t2 group by a);
+select a from t1 where a > all (select * from t2 group by a);
+
+drop table t2;
+create table t2 (a int);
+insert into t2 values (1),(NULL),(200);
+
+--echo # sebselect returns non-empty set with NULLs
+select a, a in (select * from t2) from t1;
+select a, a > any (select * from t2) from t1;
+select a, a > all (select * from t2) from t1;
+select a from t1 where a in (select * from t2);
+select a from t1 where a > any (select * from t2);
+select a from t1 where a > all (select * from t2);
+select a from t1 where a in (select * from t2 group by a);
+select a from t1 where a > any (select * from t2 group by a);
+select a from t1 where a > all (select * from t2 group by a);
+
+
+drop table t1, t2;
+
#LIMIT is not supported now
create table t1 (a float);
-- error ER_NOT_SUPPORTED_YET
@@ -932,7 +983,7 @@ drop table t1,t2;
#
# correct ALL optimisation
#
-create table t2 (a int, b int);
+create table t2 (a int, b int not null);
create table t3 (a int);
insert into t3 values (6),(7),(3);
select * from t3 where a >= all (select b from t2);
@@ -4066,7 +4117,7 @@ SELECT 1 FROM t1 GROUP BY
(SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1);
DROP TABLE t1;
-set @@optimizer_switch=@save_optimizer_switch;
+#Seems to be not needed here: set @@optimizer_switch=@subselect_tmp;
--echo #
--echo # Bug #49512 : subquery with aggregate function crash
--echo # subselect_single_select_engine::exec()
@@ -4376,6 +4427,87 @@ SELECT 1 as foo FROM t1 WHERE a < SOME
DROP TABLE t1;
+#
+# LP BUG#823169 NULLs with ALL/ANY and maxmin optimization
+#
+CREATE TABLE t1 (a int(11), b varchar(1));
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+
+delete from t1;
+INSERT INTO t1 VALUES (2,NULL),(5,'d'),(7,'g');
+
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b < ANY ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b > ANY ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b <= ANY ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b >= ANY ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b = ANY ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b <> ANY ( SELECT b FROM t1 GROUP BY b );
+
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b < ALL ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b > ALL ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b <= ALL ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b >= ALL ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b = ALL ( SELECT b FROM t1 GROUP BY b );
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 );
+SELECT a FROM t1 WHERE b <> ALL ( SELECT b FROM t1 GROUP BY b );
+
+drop table t1;
+
+--echo #
+--echo # Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+--echo #
+CREATE TABLE t1 ( f11 int) ;
+INSERT IGNORE INTO t1 VALUES (0),(0);
+
+CREATE TABLE t2 ( f3 int, f10 int, KEY (f10,f3)) ;
+INSERT IGNORE INTO t2 VALUES (NULL,NULL),(5,0);
+
+DROP TABLE IF EXISTS t3;
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+
+SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ;
+DROP TABLE t1, t2, t3;
+
+--echo End of 5.2 tests
+
--echo #
--echo # BUG#779885: Crash in eliminate_item_equal with materialization=on in
--echo # maria-5.3
@@ -4401,4 +4533,235 @@ WHERE
);
DROP TABLE t1,t2,t3;
+--echo #
+--echo # BUG LP:813473: Wrong result with outer join + NOT IN subquery
+--echo # This bug is a duplicate of Bug#11764086 whose test case is added below
+--echo #
+
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
+
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
+
+create table t3 (d int, e int);
+insert into t3 values (2, 9), (3,10);
+
+EXPLAIN
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b , t1.c) NOT IN (SELECT * from t3);
+
+SELECT t2.b , t1.c
+FROM t2 LEFT JOIN t1 ON t1.c < 3
+WHERE (t2.b, t1.c) NOT IN (SELECT * from t3);
+
+drop table t1, t2, t3;
+
--echo End of 5.3 tests
+
+--echo End of 5.5 tests.
+
+--echo #
+--echo # Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
+--echo #
+
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2(a1 int);
+INSERT INTO t2 VALUES (3);
+
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+
+## All these are subject to the transformation
+## '1 < some (...)' => '1 < max(...)'
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2);
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2);
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2);
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2);
+
+SET SESSION sql_mode=@old_sql_mode;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug#11764086: Null left operand to NOT IN in WHERE clause
+--echo # behaves differently than real NULL
+--echo #
+
+CREATE TABLE parent (id int);
+INSERT INTO parent VALUES (1), (2);
+
+CREATE TABLE child (parent_id int, other int);
+INSERT INTO child VALUES (1,NULL);
+
+--echo # Offending query (c.parent_id is NULL for null-complemented rows only)
+
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id NOT IN (
+ SELECT parent_id
+ FROM child
+ WHERE parent_id = 3
+ );
+
+--echo # Some syntactic variations with IS FALSE and IS NOT TRUE
+
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+ SELECT parent_id
+ FROM child
+ WHERE parent_id = 3
+ ) IS NOT TRUE;
+
+SELECT p.id, c.parent_id
+FROM parent p
+LEFT JOIN child c
+ON p.id = c.parent_id
+WHERE c.parent_id IN (
+ SELECT parent_id
+ FROM child
+ WHERE parent_id = 3
+ ) IS FALSE;
+
+DROP TABLE parent, child;
+
+--echo # End of test for bug#11764086.
+
+--echo #
+--echo # BUG#50257: Missing info in REF column of the EXPLAIN
+--echo # lines for subselects
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, INDEX (a));
+INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+
+--echo
+EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
+--echo
+EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7);
+
+--echo
+DROP TABLE t1;
+
+--echo #
+--echo # Bug 11765699 - 58690: !TABLE || (!TABLE->READ_SET ||
+--echo # BITMAP_IS_SET(TABLE->READ_SET, FIELD_INDEX
+--echo #
+
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES (0), (1);
+
+CREATE TABLE t2(
+ b TEXT,
+ c INT,
+ PRIMARY KEY (b(1))
+);
+INSERT INTO t2 VALUES ('a', 2), ('b', 3);
+
+SELECT 1 FROM t1 WHERE a =
+ (SELECT 1 FROM t2 WHERE b =
+ (SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ ORDER BY b
+ );
+
+SELECT 1 FROM t1 WHERE a =
+ (SELECT 1 FROM t2 WHERE b =
+ (SELECT 1 FROM t1 t11 WHERE c = 1 OR t1.a = 1 AND 1 = 2)
+ GROUP BY b
+ );
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS)
+--echo #
+
+CREATE TABLE t1 (f1 varchar(1));
+INSERT INTO t1 VALUES ('v'),('s');
+
+CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key));
+INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'),
+('d'),('y'),('t'),('d'),('s');
+
+let $query=SELECT table1.f1, table2.f1_key
+FROM t1 AS table1, t2 AS table2
+WHERE EXISTS
+(
+SELECT DISTINCT f1_key
+FROM t2
+WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
+
+eval $query;
+eval explain $query;
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #826279: assertion failure with GROUP BY a result of subquery
+--echo #
+
+CREATE TABLE t1 (a int);
+INSERT INTO t1 VALUES (0), (0);
+
+CREATE TABLE t2 (a int, b int, c int);
+INSERT INTO t2 VALUES (10,7,0), (0,7,0);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,7), (0,7);
+
+SELECT SUM(DISTINCT b),
+ (SELECT t2.a FROM t1 JOIN t2 ON t2.c != 0
+ WHERE t.a != 0 AND t2.a != 0)
+ FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+
+SELECT SUM(DISTINCT b),
+ (SELECT t2.a FROM t1,t2 WHERE t.a != 0 or 1=2 LIMIT 1)
+ FROM (SELECT * FROM t3) AS t
+GROUP BY 2;
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # Bug#12329653
+--echo # EXPLAIN, UNION, PREPARED STATEMENT, CRASH, SQL_FULL_GROUP_BY
+--echo #
+
+CREATE TABLE t1(a1 int);
+INSERT INTO t1 VALUES (1),(2);
+
+SELECT @@session.sql_mode INTO @old_sql_mode;
+SET SESSION sql_mode='ONLY_FULL_GROUP_BY';
+
+## First a simpler query, illustrating the transformation
+## '1 < some (...)' => '1 < max(...)'
+SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1);
+
+## The query which made the server crash.
+PREPARE stmt FROM
+'SELECT 1 UNION ALL
+SELECT 1 FROM t1
+ORDER BY
+(SELECT 1 FROM t1 AS t1_0
+ WHERE 1 < SOME (SELECT a1 FROM t1)
+)' ;
+
+--error ER_SUBQUERY_NO_1_ROW
+EXECUTE stmt ;
+--error ER_SUBQUERY_NO_1_ROW
+EXECUTE stmt ;
+
+SET SESSION sql_mode=@old_sql_mode;
+
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
+set optimizer_switch=@subselect_tmp;
diff --git a/mysql-test/t/subselect2.test b/mysql-test/t/subselect2.test
index 162bdd0d90a..5f819ed39ba 100644
--- a/mysql-test/t/subselect2.test
+++ b/mysql-test/t/subselect2.test
@@ -8,6 +8,9 @@
drop table if exists t1, t2, t3, t4;
--enable_warnings
+set @subselect2_test_tmp=@@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
CREATE TABLE t1
(
DOCID VARCHAR(32)BINARY NOT NULL
@@ -168,3 +171,6 @@ SELECT t1.* FROM t1 WHERE (SELECT COUNT(*) FROM t3,t2 WHERE t3.c=t2.a
and t2.a='1' AND t1.a=t3.b) > 0;
DROP TABLE t1,t2,t3;
+
+set optimizer_switch=@subselect2_test_tmp;
+
diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test
index 0c1523a04ca..f3faf44289e 100644
--- a/mysql-test/t/subselect3.test
+++ b/mysql-test/t/subselect3.test
@@ -2,7 +2,8 @@
drop table if exists t0, t1, t2, t3, t4, t5, t11, t12, t21, t22;
--enable_warnings
-set @save_optimizer_switch=@@optimizer_switch;
+set @subselect3_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
#
# 1. Subquery with GROUP/HAVING
@@ -80,6 +81,7 @@ insert into t1 values
(2, 3),
(2, NULL),
(3, NULL);
+insert into t1 values (5, 7), (8, 9), (4, 1);
create table t2 (a int, oref int);
insert into t2 values (1, 1), (2,2), (NULL, 3), (NULL, 4);
@@ -538,7 +540,6 @@ SELECT a, MAX(b),
DROP TABLE t1, t2;
# The next three test cases must be executed with the IN=>EXISTS strategy
-set @save_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch="partial_match_rowid_merge=off,partial_match_table_scan=off";
#
@@ -906,7 +907,8 @@ set @@optimizer_switch='firstmatch=off,materialization=off';
insert into t0 values(2);
explain select * from t1 where 2 in (select a from t0);
select * from t1 where 2 in (select a from t0);
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch='materialization=off';
explain select * from t1 where 2 in (select a from t0);
select * from t1 where 2 in (select a from t0);
set @@optimizer_switch=@save_optimizer_switch;
@@ -1160,7 +1162,7 @@ drop table t1,t2,t3;
--echo # BUG#47367 Crash in Name_resolution_context::process_error
--echo #
-SET SESSION optimizer_switch = 'default,semijoin=off';
+SET SESSION optimizer_switch = 'semijoin=off';
CREATE TABLE t1 (f1 INTEGER);
CREATE TABLE t2 LIKE t1;
delimiter |;
@@ -1186,4 +1188,4 @@ DROP PROCEDURE p1;
DROP TABLE t1, t2;
# The following command must be the last one the file
-set @@optimizer_switch=@save_optimizer_switch;
+set @@optimizer_switch=@subselect3_tmp;
diff --git a/mysql-test/t/subselect3_jcl6.test b/mysql-test/t/subselect3_jcl6.test
index 6d9611f83f3..8d880809476 100644
--- a/mysql-test/t/subselect3_jcl6.test
+++ b/mysql-test/t/subselect3_jcl6.test
@@ -3,8 +3,10 @@
#
set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set join_cache_level=6;
show variables like 'join_cache_level';
diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test
index 39561d5114f..db0433ce48e 100644
--- a/mysql-test/t/subselect4.test
+++ b/mysql-test/t/subselect4.test
@@ -4,6 +4,10 @@
drop table if exists t1,t2,t3,t4,t5,t6;
--enable_warnings
+set @subselect4_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
--echo #
--echo # Bug #46791: Assertion failed:(table->key_read==0),function unknown
--echo # function,file sql_base.cc
@@ -234,35 +238,6 @@ set @@session.optimizer_switch = @old_optimizer_switch,
DROP TABLE t1;
--echo #
---echo # BUG#45863 "Assertion failed: (fixed == 0), function fix_fields(),
---echo # file item.cc, line 4448"
---echo #
---disable_warnings
-DROP TABLE IF EXISTS C, BB;
---enable_warnings
-
-CREATE TABLE C (
- varchar_nokey varchar(1) NOT NULL
-);
-INSERT INTO C VALUES
- ('k'),('a'),(''),('u'),('e'),('v'),('i'),
- ('t'),('u'),('f'),('u'),('m'),('j'),('f'),
- ('v'),('j'),('g'),('e'),('h'),('z');
-CREATE TABLE BB (
- varchar_nokey varchar(1) NOT NULL
-);
-INSERT INTO BB VALUES ('i'),('t');
--- error ER_OPERAND_COLUMNS
-SELECT varchar_nokey FROM C
-WHERE (varchar_nokey, OUTR) IN (SELECT varchar_nokey
- FROM BB);
--- error ER_BAD_FIELD_ERROR
-SELECT varchar_nokey FROM C
-WHERE (varchar_nokey, OUTR) IN (SELECT varchar_nokey, varchar_nokey
- FROM BB);
-DROP TABLE C,BB;
-
---echo #
--echo # During work with BUG#45863 I had problems with a query that was
--echo # optimized differently in regular and prepared mode.
--echo # Because there was a bug in one of the selected strategies, I became
@@ -964,6 +939,40 @@ set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
+
+--echo #
+--echo # LP BUG#777691 Wrong result with subqery in select list and subquery cache=off in maria-5.3
+--echo #
+
+CREATE TABLE t1 ( f1 varchar(32)) ;
+INSERT INTO t1 VALUES ('b'),('x'),('c'),('x');
+
+CREATE TABLE t2 ( f2 int, f3 varchar(32)) ;
+INSERT INTO t2 VALUES (1,'x');
+
+set @save_optimizer_switch=@@optimizer_switch;
+set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off';
+
+EXPLAIN
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+
+set @@optimizer_switch='materialization=on,in_to_exists=off,subquery_cache=off';
+EXPLAIN
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+
+set @@optimizer_switch='materialization=off,in_to_exists=on,subquery_cache=off';
+--echo Even when t2 is not constant table, the result must be the same.
+INSERT INTO t2 VALUES (2,'y');
+EXPLAIN
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+SELECT t1.f1, ( SELECT MAX( f2 ) FROM t2 WHERE t2.f3 = t1.f1 ) as max_f2 FROM t1;
+
+set @@optimizer_switch=@save_optimizer_switch;
+
+drop table t1, t2;
+
--echo #
--echo # LP BUG#641203 Query returns rows where no result is expected (impossible WHERE)
--echo #
@@ -1415,3 +1424,345 @@ WHERE t2.f1 = (
FROM t1));
drop table t1, t2, t3;
+
+--echo #
+--echo # LP BUG#802979 Assertion `table->key_read == 0' in close_thread_table
+--echo #
+
+CREATE TABLE t1 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t1 VALUES (1,0),(5,0);
+CREATE TABLE t2 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t2 VALUES (1,0),(5,0);
+CREATE TABLE t3 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t3 VALUES (1,0),(5,0);
+CREATE TABLE t4 ( f1 int, f2 int , KEY (f1)) ;
+INSERT IGNORE INTO t4 VALUES (1,0),(5,0);
+
+EXPLAIN
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+ WHERE EXISTS (SELECT DISTINCT f1 FROM t4))
+ AND t2.f2 = t1.f1;
+
+-- error ER_SUBQUERY_NO_1_ROW
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+ WHERE EXISTS (SELECT DISTINCT f1 FROM t4))
+ AND t2.f2 = t1.f1;
+
+EXPLAIN
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+ WHERE EXISTS (SELECT DISTINCT f1 FROM t4) LIMIT 1)
+ AND t2.f2 = t1.f1;
+
+SELECT *
+FROM t1, t2
+WHERE t2.f2 = (SELECT f2 FROM t3
+ WHERE EXISTS (SELECT DISTINCT f1 FROM t4) LIMIT 1)
+ AND t2.f2 = t1.f1;
+
+drop table t1,t2,t3,t4;
+
+--echo #
+--echo # LP BUG#806943 Second crash with select_describe with nested subqueries in maria-5.3
+--echo #
+
+CREATE TABLE t1 ( f4 int) ;
+INSERT INTO t1 VALUES (0),(0);
+
+CREATE TABLE t2 ( f2 int) ;
+
+CREATE TABLE t3 ( f1 int NOT NULL );
+
+CREATE TABLE t4 ( f2 int, f3 int) ;
+INSERT INTO t4 VALUES (8,0),(3,0);
+
+EXPLAIN SELECT *
+FROM t2, t3
+WHERE t3.f1 = (
+ SELECT SUM( f2 )
+ FROM t4
+ WHERE EXISTS (
+ SELECT DISTINCT f4
+ FROM t1));
+SELECT *
+FROM t2, t3
+WHERE t3.f1 = (
+ SELECT SUM( f2 )
+ FROM t4
+ WHERE EXISTS (
+ SELECT DISTINCT f4
+ FROM t1));
+
+drop table t1, t2, t3, t4;
+
+--echo #
+--echo # LP BUG#611690 Crash in select_describe() with nested subqueries
+--echo #
+
+CREATE TABLE t1 (
+ col_int_key int(11) DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ KEY col_int_key (col_int_key),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (8,'v','v');
+INSERT INTO t1 VALUES (9,'r','r');
+
+CREATE TABLE t2 (
+ col_int_key int(11) DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ KEY col_int_key (col_int_key),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (2,'w','w');
+INSERT INTO t2 VALUES (9,'m','m');
+
+set @old_optimizer_switch = @@optimizer_switch;
+
+set @@optimizer_switch='subquery_cache=off,materialization=on,in_to_exists=off,semijoin=off';
+EXPLAIN
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+ FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ ON SUBQUERY2_t2.col_varchar_key
+ WHERE SUBQUERY2_t2.col_varchar_nokey IN
+ (SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+ FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ ON SUBQUERY2_t2.col_varchar_key
+ WHERE SUBQUERY2_t2.col_varchar_nokey IN
+ (SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+
+set @@optimizer_switch='subquery_cache=off,materialization=off,in_to_exists=on,semijoin=off';
+EXPLAIN
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+ FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ ON SUBQUERY2_t2.col_varchar_key
+ WHERE SUBQUERY2_t2.col_varchar_nokey IN
+ (SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+SELECT col_int_key
+FROM t2
+WHERE (SELECT SUBQUERY2_t1.col_int_key
+ FROM t1 SUBQUERY2_t1 STRAIGHT_JOIN t1 SUBQUERY2_t2
+ ON SUBQUERY2_t2.col_varchar_key
+ WHERE SUBQUERY2_t2.col_varchar_nokey IN
+ (SELECT col_varchar_nokey FROM t1 GROUP BY col_varchar_nokey));
+
+drop table t1, t2;
+
+set @@optimizer_switch = @old_optimizer_switch;
+
+
+--echo #
+--echo # LP BUG#612543 Crash in Item_field::used_tables() with view + subquery + prepared statements
+--echo #
+
+CREATE TABLE t1 ( f1 int(11), f2 varchar(1));
+CREATE TABLE t2 ( f3 varchar(1));
+insert into t1 values (2,'x'), (5,'y');
+insert into t2 values ('x'), ('z');
+CREATE VIEW v2 AS SELECT * FROM t2;
+
+set @old_optimizer_switch = @@optimizer_switch;
+
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 );
+PREPARE st1 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )";
+EXECUTE st1;
+EXECUTE st1;
+
+set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 );
+PREPARE st2 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )";
+EXECUTE st2;
+EXECUTE st2;
+
+set @@optimizer_switch='materialization=on,in_to_exists=on,semijoin=off,subquery_cache=off';
+EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 );
+PREPARE st3 FROM "SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM t1 )";
+EXECUTE st3;
+EXECUTE st3;
+
+set @@optimizer_switch = @old_optimizer_switch;
+
+drop table t1, t2;
+drop view v2;
+
+
+--echo #
+--echo # LP BUG#611396 RQG: crash in Item_field::register_field_in_read_map with semijoin=off
+--echo # and prepared statements and materialization
+
+CREATE TABLE t1 ( f1 int(11), f2 int(11)) ;
+CREATE TABLE t2 ( f1 int(11), f4 varchar(1), PRIMARY KEY (f1)) ;
+INSERT INTO t2 VALUES ('23','j'),('24','e');
+CREATE TABLE t3 ( f1 int(11), f4 varchar(1)) ;
+INSERT INTO t3 VALUES ('8','j');
+
+set @old_optimizer_switch = @@optimizer_switch;
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+
+EXPLAIN
+SELECT t2.f1, (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1))
+FROM t2 JOIN t3 ON t3.f4 = t2.f4
+WHERE t3.f1 = 8
+GROUP BY 1, 2;
+
+PREPARE st1 FROM "
+SELECT t2.f1, (SELECT f2 FROM t1 WHERE (7) IN (SELECT f1 FROM t1))
+FROM t2 JOIN t3 ON t3.f4 = t2.f4
+WHERE t3.f1 = 8
+GROUP BY 1, 2";
+
+EXECUTE st1;
+EXECUTE st1;
+
+set @@optimizer_switch = @old_optimizer_switch;
+
+drop table t1, t2, t3;
+
+
+--echo #
+--echo # LP BUG#611382 RQG: Query returns extra rows when executed with materialization=on
+--echo #
+
+CREATE TABLE t1 ( f4 varchar(1)) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2 ( f2 date, f3 varchar(1), f4 varchar(1)) ;
+INSERT INTO t2 VALUES ('2005-05-03','c','c'),('1900-01-01','d','d');
+CREATE TABLE t3 ( f3 varchar(1)) ;
+INSERT INTO t3 VALUES ('c');
+
+set @old_optimizer_switch = @@optimizer_switch;
+
+set @@optimizer_switch = 'materialization=on,in_to_exists=off,semijoin=off';
+
+EXPLAIN SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+
+SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+
+set @@optimizer_switch = 'materialization=off,in_to_exists=on,semijoin=off';
+
+EXPLAIN SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+
+SELECT t1.f4
+FROM t1 JOIN ( t2 JOIN t3 ON t3.f3 = t2.f4 ) ON t3.f3 = t2.f3
+WHERE t1.f4 IN ( SELECT f4 FROM t2 ) ;
+
+set @@optimizer_switch = @old_optimizer_switch;
+
+drop table t1, t2, t3;
+
+
+--echo #
+--echo # LP BUG#782305: Wrong result/valgrind warning in Item_sum_hybrid::any_value()
+--echo #
+
+CREATE TABLE t1 ( f1 int) ;
+INSERT INTO t1 VALUES (2),(3);
+CREATE TABLE t2 (f2 int) ;
+INSERT INTO t2 VALUES (2),(3);
+
+PREPARE st1 FROM '
+SELECT * FROM t2
+WHERE f2 <= SOME ( SELECT f1 FROM t1 );
+';
+EXECUTE st1;
+EXECUTE st1;
+
+PREPARE st2 FROM '
+SELECT * FROM t2
+WHERE f2 <= SOME (SELECT f1-2 FROM t1 UNION SELECT f1-1 FROM t1);
+';
+EXECUTE st2;
+EXECUTE st2;
+
+drop table t1, t2;
+
+--echo #
+--echo # LP BUG#825018: Crash in check_and_do_in_subquery_rewrites() with corrlated subquery in select list
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (10,1),(11,7);
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (2),(3);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (1,1);
+
+CREATE PROCEDURE sp1 () LANGUAGE SQL
+SELECT (SELECT t1.a
+ FROM t1
+ WHERE t1.b = t3.b
+ AND t1.b IN ( SELECT a FROM t2 )) sq
+FROM t3
+GROUP BY 1;
+CALL sp1();
+CALL sp1();
+drop procedure sp1;
+
+prepare st1 from "
+SELECT (SELECT t1.a
+ FROM t1
+ WHERE t1.b = t3.b
+ AND t1.b IN ( SELECT a FROM t2 )) sq
+FROM t3
+GROUP BY 1";
+execute st1;
+execute st1;
+deallocate prepare st1;
+
+drop table t1, t2, t3;
+
+set optimizer_switch=@subselect4_tmp;
+
+--echo #
+--echo # LP BUG#833702 Wrong result with nested IN and singlerow subqueries and equality propagation
+--echo #
+
+CREATE TABLE t2 (c int , a int, b int);
+INSERT INTO t2 VALUES (10,7,0);
+
+CREATE TABLE t3 (a int, b int) ;
+INSERT INTO t3 VALUES (5,0),(7,0);
+
+CREATE TABLE t4 (a int);
+INSERT INTO t4 VALUES (2),(8);
+
+set @@optimizer_switch='semijoin=off,in_to_exists=on,materialization=off,subquery_cache=off';
+
+SELECT * FROM t2
+WHERE t2.b IN (SELECT b FROM t3 WHERE t3.a = t2.a AND a < SOME (SELECT * FROM t4))
+ OR ( t2.c > 242 );
+
+EXPLAIN SELECT * FROM t2
+WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.a < ANY (SELECT t4.a FROM t4) and t3.a = 7);
+SELECT * FROM t2
+WHERE t2.b IN (SELECT t3.b FROM t3 WHERE t3.a < ANY (SELECT t4.a FROM t4) and t3.a = 7);
+
+drop table t2, t3, t4;
+
+set optimizer_switch=@subselect4_tmp;
+
+SET optimizer_switch= @@global.optimizer_switch;
+set @@tmp_table_size= @@global.tmp_table_size;
diff --git a/mysql-test/t/subselect_cache.test b/mysql-test/t/subselect_cache.test
index 12f42aab7d6..6bf5028b6cf 100644
--- a/mysql-test/t/subselect_cache.test
+++ b/mysql-test/t/subselect_cache.test
@@ -1,4 +1,10 @@
+--disable_warnings
+drop table if exists t1,t2,t3,t4,t5;
+drop view if exists v1;
+--enable_warnings
+
+
set optimizer_switch='subquery_cache=on';
create table t1 (a int, b int);
@@ -1567,6 +1573,7 @@ FROM t2 ) AND table1 .`col_varchar_key` OR table1 .`pk` ;
drop table t1,t2;
set @@optimizer_switch= default;
+set optimizer_switch='subquery_cache=on';
#
--echo # LP BUG#615378 (incorrect NULL result returning in Item_cache)
#
@@ -1614,3 +1621,82 @@ GROUP BY field3
HAVING (field3 <= 'h' AND field2 != 4) ;
--enable_warnings
drop tables t1, t2, t3;
+
+--echo #
+--echo # Test aggregate functions as parameters to subquery cache
+--echo #
+
+CREATE TABLE t1 ( a INT, b INT, c INT, KEY (a, b));
+
+INSERT INTO t1 VALUES
+ ( 1, 1, 1 ),
+ ( 1, 2, 2 ),
+ ( 1, 3, 3 ),
+ ( 1, 4, 6 ),
+ ( 1, 5, 5 ),
+ ( 1, 9, 13 ),
+
+ ( 2, 1, 6 ),
+ ( 2, 2, 7 ),
+ ( 2, 3, 8 );
+
+SELECT a, AVG(t1.b),
+(SELECT t11.c FROM t1 t11 WHERE t11.a = t1.a AND t11.b = AVG(t1.b)) AS t11c
+FROM t1 GROUP BY a;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Test of LP BUG#800696 (deleting list of Items (OR arguments)
+--echo # in optimization)
+--echo #
+
+set optimizer_switch='subquery_cache=on,in_to_exists=on';
+CREATE TABLE t1 ( f3 int) ;
+INSERT INTO t1 VALUES (0),(0);
+
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (0),(0);
+
+CREATE TABLE t2 ( f1 int, f2 int, f3 int) ;
+INSERT INTO t2 VALUES (7,0,0);
+
+SELECT *
+FROM t2, t3
+WHERE t2.f2 OR t3.f3 IN
+(
+SELECT t2.f2
+FROM t1
+WHERE t2.f1 OR t2.f3 );
+drop tables t1, t2, t3;
+
+--echo #
+--echo # Test of LP BUG#872775 view with "outer references" bug
+--echo #
+set @@optimizer_switch= default;
+set optimizer_switch='subquery_cache=on';
+CREATE TABLE t1 (a int) ;
+
+CREATE TABLE t2 (b int, c varchar(1) NOT NULL ) ;
+INSERT INTO t2 VALUES (1,'x'),(2,'y');
+
+CREATE TABLE t3 (a int) ;
+
+CREATE TABLE t4 ( pk int(11) NOT NULL , b int(11) NOT NULL ) ;
+INSERT INTO t4 VALUES (26,9),(27,5),(28,0),(29,3);
+
+CREATE OR REPLACE VIEW v1 AS
+SELECT t2.b
+FROM t1
+JOIN t2
+WHERE t2 .c > (
+ SELECT t2.c FROM t3
+ );
+
+SELECT * FROM t4 WHERE b NOT IN ( SELECT * FROM v1 );
+
+drop view v1;
+drop table t1,t2,t3,t4;
+
+--echo # restore default
+set @@optimizer_switch= default;
diff --git a/mysql-test/t/subselect_extra.test b/mysql-test/t/subselect_extra.test
new file mode 100644
index 00000000000..ed1c0ef7e4d
--- /dev/null
+++ b/mysql-test/t/subselect_extra.test
@@ -0,0 +1,393 @@
+#
+# This file is for tests for other features that happen to use
+# subqueries. The idea is that one should be able to run
+#
+# ./mysql-test-run t/subselect*.test
+#
+# and get as much subquery testing as possible.
+#
+
+--disable_warnings
+drop table if exists t1,t2,t3,t4;
+drop view if exists v1,v2,v3;
+--enable_warnings
+
+
+--echo # From explain.test:
+--echo #
+--echo # Bug#37870: Usage of uninitialized value caused failed assertion.
+--echo #
+create table t1 (dt datetime not null, t time not null);
+create table t2 (dt datetime not null);
+insert into t1 values ('2001-01-01 1:1:1', '1:1:1'),
+('2001-01-01 1:1:1', '1:1:1');
+insert into t2 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
+flush tables;
+EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+flush tables;
+SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
+drop tables t1, t2;
+
+--echo # From type_datetime.test:
+--echo #
+--echo # Bug #32694: NOT NULL table field in a subquery produces invalid results
+--echo #
+create table t1 (id int(10) not null, cur_date datetime not null);
+create table t2 (id int(10) not null, cur_date date not null);
+insert into t1 (id, cur_date) values (1, '2007-04-25 18:30:22');
+insert into t2 (id, cur_date) values (1, '2007-04-25');
+
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+
+insert into t1 (id, cur_date) values (2, '2007-04-26 18:30:22');
+insert into t2 (id, cur_date) values (2, '2007-04-26');
+
+explain extended
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+select * from t1
+where id in (select id from t1 as x1 where (t1.cur_date is null));
+
+explain extended
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+select * from t2
+where id in (select id from t2 as x1 where (t2.cur_date is null));
+
+drop table t1,t2;
+
+--echo #
+--echo # From group_min_max.test
+--echo #
+create table t1 (
+ a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
+);
+
+insert into t1 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'),
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4'),
+('d','a','a','a411','xy1'),('d','a','a','b411','xy2'),('d','a','a','c411','xy3'),('d','a','a','d411','xy4'),
+('d','a','b','e412','xy1'),('d','a','b','f412','xy2'),('d','a','b','g412','xy3'),('d','a','b','h412','xy4'),
+('d','b','a','i421','xy1'),('d','b','a','j421','xy2'),('d','b','a','k421','xy3'),('d','b','a','l421','xy4'),
+('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4');
+
+create index idx_t1_0 on t1 (a1);
+create index idx_t1_1 on t1 (a1,a2,b,c);
+create index idx_t1_2 on t1 (a1,a2,b);
+analyze table t1;
+
+# t2 is the same as t1, but with some NULLs in the MIN/MAX column, and
+# one more nullable attribute
+
+create table t2 (
+ a1 char(64), a2 char(64) not null, b char(16), c char(16), d char(16), dummy char(64) default ' '
+);
+insert into t2 select * from t1;
+# add few rows with NULL's in the MIN/MAX column
+insert into t2 (a1, a2, b, c, d) values
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),
+('a','a',NULL,'a777','xyz'),('a','a',NULL,'a888','xyz'),('a','a',NULL,'a999','xyz'),
+('a','a','a',NULL,'xyz'),
+('a','a','b',NULL,'xyz'),
+('a','b','a',NULL,'xyz'),
+('c','a',NULL,'c777','xyz'),('c','a',NULL,'c888','xyz'),('c','a',NULL,'c999','xyz'),
+('d','b','b',NULL,'xyz'),
+('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),('e','a','a',NULL,'xyz'),
+('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz'),('e','a','b',NULL,'xyz');
+
+create index idx_t2_0 on t2 (a1);
+create index idx_t2_1 on t2 (a1,a2,b,c);
+create index idx_t2_2 on t2 (a1,a2,b);
+analyze table t2;
+
+# Table t3 is the same as t1, but with smaller column lenghts.
+# This allows to test different branches of the cost computation procedure
+# when the number of keys per block are less than the number of keys in the
+# sub-groups formed by predicates over non-group attributes.
+
+create table t3 (
+ a1 char(1), a2 char(1), b char(1), c char(4) not null, d char(3), dummy char(1) default ' '
+);
+
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+insert into t3 (a1, a2, b, c, d) values
+('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
+('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
+('a','b','a','i121','xy1'),('a','b','a','j121','xy2'),('a','b','a','k121','xy3'),('a','b','a','l121','xy4'),
+('a','b','b','m122','xy1'),('a','b','b','n122','xy2'),('a','b','b','o122','xy3'),('a','b','b','p122','xy4'),
+('b','a','a','a211','xy1'),('b','a','a','b211','xy2'),('b','a','a','c211','xy3'),('b','a','a','d211','xy4'),
+('b','a','b','e212','xy1'),('b','a','b','f212','xy2'),('b','a','b','g212','xy3'),('b','a','b','h212','xy4'),
+('b','b','a','i221','xy1'),('b','b','a','j221','xy2'),('b','b','a','k221','xy3'),('b','b','a','l221','xy4'),
+('b','b','b','m222','xy1'),('b','b','b','n222','xy2'),('b','b','b','o222','xy3'),('b','b','b','p222','xy4'),
+('c','a','a','a311','xy1'),('c','a','a','b311','xy2'),('c','a','a','c311','xy3'),('c','a','a','d311','xy4'),
+('c','a','b','e312','xy1'),('c','a','b','f312','xy2'),('c','a','b','g312','xy3'),('c','a','b','h312','xy4'),
+('c','b','a','i321','xy1'),('c','b','a','j321','xy2'),('c','b','a','k321','xy3'),('c','b','a','l321','xy4'),
+('c','b','b','m322','xy1'),('c','b','b','n322','xy2'),('c','b','b','o322','xy3'),('c','b','b','p322','xy4');
+
+create index idx_t3_0 on t3 (a1);
+create index idx_t3_1 on t3 (a1,a2,b,c);
+create index idx_t3_2 on t3 (a1,a2,b);
+analyze table t3;
+
+
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+ where t2.c in (select c from t3 where t3.c > t1.b) and
+ t2.c > 'b1' )
+group by a1,a2,b;
+
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+ where t2.c in (select c from t3 where t3.c > t1.b) and
+ t2.c > 'b1' )
+group by a1,a2,b;
+
+explain select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+ where t2.c in (select c from t3 where t3.c > t1.c) and
+ t2.c > 'b1' )
+group by a1,a2,b;
+
+select a1,a2,b,c,min(c), max(c) from t1
+where exists ( select * from t2
+ where t2.c in (select c from t3 where t3.c > t1.c) and
+ t2.c > 'b1' )
+group by a1,a2,b;
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # From group_by.test
+--echo #
+
+--echo # Bug #21174: Index degrades sort performance and
+--echo # optimizer does not honor IGNORE INDEX.
+--echo # a.k.a WL3527.
+--echo #
+CREATE TABLE t1 (a INT, b INT,
+ PRIMARY KEY (a),
+ KEY i2(a,b));
+INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8);
+INSERT INTO t1 SELECT a + 8,b FROM t1;
+INSERT INTO t1 SELECT a + 16,b FROM t1;
+INSERT INTO t1 SELECT a + 32,b FROM t1;
+INSERT INTO t1 SELECT a + 64,b FROM t1;
+INSERT INTO t1 SELECT a + 128,b FROM t1 limit 16;
+ANALYZE TABLE t1;
+EXPLAIN SELECT 1 FROM t1 WHERE a IN
+ (SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+
+CREATE TABLE t2 (a INT, b INT, KEY(a));
+INSERT INTO t2 VALUES (1, 1), (2, 2), (3,3), (4,4);
+EXPLAIN SELECT a, SUM(b) FROM t2 GROUP BY a LIMIT 2;
+EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2;
+
+EXPLAIN SELECT 1 FROM t2 WHERE a IN
+ (SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
+DROP TABLE t1, t2;
+
+--echo #
+--echo # From derived_view.test
+--echo #
+set @tmp_subselect_extra_derived=@@optimizer_switch;
+set optimizer_switch='derived_merge=on,derived_with_keys=on';
+
+--echo #
+--echo # LP bug #806504: right join over a view/derived table
+--echo #
+
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (0,0);
+
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (0), (0);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN (SELECT * FROM t1) AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+EXPLAIN EXTENDED
+SELECT * FROM t2 RIGHT JOIN v1 AS t ON t.a != 0
+ WHERE t.a IN (SELECT b FROM t1);
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #793448: materialized view accessed by two-component key
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (9,3), (2,5);
+
+CREATE TABLE t2 (a int, b int);
+INSERT INTO t2 VALUES (9,3), (3,7), (9,1), (2,5), (2,4), (3,8);
+
+CREATE TABLE t3 (a int, b int);
+INSERT INTO t3 VALUES (10,3), (9,7), (9,1), (2,4);
+
+CREATE VIEW v1(a,b) AS SELECT a, MAX(b) FROM t2 GROUP BY a;
+CREATE VIEW v2(a,b) AS SELECT a,b FROM t2 UNION SELECT a,b FROM t3;
+
+SELECT * FROM v1;
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v1);
+
+SELECT * FROM v2;
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+EXPLAIN
+SELECT a FROM t1 WHERE (a,b) IN (SELECT * FROM v2);
+
+DROP VIEW v1,v2;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #874006: materialized view used in IN subquery
+--echo #
+
+CREATE TABLE t3 (a int NOT NULL, b varchar(1), c varchar(1));
+INSERT INTO t3 VALUES (19,NULL,NULL), (20,'r','r');
+
+CREATE TABLE t1 (a int, b varchar(1) , c varchar(1));
+INSERT INTO t1 VALUES (1,NULL,NULL), (5,'r','r'), (7,'y','y');
+
+CREATE TABLE t2 (a int NOT NULL , b int, c varchar(1));
+INSERT INTO t2 VALUES (4,3,'r');
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+
+SET SESSION optimizer_switch='derived_with_keys=off';
+EXPLAIN
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+SELECT * FROM t3
+ WHERE t3.b IN (SELECT v1.b FROM v1, t2
+ WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # LP bug #873263: materialized view used in correlated IN subquery
+--echo #
+
+CREATE TABLE t1 (a int, b int) ;
+INSERT INTO t1 VALUES (5,4), (9,8);
+
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (4,5), (5,1);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2;
+
+SET SESSION optimizer_switch='derived_with_keys=on';
+EXPLAIN
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+SELECT * FROM t1 WHERE t1.b IN (SELECT v2.a FROM v2 WHERE v2.b = t1.a);
+
+DROP VIEW v2;
+DROP TABLE t1,t2;
+
+set optimizer_switch= @tmp_subselect_extra_derived;
+
diff --git a/mysql-test/t/subselect_extra_no_semijoin.test b/mysql-test/t/subselect_extra_no_semijoin.test
new file mode 100644
index 00000000000..65fbbfc6409
--- /dev/null
+++ b/mysql-test/t/subselect_extra_no_semijoin.test
@@ -0,0 +1,7 @@
+set @subselect_extra_no_sj_tmp=@@optimizer_switch;
+set optimizer_switch='semijoin=off,firstmatch=off,loosescan=off';
+
+--source t/subselect_extra.test
+
+set optimizer_switch= @subselect_extra_no_sj_tmp;
+
diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test
index 573fe0c1810..4b511b45e03 100644
--- a/mysql-test/t/subselect_innodb.test
+++ b/mysql-test/t/subselect_innodb.test
@@ -1,5 +1,9 @@
-- source include/have_innodb.inc
+# Note: the tests uses only non-semijoin subqueries so semi-join switch
+# settings are not relevant.
+set @subselect_innodb_tmp=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
--disable_warnings
drop table if exists t1,t2,t3;
--enable_warnings
@@ -238,3 +242,62 @@ call p1();
call p1();
drop procedure p1;
drop tables t1,t2,t3;
+
+--echo #
+--echo # LP BUG#827416: Crash in select_describe() on EXPLAIN with DISTINCT in nested subqueries
+--echo #
+
+CREATE TABLE t3 ( b int) ENGINE=InnoDB;
+CREATE TABLE t2 ( c int) ENGINE=InnoDB;
+CREATE TABLE t1 ( a int NOT NULL , PRIMARY KEY (a)) ENGINE=InnoDB;
+
+EXPLAIN SELECT *
+FROM t1
+WHERE t1.a = (
+ SELECT SUM( c )
+ FROM t2
+ WHERE (SELECT DISTINCT b FROM t3) > 0);
+SELECT *
+FROM t1
+WHERE t1.a = (
+ SELECT SUM( c )
+ FROM t2
+ WHERE (SELECT DISTINCT b FROM t3) > 0);
+
+DROP TABLE t1, t2, t3;
+
+
+--echo #
+--echo # LP BUG#858148 Fourth crash in select_describe() with nested subqueries
+--echo #
+
+CREATE TABLE t1 ( f1 int(11)) ENGINE=InnoDB;
+CREATE TABLE t2 ( f1 int(11), f2 int(11), PRIMARY KEY (f1)) ;
+CREATE TABLE t3 ( f3 int(11)) ENGINE=InnoDB;
+
+EXPLAIN
+SELECT MAX( f1 ) FROM t2
+WHERE f2 >= (
+ SELECT SUM( f1 )
+ FROM t1
+ WHERE EXISTS (
+ SELECT f3
+ FROM t3
+ GROUP BY 1
+ )
+);
+
+SELECT MAX( f1 ) FROM t2
+WHERE f2 >= (
+ SELECT SUM( f1 )
+ FROM t1
+ WHERE EXISTS (
+ SELECT f3
+ FROM t3
+ GROUP BY 1
+ )
+);
+
+drop table t1, t2, t3;
+
+set optimizer_switch=@subselect_innodb_tmp;
diff --git a/mysql-test/t/subselect_mat.test b/mysql-test/t/subselect_mat.test
index 9d6eb2775ab..09c6b3e1747 100644
--- a/mysql-test/t/subselect_mat.test
+++ b/mysql-test/t/subselect_mat.test
@@ -5,10 +5,13 @@
# force the use of materialization
-set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+set @subselect_mat_test_optimizer_switch_value='materialization=on,in_to_exists=off,semijoin=off';
--source t/subselect_sj_mat.test
+set @subselect_mat_test_optimizer_switch_value=null;
+
set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
#
# Test that the contents of the temp table of a materialized subquery is
# cleaned up between PS re-executions.
@@ -199,3 +202,55 @@ SELECT (f1, f2, f3) NOT IN
FROM t2;
drop table t1, t2;
+
+--echo #
+--echo # LPBUG#702301: MAX in select + always false WHERE with SQ
+--echo #
+
+CREATE TABLE t1 (a int, b int, KEY (b));
+INSERT INTO t1 VALUES (3,1), (4,2);
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (7), (8);
+
+set @@optimizer_switch='materialization=on,in_to_exists=off,semijoin=off';
+
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+EXPLAIN EXTENDED
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+
+set @@optimizer_switch='materialization=off,in_to_exists=on,semijoin=off';
+
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+EXPLAIN EXTENDED
+SELECT MAX(t1.b) AS max_res FROM t1 WHERE (9) IN (SELECT a FROM t2);
+
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LPBUG#825095: Wrong result with materialization and NOT IN with 2 expressions
+--echo #
+
+CREATE TABLE t1 (a int,b int);
+INSERT INTO t1 VALUES (4,4),(4,2);
+
+CREATE TABLE t2 (b int, a int);
+INSERT INTO t2 VALUES (4,3),(8,4);
+
+set @@optimizer_switch='semijoin=off,in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+
+EXPLAIN SELECT *
+FROM t1
+WHERE (a, b) NOT IN (SELECT a, b FROM t2);
+
+SELECT *
+FROM t1
+WHERE (a, b) NOT IN (SELECT a, b FROM t2);
+
+EXPLAIN
+SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
+FROM t1;
+
+SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
+FROM t1;
+
+drop table t1, t2;
diff --git a/mysql-test/t/subselect_mat_cost-master.opt b/mysql-test/t/subselect_mat_cost-master.opt
new file mode 100644
index 00000000000..dc7ac6cc205
--- /dev/null
+++ b/mysql-test/t/subselect_mat_cost-master.opt
@@ -0,0 +1 @@
+--log-output=TABLE,FILE --log --log-slow-queries --slow-query-log=1
diff --git a/mysql-test/t/subselect_mat_cost.test b/mysql-test/t/subselect_mat_cost.test
index ced99bccea3..a747b9a6c5e 100644
--- a/mysql-test/t/subselect_mat_cost.test
+++ b/mysql-test/t/subselect_mat_cost.test
@@ -1,204 +1,429 @@
#
-# Tets of cost-based choice between the materialization and in-to-exists
+# Tests of cost-based choice between the materialization and in-to-exists
# subquery execution strategies (MWL#89)
#
+# The test file is divided into two groups of tests:
+# A. Typical cases when either of the two strategies is selected:
+# 1. Subquery in disjunctive WHERE clause of the outer query.
+# 2. NOT IN subqueries
+# 3. Subqueries with GROUP BY, HAVING, and aggregate functions
+# 4. Subqueries in the SELECT and HAVING clauses
+# 5. Subqueries with UNION
+# B. Reasonably exhaustive tests of the various combinations of optimizer
+# switches, data distribution, available indexes, and typical queries.
+#
+
+set @subselect_mat_cost=@@optimizer_switch;
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+#
+# Test logging to slow log (there was some errors in the log files about
+# the slow log when running under valgrind, so better to get this tested)
+#
+set log_slow_time=0.1;
+
+
+-- echo TEST GROUP 1:
+-- echo Typical cases of in-to-exists and materialization subquery strategies
+-- echo =====================================================================
--disable_warnings
-drop table if exists t1, t2, t1_1024, t2_1024;
-drop procedure if exists make_t1_indexes;
-drop procedure if exists make_t2_indexes;
-drop procedure if exists remove_t1_indexes;
-drop procedure if exists remove_t2_indexes;
-drop procedure if exists add_materialization_data;
-drop procedure if exists delete_materialization_data;
-drop procedure if exists set_all_columns_not_null;
-drop procedure if exists set_all_columns_nullable;
+drop database if exists world;
--enable_warnings
-create table t1 (a1 char(8), a2 char(8), a3 char(8), a4 int);
-insert into t1 values ('1 - 00', '2 - 00', '3 - 00', 0);
-insert into t1 values ('1 - 01', '2 - 01', '3 - 01', 1);
-
-create table t2 (b1 char(8), b2 char(8), b3 char(8), b4 int);
-insert into t2 values ('1 - 01', '2 - 01', '3 - 01', 1);
-insert into t2 values ('1 - 01', '2 - 01', '3 - 02', 2);
-insert into t2 values ('1 - 02', '2 - 02', '3 - 03', 3);
-insert into t2 values ('1 - 02', '2 - 02', '3 - 04', 4);
-insert into t2 values ('1 - 03', '2 - 03', '3 - 05', 5);
-
-create table t1_1024 (a1 blob(1024), a2 blob(1024));
-insert into t1_1024 values (concat('1 - 00', repeat('x', 1018)), concat('2 - 00', repeat('x', 1018)));
-insert into t1_1024 values (concat('1 - 01', repeat('x', 1018)), concat('2 - 01', repeat('x', 1018)));
-
-create table t2_1024 (b1 blob(1024), b2 blob(1024));
-insert into t2_1024 values (concat('1 - 01', repeat('x', 1018)), concat('2 - 01', repeat('x', 1018)));
-insert into t2_1024 values (concat('1 - 02', repeat('x', 1018)), concat('2 - 02', repeat('x', 1018)));
-insert into t2_1024 values (concat('1 - 03', repeat('x', 1018)), concat('2 - 03', repeat('x', 1018)));
-insert into t2_1024 values (concat('1 - 04', repeat('x', 1018)), concat('2 - 04', repeat('x', 1018)));
-
-delimiter |;
-create procedure make_t1_indexes()
-begin
- create index it1i1 on t1 (a1);
- create index it1i2 on t1 (a2);
- create index it1i3 on t1 (a1, a2);
- create index it1_1024i1 on t1_1024 (a1(6));
- create index it1_1024i2 on t1_1024 (a2(6));
- create index it1_1024i3 on t1_1024 (a1(6), a2(6));
-end|
-
-create procedure make_t2_indexes()
-begin
- create index it2i1 on t2 (b1);
- create index it2i2 on t2 (b2);
- create index it2i3 on t2 (b1, b2);
- create unique index it2i4 on t2 (b1, b2, b3);
- create index it2_1024i1 on t2_1024 (b1(6));
- create index it2_1024i2 on t2_1024 (b2(6));
- create index it2_1024i3 on t2_1024 (b1(6), b2(6));
-end|
-
-create procedure remove_t1_indexes()
-begin
- drop index it1i1 on t1;
- drop index it1i2 on t1;
- drop index it1i3 on t1;
- drop index it1_1024i1 on t1_1024;
- drop index it1_1024i2 on t1_1024;
- drop index it1_1024i3 on t1_1024;
-end|
-
-create procedure remove_t2_indexes()
-begin
- drop index it2i1 on t2;
- drop index it2i2 on t2;
- drop index it2i3 on t2;
- drop index it2i4 on t2;
- drop index it2_1024i1 on t2_1024;
- drop index it2_1024i2 on t2_1024;
- drop index it2_1024i3 on t2_1024;
-end|
-
-create procedure add_materialization_data()
-begin
-insert into t1 values ('1 - 03', '2 - 03', '3 - 03', 3);
-insert into t1 values ('1 - 04', '2 - 04', '3 - 04', 4);
-insert into t1 values ('1 - 05', '2 - 05', '3 - 05', 5);
-insert into t1 values ('1 - 06', '2 - 06', '3 - 06', 6);
-insert into t1 values ('1 - 07', '2 - 07', '3 - 07', 7);
-insert into t1_1024 values (concat('1 - 03', repeat('x', 1018)), concat('2 - 03', repeat('x', 1018)));
-end|
-
-create procedure delete_materialization_data()
-begin
-delete from t1 where a1 >= '1 - 03';
-delete from t1_1024 where a1 >= '1 - 03';
-end|
-
-create procedure set_all_columns_not_null()
-begin
-alter table t1 modify a1 char(8) not null, modify a2 char(8) not null, modify a3 char(8) not null;
-alter table t2 modify b1 char(8) not null, modify b2 char(8) not null, modify b3 char(8) not null;
-end|
-
-create procedure set_all_columns_nullable()
-begin
-alter table t1 modify a1 char(8) null, modify a2 char(8) null, modify a3 char(8) null;
-alter table t2 modify b1 char(8) null, modify b2 char(8) null, modify b3 char(8) null;
-end|
-
-delimiter ;|
--- echo
-
--- echo /******************************************************************************
--- echo 1. Both materialization and in-to-exists are ON, make a cost-based choice.
--- echo ******************************************************************************/
-set @@optimizer_switch='materialization=on,in_to_exists=on';
--- echo
--- echo /* 1.1 In-to-exists is cheaper */
-call make_t1_indexes();
-
--- echo /* 1.1.1 non-indexed table access */
--- source include/subselect_mat_cost.inc
-
--- echo /* 1.1.2 indexed table access, nullabale columns. */
-call make_t2_indexes();
--- source include/subselect_mat_cost.inc
-
--- echo /* 1.1.3 indexed table access, non-nullabale columns. */
-call set_all_columns_not_null();
--- source include/subselect_mat_cost.inc
-call set_all_columns_nullable();
-
--- echo
--- echo /* 1.2 Materialization is cheaper */
-# make materialization cheaper
-call add_materialization_data();
-call remove_t1_indexes();
-
--- echo /* 1.2.1 non-indexed table access */
-call remove_t2_indexes();
--- source include/subselect_mat_cost.inc
-
--- echo /* 1.2.2 indexed table access, nullabale columns. */
-call make_t2_indexes();
--- source include/subselect_mat_cost.inc
-
--- echo /* 1.2.3 indexed table access, non-nullabale columns. */
-call set_all_columns_not_null();
--- source include/subselect_mat_cost.inc
-call set_all_columns_nullable();
-
-
-insert into t1 values ('1 - 02', '2 - 02', '3 - 02', 2);
-
--- echo /******************************************************************************
--- echo 2. Materialization is OFF, in-to-exists is ON, materialization is cheaper.
--- echo ******************************************************************************/
-set @@optimizer_switch='materialization=off,in_to_exists=on';
-
--- echo /* 2.1 non-indexed table access */
-call remove_t2_indexes();
--- source include/subselect_mat_cost.inc
-
--- echo /* 2.2 indexed table access, nullabale columns. */
-call make_t2_indexes();
--- source include/subselect_mat_cost.inc
-
--- echo /* 2.3 indexed table access, non-nullabale columns. */
-call set_all_columns_not_null();
--- source include/subselect_mat_cost.inc
-call set_all_columns_nullable();
-
-
--- echo /******************************************************************************
--- echo 3. Materialization is ON, in-to-exists is OFF, in-to-exists is cheaper.
--- echo ******************************************************************************/
-set @@optimizer_switch='materialization=on,in_to_exists=off';
-# make IN-TO-EXISTS cheaper
-call delete_materialization_data();
-call make_t1_indexes();
-
--- echo /* 3.1 non-indexed table access */
-call remove_t2_indexes();
--- source include/subselect_mat_cost.inc
-
--- echo /* 3.2 indexed table access, nullabale columns. */
-call make_t2_indexes();
--- source include/subselect_mat_cost.inc
-
--- echo /* 3.3 indexed table access, non-nullabale columns. */
-call set_all_columns_not_null();
--- source include/subselect_mat_cost.inc
-call set_all_columns_nullable();
-
-
-drop procedure make_t1_indexes;
-drop procedure make_t2_indexes;
-drop procedure remove_t1_indexes;
-drop procedure remove_t2_indexes;
-drop procedure add_materialization_data;
-drop procedure delete_materialization_data;
-drop procedure set_all_columns_not_null;
-drop procedure set_all_columns_nullable;
-drop table t1, t2, t1_1024, t2_1024;
+set names utf8;
+
+create database world;
+use world;
+
+--source include/world_schema.inc
+--disable_query_log
+--disable_result_log
+--disable_warnings
+--source include/world.inc
+--enable_warnings
+--enable_result_log
+--enable_query_log
+
+-- echo Make the schema and data more diverse by adding more indexes, nullable
+-- echo columns, and NULL data.
+create index SurfaceArea on Country(SurfaceArea);
+create index Language on CountryLanguage(Language);
+create index CityName on City(Name);
+alter table City change population population int(11) null default 0;
+
+select max(id) from City into @max_city_id;
+insert into City values (@max_city_id + 1,'Kilifarevo','BGR',NULL);
+
+
+SELECT COUNT(*) FROM Country;
+SELECT COUNT(*) FROM City;
+SELECT COUNT(*) FROM CountryLanguage;
+
+set @@optimizer_switch = 'in_to_exists=on,semijoin=on,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=on';
+
+-- echo
+-- echo 1. Subquery in a disjunctive WHERE clause of the outer query.
+-- echo
+
+-- echo
+-- echo Q1.1m:
+-- echo MATERIALIZATION: there are too many rows in the outer query
+-- echo to be looked up in the inner table.
+EXPLAIN
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+ Name LIKE 'L%') AND
+ surfacearea > 1000000;
+
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+ Name LIKE 'L%') AND
+ surfacearea > 1000000;
+
+-- echo Q1.1e:
+-- echo IN-EXISTS: the materialization cost is the same as above, but
+-- echo there are much fewer outer rows to be looked up, thus the
+-- echo materialization cost is too high to compensate for fast lookups.
+EXPLAIN
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+ Name LIKE 'L%') AND
+ surfacearea > 10*1000000;
+
+SELECT Name FROM Country
+WHERE (Code IN (select Country from City where City.Population > 100000) OR
+ Name LIKE 'L%') AND
+ surfacearea > 10*1000000;
+
+-- echo
+-- echo Q1.2m:
+-- echo MATERIALIZATION: the IN predicate is pushed (attached) to the last table
+-- echo in the join order (Country, City), therefore there are too many row
+-- echo combinations to filter by re-executing the subquery for each combination.
+EXPLAIN
+SELECT *
+ FROM Country, City
+ WHERE City.Country = Country.Code AND
+ Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+ (City.Name IN
+ (select Language from CountryLanguage where Percentage > 50) OR
+ City.name LIKE '%Island%');
+
+SELECT *
+ FROM Country, City
+ WHERE City.Country = Country.Code AND
+ Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+ (City.Name IN
+ (select Language from CountryLanguage where Percentage > 50) OR
+ City.name LIKE '%Island%');
+
+-- echo Q1.2e:
+-- echo IN_EXISTS: join order is the same, but the left IN operand refers to
+-- echo only the first table in the join order (Country), so there are much
+-- echo fewer rows to filter by subquery re-execution.
+EXPLAIN
+SELECT *
+ FROM Country, City
+ WHERE City.Country = Country.Code AND
+ Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+ (Country.Name IN
+ (select Language from CountryLanguage where Percentage > 50) OR
+ Country.name LIKE '%Island%');
+
+SELECT *
+ FROM Country, City
+ WHERE City.Country = Country.Code AND
+ Country.SurfaceArea < 3000 AND Country.SurfaceArea > 10 AND
+ (Country.Name IN
+ (select Language from CountryLanguage where Percentage > 50) OR
+ Country.name LIKE '%Island%');
+
+
+-- echo
+-- echo Q1.3:
+-- echo For the same reasons as in Q2 IN-EXISTS and MATERIALIZATION chosen
+-- echo for each respective subquery.
+EXPLAIN
+SELECT City.Name, Country.Name
+ FROM City,Country
+ WHERE City.Country = Country.Code AND
+ Country.SurfaceArea < 30000 AND Country.SurfaceArea > 10 AND
+ ((Country.Code, Country.Name) IN
+ (select Country, Language from CountryLanguage where Percentage > 50) AND
+ Country.Population > 3000000
+ OR
+ (Country.Code, City.Name) IN
+ (select Country, Language from CountryLanguage));
+
+SELECT City.Name, Country.Name
+ FROM City,Country
+ WHERE City.Country = Country.Code AND
+ Country.SurfaceArea < 30000 AND Country.SurfaceArea > 10 AND
+ ((Country.Code, Country.Name) IN
+ (select Country, Language from CountryLanguage where Percentage > 50) AND
+ Country.Population > 3000000
+ OR
+ (Country.Code, City.Name) IN
+ (select Country, Language from CountryLanguage));
+
+
+-- echo
+-- echo 2. NOT IN subqueries
+-- echo
+
+-- echo
+-- echo Q2.1:
+-- echo Number of cities that are not capitals in countries with small population.
+-- echo MATERIALIZATION is 50 times faster because the cost of each subquery
+-- echo re-execution is much higher than the cost of index lookups into the
+-- echo materialized subquery.
+
+EXPLAIN
+select count(*) from City
+where City.id not in (select capital from Country
+ where capital is not null and population < 100000);
+
+-- echo
+-- echo Q2.2e:
+-- echo Countries that speak French, but do not speak English
+-- echo IN-EXISTS because the outer query filters many rows, thus
+-- echo there are few lookups to make.
+EXPLAIN
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+ AND CountryLanguage.Language = 'French'
+ AND Code = Country;
+
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+ AND CountryLanguage.Language = 'French'
+ AND Code = Country;
+
+-- echo Q2.2m:
+-- echo Countries that speak French OR Spanish, but do not speak English
+-- echo MATERIALIZATION because the outer query filters less rows than Q5-a,
+-- echo so there are more lookups.
+EXPLAIN
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+ AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish')
+ AND Code = Country;
+
+SELECT Country.Name
+FROM Country, CountryLanguage
+WHERE Code NOT IN (SELECT Country FROM CountryLanguage WHERE Language = 'English')
+ AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish')
+ AND Code = Country;
+
+-- echo
+-- echo Q2.3e:
+-- echo Not a very meaningful query that tests NOT IN.
+-- echo IN-EXISTS because the outer query is cheap enough to reexecute many times.
+EXPLAIN
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+ (SELECT City.Name, Country.Code
+ FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000))
+ AND Language IN ('English','Spanish');
+
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+ (SELECT City.Name, Country.Code
+ FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000))
+ AND Language IN ('English','Spanish');
+
+-- echo Q2.3m:
+-- echo MATERIALIZATION with the PARTIAL_MATCH_MERGE strategy, because the HAVING
+-- echo clause prevents the use of the index on City(Name), and in practice reduces
+-- echo radically the size of the temp table.
+EXPLAIN
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+ (SELECT City.Name, Country.Code
+ FROM City LEFT JOIN Country ON (Country = Code)
+ HAVING City.Name LIKE "Santa%");
+
+select count(*)
+from CountryLanguage
+where (Language, Country) NOT IN
+ (SELECT City.Name, Country.Code
+ FROM City LEFT JOIN Country ON (Country = Code)
+ HAVING City.Name LIKE "Santa%");
+
+
+-- echo
+-- echo 3. Subqueries with GROUP BY, HAVING, and aggregate functions
+-- echo
+
+-- echo Q3.1:
+-- echo Languages that are spoken in countries with 10 or 11 languages
+-- echo MATERIALIZATION is about 100 times faster than IN-EXISTS.
+
+EXPLAIN
+select count(*)
+from CountryLanguage
+where
+(Country, 10) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+ WHERE Code = Country GROUP BY Code)
+OR
+(Country, 11) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+ WHERE Code = Country GROUP BY Code)
+order by Country;
+
+select count(*)
+from CountryLanguage
+where
+(Country, 10) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+ WHERE Code = Country GROUP BY Code)
+OR
+(Country, 11) IN (SELECT Code, COUNT(*) FROM CountryLanguage, Country
+ WHERE Code = Country GROUP BY Code)
+order by Country;
+
+
+-- echo
+-- echo Q3.2:
+-- echo Countries whose capital is a city name that names more than one
+-- echo cities.
+-- echo MATERIALIZATION because the cost of single subquery execution is
+-- echo close to that of materializing the subquery.
+
+EXPLAIN
+select * from Country, City
+where capital = id and
+ (City.name in (SELECT name FROM City
+ GROUP BY name HAVING Count(*) > 2) OR
+ capital is null);
+
+select * from Country, City
+where capital = id and
+ (City.name in (SELECT name FROM City
+ GROUP BY name HAVING Count(*) > 2) OR
+ capital is null);
+
+-- echo
+-- echo Q3.3: MATERIALIZATION is 25 times faster than IN-EXISTS
+
+EXPLAIN
+SELECT Name
+FROM Country
+WHERE Country.Code NOT IN
+ (SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1);
+
+SELECT Name
+FROM Country
+WHERE Country.Code NOT IN
+ (SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1);
+
+
+-- echo
+-- echo 4. Subqueries in the SELECT and HAVING clauses
+-- echo
+
+-- echo Q4.1m:
+-- echo Capital information about very big cities
+-- echo MATERIALIZATION
+EXPLAIN
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+
+-- echo Q4.1e:
+-- echo IN-TO-EXISTS after adding an index to make the subquery re-execution
+-- echo efficient.
+
+create index CountryCapital on Country(capital);
+
+EXPLAIN
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+
+select Name, City.id in (select capital from Country where capital is not null) as is_capital
+from City
+where City.population > 10000000;
+
+drop index CountryCapital on Country;
+
+-- echo
+-- echo Q4.2:
+-- echo MATERIALIZATION
+# TODO: the cost estimates for subqueries in the HAVING clause need to be changed
+# to take into account that the subquery predicate is executed #times ~ to the
+# number of groups, not number of rows
+EXPLAIN
+SELECT City.Name, City.Population
+FROM City JOIN Country ON City.Country = Country.Code
+GROUP BY City.Name
+HAVING City.Name IN (select Name from Country where population < 1000000);
+
+SELECT City.Name, City.Population
+FROM City JOIN Country ON City.Country = Country.Code
+GROUP BY City.Name
+HAVING City.Name IN (select Name from Country where population < 1000000);
+
+
+-- echo
+-- echo 5. Subqueries with UNION
+-- echo
+
+-- echo Q5.1:
+EXPLAIN
+SELECT * from City where (Name, 91) in
+(SELECT Name, round(Population/1000)
+ FROM City
+ WHERE Country = "IND" AND Population > 2500000
+UNION
+ SELECT Name, round(Population/1000)
+ FROM City
+ WHERE Country = "IND" AND Population < 100000);
+
+SELECT * from City where (Name, 91) in
+(SELECT Name, round(Population/1000)
+ FROM City
+ WHERE Country = "IND" AND Population > 2500000
+UNION
+ SELECT Name, round(Population/1000)
+ FROM City
+ WHERE Country = "IND" AND Population < 100000);
+
+set @@optimizer_switch='default';
+drop database world;
+-- echo
+
+
+-- echo
+-- echo TEST GROUP 2:
+-- echo Tests of various combinations of optimizer switches, types of queries,
+-- echo available indexes, column nullability, constness of tables/predicates.
+-- echo =====================================================================
+
+
+#TODO From Igor's review:
+#
+#2.1 Please add a case when two subqueries are used in the where clause
+#(or in select) of a 2-way join.
+#The first subquery is accessed after the first table, while the second
+#is accessed after the second table.
+#
+#2.2. Please add a test case when one non-correlated subquery contains
+#another non-correlated subquery.
+#Consider 4 subcases:
+# both subqueries are materialized
+# IN_EXIST transformations are applied to both subqueries
+# outer subquery is materialized while the inner subquery is not
+#(IN_EXIST transformation is applied to it)
+# inner subqyery is materialized while the outer subquery is not (
+#IN_EXIST transformation is applied to it)
+
+set optimizer_switch=@subselect_mat_cost;
diff --git a/mysql-test/t/subselect_mat_cost_bugs.test b/mysql-test/t/subselect_mat_cost_bugs.test
index 0240c9203b3..2e5dd71f9af 100644
--- a/mysql-test/t/subselect_mat_cost_bugs.test
+++ b/mysql-test/t/subselect_mat_cost_bugs.test
@@ -89,6 +89,12 @@ CREATE TABLE t1 (
INSERT INTO t1 VALUES (10,7,8,'v','v');
INSERT INTO t1 VALUES (11,1,9,'r','r');
INSERT INTO t1 VALUES (12,5,9,'a','a');
+INSERT INTO t1 VALUES (13,7,18,'v','v');
+INSERT INTO t1 VALUES (14,1,19,'r','r');
+INSERT INTO t1 VALUES (15,5,29,'a','a');
+INSERT INTO t1 VALUES (17,7,38,'v','v');
+INSERT INTO t1 VALUES (18,1,39,'r','r');
+INSERT INTO t1 VALUES (19,5,49,'a','a');
create table t1a like t1;
insert into t1a select * from t1;
@@ -326,3 +332,85 @@ select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or
select c1 from t1 where c1 in (select kp1 from t2 where kp2 = 10 and c2 = 4) or c1 > 7;
drop table t1, t2;
+
+--echo #
+--echo # LP BUG#800679: Assertion `outer_join->table_count > 0' failed in
+--echo # JOIN::choose_subquery_plan() with materialization=on,semijoin=off
+--echo #
+
+CREATE TABLE t1 ( f1 int);
+insert into t1 values (1),(2);
+CREATE TABLE t2 ( f1 int);
+insert into t2 values (1),(2);
+
+SET @@optimizer_switch='materialization=on,semijoin=off';
+
+EXPLAIN
+SELECT * FROM t1
+WHERE (f1) IN (SELECT f1 FROM t2)
+LIMIT 0;
+
+SELECT * FROM t1
+WHERE (f1) IN (SELECT f1 FROM t2)
+LIMIT 0;
+
+set @@optimizer_switch='default';
+drop table t1, t2;
+
+--echo #
+--echo # LP BUG#834492: Crash in fix_semijoin_strategies_for_picked_join_order
+--echo # with nested subqueries and LooseScan=ON
+--echo #
+
+CREATE TABLE t3 (b int) ;
+INSERT INTO t3 VALUES (0),(0);
+
+CREATE TABLE t4 (a int, b int, c int, d int, PRIMARY KEY (a)) ;
+INSERT INTO t4 VALUES (28,0,0,0),(29,3,0,0);
+
+CREATE TABLE t5 (a int, b int, c int, d int, KEY (c,b)) ;
+INSERT INTO t5 VALUES (28,0,0,0),(29,3,0,0);
+
+SET @@optimizer_switch='semijoin=ON,loosescan=ON,firstmatch=OFF,materialization=OFF';
+
+EXPLAIN SELECT *
+FROM t3
+WHERE t3.b > ALL (
+ SELECT c
+ FROM t4
+ WHERE t4.a >= t3.b
+ AND a = SOME (SELECT b FROM t5));
+
+SELECT *
+FROM t3
+WHERE t3.b > ALL (
+ SELECT c
+ FROM t4
+ WHERE t4.a >= t3.b
+ AND a = SOME (SELECT b FROM t5));
+
+set @@optimizer_switch='default';
+drop table t3, t4, t5;
+
+--echo #
+--echo # LP BUG#858038 The result of a query with NOT IN subquery depends on the state of the optimizer switch
+--echo #
+
+create table t1 (c1 char(2) not null, c2 char(2));
+create table t2 (c3 char(2), c4 char(2));
+
+insert into t1 values ('a1', 'b1');
+insert into t1 values ('a2', 'b2');
+
+insert into t2 values ('x1', 'y1');
+insert into t2 values ('a2', null);
+
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=off,partial_match_table_scan=on';
+explain select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+explain select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
+
+drop table t1, t2;
diff --git a/mysql-test/t/subselect_no_mat.test b/mysql-test/t/subselect_no_mat.test
index 5fbbef5caed..0265ec91e88 100644
--- a/mysql-test/t/subselect_no_mat.test
+++ b/mysql-test/t/subselect_no_mat.test
@@ -3,6 +3,7 @@
#
select @@optimizer_switch like '%materialization=on%';
set optimizer_switch='materialization=off';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
--source t/subselect.test
diff --git a/mysql-test/t/subselect_no_opts.test b/mysql-test/t/subselect_no_opts.test
index d72deab45bf..724cbab6310 100644
--- a/mysql-test/t/subselect_no_opts.test
+++ b/mysql-test/t/subselect_no_opts.test
@@ -1,9 +1,10 @@
#
# Run subselect.test without semi-join and materialization optimizations
# (test in-to-exists)
-set optimizer_switch='materialization=off,semijoin=off';
+
+set @optimizer_switch_for_subselect_test='materialization=off,semijoin=off,subquery_cache=off,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
--source t/subselect.test
-set optimizer_switch=default;
+set @optimizer_switch_for_subselect_test=null;
diff --git a/mysql-test/t/subselect_no_scache.test b/mysql-test/t/subselect_no_scache.test
new file mode 100644
index 00000000000..fe8ff749a59
--- /dev/null
+++ b/mysql-test/t/subselect_no_scache.test
@@ -0,0 +1,11 @@
+#
+# Run subselect.test without semi-join optimization (test materialize)
+#
+select @@optimizer_switch like '%subquery_cache=on%';
+set optimizer_switch='subquery_cache=off';
+
+--source t/subselect.test
+
+set optimizer_switch=default;
+select @@optimizer_switch like '%subquery_cache=on%';
+
diff --git a/mysql-test/t/subselect_no_semijoin.test b/mysql-test/t/subselect_no_semijoin.test
index e9f2e0654ce..c836c12ec50 100644
--- a/mysql-test/t/subselect_no_semijoin.test
+++ b/mysql-test/t/subselect_no_semijoin.test
@@ -1,8 +1,8 @@
#
# Run subselect.test without semi-join optimization (test materialize)
#
-set optimizer_switch='semijoin=off';
+set @optimizer_switch_for_subselect_test='semijoin=off,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
--source t/subselect.test
-set optimizer_switch=default;
+set @optimizer_switch_for_subselect_test=null;
diff --git a/mysql-test/t/subselect_nulls.test b/mysql-test/t/subselect_nulls.test
index 6de7820872c..4b08e773b17 100644
--- a/mysql-test/t/subselect_nulls.test
+++ b/mysql-test/t/subselect_nulls.test
@@ -5,6 +5,9 @@ drop table if exists x1;
drop table if exists x2;
--enable_warnings
+set @tmp_subselect_nulls=@@optimizer_switch;
+set optimizer_switch='semijoin=off';
+
create table x1(k int primary key, d1 int, d2 int);
create table x2(k int primary key, d1 int, d2 int);
@@ -90,5 +93,7 @@ where exists (select *
from x2
where x1.d1=x2.d1 and x1.d2=x2.d2);
+set optimizer_switch= @tmp_subselect_nulls;
+
drop table x1;
drop table x2;
diff --git a/mysql-test/t/subselect_partial_match.test b/mysql-test/t/subselect_partial_match.test
index c5167f827ab..cb25656e4fc 100644
--- a/mysql-test/t/subselect_partial_match.test
+++ b/mysql-test/t/subselect_partial_match.test
@@ -3,6 +3,221 @@
# MWL#68: Subquery optimization: Efficient NOT IN execution with NULLs
#
+set @save_optimizer_switch=@@optimizer_switch;
+
+--echo -------------------------------
+--echo Part 1: Feature tests.
+--echo -------------------------------
+
+--echo Default for all tests.
+set @@optimizer_switch="materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off";
+
+--echo
+--echo Schema requires partial matching, but data analysis discoveres there is
+--echo no need. This is possible only if all outer columns are not NULL.
+--echo
+
+create table t1 (a1 char(8) not null, a2 char(8) not null);
+create table t2 (b1 char(8), b2 char(8));
+
+insert into t1 values ('1 - 00', '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+
+insert into t2 values ('1 - 00', '2 - 00');
+insert into t2 values ('1 - 01', NULL );
+insert into t2 values (NULL , '2 - 02');
+insert into t2 values (NULL , NULL );
+insert into t2 values ('1 - 02', '2 - 02');
+
+select * from t1
+where (a1, a2) not in (select * from t2 where b1 is not null and b2 is not null);
+
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+--echo
+--echo NULLs in the outer columns, no NULLs in the suqbuery
+--echo
+
+create table t1 (a1 char(8), a2 char(8));
+create table t2 (b1 char(8) not null, b2 char(8) not null);
+
+insert into t1 values (NULL , '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+insert into t1 values (NULL , NULL );
+
+insert into t2 values ('1 - 00', '2 - 00');
+insert into t2 values ('1 - 01', '2 - 01');
+insert into t2 values ('1 - 02', '2 - 00');
+
+select * from t1
+where (a1, a2) not in (select * from t2 where b1 is not null and b2 is not null);
+
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+
+select * from t1
+where (a1, a2) in (select * from t2 where b1 is not null and b2 is not null);
+
+select a1, a2, (a1, a2) in (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+--echo
+--echo All columns require partial matching (no non-null columns)
+--echo
+
+--echo TODO
+
+--echo
+--echo Both non-NULL columns and columns with NULLs
+--echo
+
+--echo TODO
+
+--echo
+--echo Covering NULL rows
+--echo
+
+create table t1 (a1 char(8), a2 char(8));
+create table t2 (b1 char(8), b2 char(8));
+
+insert into t1 values ('1 - 00', '2 - 00');
+insert into t1 values ('1 - 01', '2 - 01');
+
+insert into t2 values ('1 - 01', NULL );
+insert into t2 values (NULL , '2 - 02');
+insert into t2 values (NULL , NULL );
+insert into t2 values ('1 - 02', '2 - 02');
+
+select * from t1
+where (a1, a2) not in (select * from t2);
+
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+
+insert into t2 values ('1 - 01', '2 - 01');
+
+select * from t1
+where (a1, a2) not in (select * from t2);
+
+select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
+
+select * from t1
+where (a1, a2) in (select * from t2);
+
+select a1, a2, (a1, a2) in (select * from t2) as in_res from t1;
+
+
+drop table t1, t2;
+
+--echo
+--echo Covering NULL columns
+--echo
+
+--echo this case affects only the rowid-merge algorithm
+set @@optimizer_switch="partial_match_rowid_merge=on,partial_match_table_scan=off";
+
+create table t1 (a1 char(8) not null, a2 char(8), a3 char(8) not null);
+create table t2 (b1 char(8) not null, b2 char(8), b3 char(8) not null);
+
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+
+insert into t2 values ('1 - 01', NULL, '3 - x1');
+insert into t2 values ('1 - 02', NULL, '3 - 02');
+insert into t2 values ('1 - 00', NULL, '3 - 00');
+
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+create table t1 (a1 char(8), a2 char(8), a3 char(8) not null);
+create table t2 (b1 char(8), b2 char(8), b3 char(8) not null);
+
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+
+insert into t2 values (NULL, NULL, '3 - x1');
+insert into t2 values (NULL, NULL, '3 - 02');
+insert into t2 values (NULL, NULL, '3 - 00');
+
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+--echo
+--echo Covering NULL row, and a NULL column
+--echo
+
+create table t1 (a1 char(8) not null, a2 char(8), a3 char(8));
+create table t2 (b1 char(8), b2 char(8), b3 char(8));
+
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+
+insert into t2 values ('1 - 01', NULL, '3 - x1');
+insert into t2 values (NULL , NULL, NULL );
+insert into t2 values ('1 - 00', NULL, '3 - 00');
+
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+
+--echo
+--echo Covering NULL row, and covering NULL columns
+--echo
+
+create table t1 (a1 char(8) not null, a2 char(8), a3 char(8));
+create table t2 (b1 char(8), b2 char(8), b3 char(8));
+
+insert into t1 values ('1 - 00', '2 - 00', '3 - 00');
+insert into t1 values ('1 - 01', '2 - 01', '3 - 01');
+
+insert into t2 values (NULL, NULL, NULL);
+insert into t2 values (NULL, NULL, NULL);
+
+select * from t1
+where (a1, a2, a3) not in (select * from t2);
+
+select *, (a1, a2, a3) not in (select * from t2) as in_res from t1;
+
+select * from t1
+where (a1, a2, a3) in (select * from t2);
+
+select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+
+--echo -------------------------------
+--echo Part 2: Test cases for bugs.
+--echo -------------------------------
+
--disable_warnings
drop table if exists t1, t2;
--enable_warnings
@@ -10,7 +225,6 @@ drop table if exists t1, t2;
--echo #
--echo # LP BUG#608744
--echo #
-set @save_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch="materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off";
create table t1 (a1 char(1), a2 char(1));
insert into t1 values (NULL, 'b');
@@ -18,7 +232,6 @@ create table t2 (b1 char(1), b2 char(2));
insert into t2 values ('a','b'), ('c', 'd');
select * from t1 where (a1, a2) NOT IN (select b1, b2 from t2);
drop table t1,t2;
-set @@optimizer_switch=@save_optimizer_switch;
--echo #
@@ -32,20 +245,17 @@ CREATE TABLE t2 (b1 int DEFAULT NULL, b2 int DEFAULT NULL);
INSERT INTO t2 VALUES (6,NULL);
INSERT INTO t2 VALUES (NULL,0);
-set @save_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on';
EXPLAIN EXTENDED
SELECT * FROM (SELECT * FROM t1 WHERE a1 NOT IN (SELECT b2 FROM t2)) table1;
DROP TABLE t1, t2;
-set @@optimizer_switch=@save_optimizer_switch;
--echo #
--echo # LP BUG#613009 Crash in Ordered_key::get_field_idx
--echo #
-set @save_optimizer_switch=@@optimizer_switch;
set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off';
create table t1 (a1 char(3) DEFAULT NULL, a2 char(3) DEFAULT NULL);
@@ -53,7 +263,6 @@ insert into t1 values (NULL, 'a21'), (NULL, 'a22');
explain select * from t1 where (a1, a2) not in (select a1, a2 from t1);
select * from t1 where (a1, a2) not in (select a1, a2 from t1);
drop table t1;
-set @@optimizer_switch=@save_optimizer_switch;
--echo #
--echo # LP BUG#680058 void Ordered_key::add_key(rownum_t):
@@ -65,8 +274,104 @@ insert into t1 values ('t', '0'), ('0', 't');
create table t2 (f3 char(1), f4 char(1));
insert into t2 values ('t', NULL), ('t', NULL), ('d', 'y');
-set @save_optimizer_switch=@@optimizer_switch;
-SET @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,semijoin=off';
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,semijoin=off';
select * from t1 where (f1, f2) not in (select * from t2);
-set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2;
+
+
+--echo #
+--echo # LP BUG#809245 Second assertion `bit < (map)->n_bits' with partial_match_merge
+--echo #
+
+CREATE TABLE t1 (d varchar(32)) ;
+INSERT INTO t1 VALUES ('r');
+
+CREATE TABLE t2 ( a int, c varchar(32)) ;
+INSERT INTO t2 VALUES (5,'r');
+
+CREATE TABLE t3 ( a int NOT NULL , d varchar(32)) ;
+INSERT INTO t3 VALUES (10,'g');
+
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+
+EXPLAIN SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+ SELECT t3.d , t2.c
+ FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+
+SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+ SELECT t3.d , t2.c
+ FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+
+EXPLAIN SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+ SELECT t3.d , t2.c
+ FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+
+SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+ SELECT t3.d , t2.c
+ FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+
+drop table t1, t2, t3;
+
+--echo #
+--echo # LP BUG#809266 Diverging results with partial_match_rowid_merge=on
+--echo #
+
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (0),(0);
+
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (6,3), (9,NULL);
+
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
+
+EXPLAIN
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
+
+drop table t1, t2;
+
+--echo #
+--echo # LP BUG#856152 Wrong result with NOT IN subquery and partial_match_rowid_merge
+--echo #
+
+CREATE TABLE t1 ( f1 integer NOT NULL , f2 integer) ;
+INSERT INTO t1 VALUES (3,3),(48,NULL),(49,1);
+
+CREATE TABLE t2 ( f3 int) ;
+INSERT INTO t2 VALUES (5);
+
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+
+set @@optimizer_switch='in_to_exists=on,materialization=off';
+EXPLAIN SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
+
+drop table t1, t2;
+
+set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test
index 86ea719e8b0..9d618a8590e 100644
--- a/mysql-test/t/subselect_sj.test
+++ b/mysql-test/t/subselect_sj.test
@@ -2,9 +2,15 @@
# Nested Loops semi-join subquery evaluation tests
#
--disable_warnings
-drop table if exists t0, t1, t2, t3, t4, t10, t11, t12;
+drop table if exists t0, t1, t2, t3, t4, t5, t10, t11, t12;
+drop view if exists v1, v2, v3, v4;
+drop procedure if exists p1;
--enable_warnings
+set @subselect_sj_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+# The 'default' value within the scope of this test:
set @save_optimizer_switch=@@optimizer_switch;
#
@@ -643,6 +649,7 @@ CREATE TABLE it1 (
);
INSERT INTO it1 VALUES
(9,5), (0,4);
+--sorted_result
SELECT int_key FROM ot1
WHERE int_nokey IN (SELECT it2.int_key
FROM it1 LEFT JOIN it2 ON it2.datetime_key);
@@ -1212,5 +1219,638 @@ LEFT JOIN t2 JOIN t3 ON t3.f10 = t2.f10 ON t3.f11 != 0 );
drop table t1,t2,t3,t4;
+--echo #
+--echo # BUG#751484: Valgrind warning / sporadic crash in evaluate_join_record sql_select.cc:14099 with semijoin
+--echo #
+
+CREATE TABLE t1 ( f10 int, f11 int, KEY (f10));
+INSERT IGNORE INTO t1 VALUES (0, 0),(0, 0);
+
+CREATE TABLE t3 ( f10 int);
+INSERT IGNORE INTO t3 VALUES (0);
+
+set @tmp_751484= @@optimizer_switch;
+set optimizer_switch='materialization=on';
+SELECT * FROM t1
+WHERE f11 IN (
+ SELECT C_SQ1_alias1.f11
+ FROM t1 AS C_SQ1_alias1
+ JOIN t3 AS C_SQ1_alias2
+ ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10
+);
+set optimizer_switch='materialization=off';
+SELECT * FROM t1
+WHERE f11 IN (
+ SELECT C_SQ1_alias1.f11
+ FROM t1 AS C_SQ1_alias1
+ JOIN t3 AS C_SQ1_alias2
+ ON C_SQ1_alias2.f10 = C_SQ1_alias1.f10
+);
+set optimizer_switch=@tmp_751484;
+drop table t1, t3;
+
+#
+--echo # BUG#795530 Wrong result with subquery semijoin materialization and outer join
+--echo # Simplified testcase that uses DuplicateElimination
+--echo #
+create table t1 (a int);
+create table t2 (a int, b char(10));
+
+insert into t1 values (1),(2);
+insert into t2 values (1, 'one'), (3, 'three');
+
+create table t3 (b char(10));
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+insert into t3 values('three'),( 'four');
+explain select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
+select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.a=t2.a);
+drop table t1, t2, t3;
+
+--echo #
+--echo # BUG#600958 RQG: Crash in optimize_semijoin_nests
+--echo #
+CREATE TABLE t1 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_key int(11) DEFAULT NULL,
+ col_date_key date DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY col_int_key (col_int_key),
+ KEY col_date_key (col_date_key),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
+INSERT INTO t1 VALUES (10,8,'2002-02-21',NULL);
+CREATE TABLE t2 (
+ pk int(11) NOT NULL AUTO_INCREMENT,
+ col_int_key int(11) DEFAULT NULL,
+ col_date_key date DEFAULT NULL,
+ col_varchar_key varchar(1) DEFAULT NULL,
+ PRIMARY KEY (pk),
+ KEY col_int_key (col_int_key),
+ KEY col_date_key (col_date_key),
+ KEY col_varchar_key (col_varchar_key,col_int_key)
+) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
+INSERT INTO t2 VALUES (1,7,'1900-01-01','f');
+
+SELECT col_date_key FROM t1
+WHERE 5 IN (
+ SELECT SUBQUERY3_t1 .col_int_key
+ FROM t2 SUBQUERY3_t1
+ LEFT JOIN t1 SUBQUERY3_t2 ON SUBQUERY3_t1 .col_varchar_key
+);
+drop table t2, t1;
+
+
+--echo #
+--echo # No BUG#: Duplicate weedout check is not done for outer joins
+--echo #
+create table t1 (a int);
+create table t2 (a int);
+
+insert into t1 values (1),(1),(2),(2);
+insert into t2 values (1);
+
+create table t0 (a int);
+insert into t0 values (1),(2);
+
+set @tmp_20110622= @@optimizer_switch;
+set optimizer_switch='firstmatch=off,loosescan=off,materialization=off';
+--echo # Check DuplicateWeedout + join buffer
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+
+--echo # Check DuplicateWeedout without join buffer
+set @tmp_jcl_20110622= @@join_cache_level;
+set join_cache_level= 0;
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+
+
+--echo # Check FirstMatch without join buffer:
+set optimizer_switch='firstmatch=on';
+explain
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
+
+--echo #
+--echo # Now, check the same for multiple inner tables:
+alter table t2 add b int;
+update t2 set b=a;
+create table t3 as select * from t2;
+
+set optimizer_switch='firstmatch=off';
+set join_cache_level= 0;
+--echo # DuplicateWeedout without join buffer
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+
+set @@join_cache_level=@tmp_jcl_20110622;
+--echo # DuplicateWeedout + join buffer
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+
+--echo # Now, let the inner join side have a 'partial' match
+select * from t3;
+insert into t3 values(2,2);
+
+explain
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+
+select * from t0
+where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
+
+set @@optimizer_switch=@tmp_20110622;
+
+drop table t0, t1, t2, t3;
+
+--echo #
+--echo # BUG#802965: Crash in do_copy_not_null with semijoin=on in maria-5.3
+--echo #
+set @save_802965= @@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=off,firstmatch=off,loosescan=off';
+
+CREATE TABLE t2 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t2 VALUES (19),(20);
+
+CREATE TABLE t1 ( f1 int NOT NULL , PRIMARY KEY (f1)) ;
+INSERT IGNORE INTO t1 VALUES (21),(22),(23),(24);
+
+SELECT *
+FROM t2 , t1
+WHERE t2.f1 IN
+(
+ SELECT SQ1_alias1.f1
+ FROM t1 AS SQ1_alias1 LEFT JOIN t2 AS SQ1_alias2 JOIN t2 AS SQ1_alias3 ON SQ1_alias3.f1 ON SQ1_alias3.f1
+)
+AND t1.f1 = t2.f1 ;
+
+DROP TABLE t1, t2;
+set optimizer_switch=@save_802965;
+
+--echo #
+--echo # BUG#803365: Crash in pull_out_semijoin_tables with outer join + semijoin + derived tables in maria-5.3 with WL#106
+--echo #
+CREATE TABLE t1 ( f1 int) ;
+INSERT INTO t1 VALUES (1),(1);
+
+CREATE TABLE t2 ( f2 int) ;
+INSERT INTO t2 VALUES (1),(1);
+
+CREATE TABLE t3 ( f3 int) ;
+INSERT INTO t3 VALUES (1),(1);
+
+SELECT *
+FROM t1
+WHERE t1.f1 IN (
+ SELECT t2.f2
+ FROM t2
+ LEFT JOIN (
+ SELECT *
+ FROM t3
+ ) AS alias1
+ ON alias1.f3 = t2.f2
+);
+
+DROP TABLE t1,t2,t3;
+
+
+--echo #
+--echo # BUG#611704: Crash in replace_where_subcondition with nested subquery and semijoin=on
+--echo #
+
+CREATE TABLE t1 ( f1 int) ;
+CREATE TABLE t2 ( f1 int) ;
+CREATE TABLE t3 ( f1 int) ;
+
+SELECT * FROM (
+ SELECT t3.*
+ FROM t2 STRAIGHT_JOIN t3
+ ON t3.f1
+ AND (t3.f1 ) IN (
+ SELECT t1.f1
+ FROM t1
+ )
+) AS alias1;
+DROP TABLE t1,t2,t3;
+
+--echo # BUG#611704: another testcase:
+CREATE TABLE t1 ( f1 int(11), f3 varchar(1), f4 varchar(1)) ;
+CREATE TABLE t2 ( f2 int(11), KEY (f2));
+CREATE TABLE t3 ( f4 varchar(1)) ;
+
+PREPARE st1 FROM '
+SELECT *
+FROM t1
+STRAIGHT_JOIN ( t2 STRAIGHT_JOIN t3 ON t2.f2 )
+ON (t1.f3) IN ( SELECT f4 FROM t1 )
+';
+EXECUTE st1;
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
+--echo # (Original testcase)
+--echo #
+
+CREATE TABLE t1 (f1 int, f2 int );
+INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL);
+
+CREATE TABLE t2 (f2 int, f3 int );
+INSERT INTO t2 VALUES (NULL,NULL),(0,0);
+
+CREATE TABLE t3 ( f1 int, f3 int );
+INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0);
+
+CREATE TABLE t4 ( f2 int, KEY (f2) );
+INSERT INTO t4 VALUES (0),(NULL);
+
+CREATE VIEW v4 AS SELECT DISTINCT f2 FROM t4 ;
+
+--echo # The following must not have outer joins:
+explain extended
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
+
+drop view v4;
+drop table t1, t2, t3, t4;
+
+--echo #
+--echo # BUG#803303: Wrong result with semijoin=on, outer join in maria-5.3-subqueries-mwl90
+--echo #
+
+--echo # Testcase#1:
+set @tmp803303= @@optimizer_switch;
+set optimizer_switch = 'semijoin=on,materialization=off,firstmatch=off,loosescan=off';
+CREATE TABLE t2 ( f1 int) ;
+INSERT IGNORE INTO t2 VALUES (6),(8);
+CREATE TABLE t1 ( f1 int, f2 int, f3 int) ;
+INSERT IGNORE INTO t1 VALUES (8,0,0),(7,0,0),(9,0,0);
+SELECT alias2.f1
+FROM t2 AS alias1
+LEFT JOIN ( t1 AS alias2 JOIN t1 AS alias3 ON alias3.f2 = alias2.f3 )
+ON alias3.f2 = alias2.f2
+WHERE alias2.f1 IN ( SELECT f1 FROM t2 AS alias4 ) ;
+drop table t1,t2;
+set optimizer_switch= @tmp803303;
+
+--echo # Testcase #2:
+CREATE TABLE t1 ( f10 int) ;
+INSERT INTO t1 VALUES (0),(0);
+
+CREATE TABLE t2 ( f10 int, f11 varchar(1)) ;
+INSERT INTO t2 VALUES (0,'a'),(0,'b');
+
+CREATE TABLE t3 ( f10 int) ;
+INSERT INTO t3 VALUES (0),(0),(0),(0),(0);
+
+CREATE TABLE t4 ( f10 varchar(1), f11 int) ;
+INSERT INTO t4 VALUES ('a',0),('b',0);
+
+SELECT * FROM t1
+LEFT JOIN ( t2 JOIN t3 ON t3.f10 = t2.f10 ) ON t1.f10 = t2.f10
+WHERE t2.f10 IN (
+ SELECT t4.f11
+ FROM t4
+ WHERE t4.f10 != t2.f11
+);
+
+drop table t1,t2,t3,t4;
+
+--echo #
+--echo # BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
+--echo #
+set @tmp803457=@@optimizer_switch;
+set optimizer_switch='materialization=off';
+CREATE TABLE t1 (f1 int, f2 int );
+INSERT INTO t1 VALUES (2,0),(4,0),(0,NULL);
+
+CREATE TABLE t2 (f2 int, f3 int );
+INSERT INTO t2 VALUES (NULL,NULL),(0,0);
+
+CREATE TABLE t3 ( f1 int, f3 int );
+INSERT INTO t3 VALUES (2,0),(4,0),(0,NULL),(4,0),(8,0);
+
+CREATE TABLE t4 ( f2 int);
+INSERT INTO t4 VALUES (0),(NULL);
+
+--echo # The following uses Duplicate Weedout, and "End temporary" must not be
+--echo # in the middle of the inner side of an outer join:
+explain
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
+SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3 ) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
+
+DROP TABLE t1, t2, t3, t4;
+set @tmp803457=@@optimizer_switch;
+
+--echo #
+--echo # BUG#818280: crash in do_copy_not_null() in maria-5.3 with semijoin
+--echo #
+CREATE TABLE t1 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ;
+INSERT IGNORE INTO t1 VALUES (2,7),(1,3),(5,6);
+
+CREATE TABLE t3 ( c1 int NOT NULL , c2 int NOT NULL, PRIMARY KEY (c1)) ;
+INSERT IGNORE INTO t3 VALUES (2,7),(1,3),(5,6);
+
+CREATE TABLE t2 ( c1 int NOT NULL , c5 int NOT NULL );
+INSERT IGNORE INTO t2 VALUES (2,2),(2,2),(5,6);
+
+SELECT * FROM t1 WHERE c1 IN ( SELECT t3.c1 FROM t3 LEFT JOIN t2 ON t2 .c1 = t3 .c1 WHERE t2.c5 != 0 );
+
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # BUG#834534: Assertion `0' failed in replace_where_subcondition with semijoin subquery in HAVING
+--echo #
+CREATE TABLE t1 ( d int );
+INSERT INTO t1 VALUES (2),(2),(0),(2),(2);
+
+CREATE TABLE t2 ( b int );
+INSERT INTO t2 VALUES (4),(3),(3);
+
+CREATE TABLE t3 ( a int );
+
+SELECT *
+FROM t3
+WHERE (t3.a) IN (
+ SELECT t1.d
+ FROM t1
+ HAVING ( 4 ) IN (
+ SELECT t2.b
+ FROM t2
+ )
+);
+drop table t1, t2,t3;
+
+--echo #
+--echo # BUG#834758: Wrong result with innner join, LooseScan, two-column IN() predicate
+--echo #
+
+set @tmp835758=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
+
+CREATE TABLE t1 (b int) ;
+INSERT INTO t1 VALUES (1),(5);
+
+CREATE TABLE t2 (a int, PRIMARY KEY (a)) ;
+INSERT INTO t2 VALUES (6),(10);
+
+CREATE TABLE t3 (a int, b int, KEY (b)) ;
+INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5);
+
+--echo # This used to incorrectly pick a join order of (t1, LooseScan(t3), t2):
+explain
+SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
+SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
+
+DROP TABLE t1, t2, t3;
+set @@optimizer_switch= @tmp835758;
+
+--echo #
+--echo # BUG#834739: Wrong result with 3-way inner join, LooseScan,multipart keys
+--echo #
+set @tmp834739=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=on,materialization=off,firstmatch=off';
+CREATE TABLE t2 ( b int, c int, KEY (b)) ;
+INSERT INTO t2 VALUES (1,0),(1,0),(9,0),(1,0),(5,0);
+INSERT INTO t2 VALUES (2,0),(3,0),(8,0),(6,0),(5,0);
+
+CREATE TABLE t3 ( a int);
+INSERT INTO t3 VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0),(0);
+
+CREATE TABLE t4 ( a int);
+INSERT INTO t4 VALUES (0),(0),(0);
+
+CREATE TABLE t5 ( b int, a int , KEY (a,b)) ;
+INSERT INTO t5 VALUES (7,0),(9,0);
+
+explain
+SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
+SELECT * FROM t3 WHERE t3.a IN (SELECT t5.a FROM t2, t4, t5 WHERE t2.c = t5.a AND t2.b = t5.b);
+
+DROP TABLE t2, t3, t4, t5;
+set @@optimizer_switch=@tmp834739;
+
+--echo #
+--echo # BUG#830993: Crash in end_read_record with derived table
+--echo #
+set @tmp_830993=@@optimizer_switch;
+set optimizer_switch='semijoin=on,loosescan=off,materialization=off,firstmatch=off';
+set @tmp_830993_jbs= @@join_buffer_size;
+--disable_warnings
+set join_buffer_size=160;
+--enable_warnings
+CREATE TABLE t1 (
+ a int(11) NOT NULL AUTO_INCREMENT,
+ b int(11) DEFAULT NULL,
+ c int(11) DEFAULT NULL,
+ d time DEFAULT NULL,
+ e varchar(1) DEFAULT NULL,
+ f varchar(1) DEFAULT NULL,
+ PRIMARY KEY (a),
+ KEY c (c),
+ KEY d (d),
+ KEY e (e,c)
+);
+INSERT INTO t1 VALUES (10,NULL,8,'22:55:23','x','x'),
+ (11,8,7,'10:19:31','d','d'),(12,1,1,'14:40:36','r','r'),
+ (13,9,7,'04:37:47','f','f'),(14,4,9,'19:34:06','y','y'),
+ (15,3,NULL,'20:35:33','u','u'),(16,2,1,NULL,'m','m'),
+ (17,NULL,9,'14:43:37',NULL,NULL),(18,2,2,'02:23:09','o','o'),
+ (19,NULL,9,'01:22:45','w','w'),(20,6,2,'00:00:00','m','m'),
+ (21,7,4,'00:13:25','q','q'),(22,2,0,'03:47:16',NULL,NULL),
+ (23,5,4,'01:41:48','d','d'),(24,7,8,'00:00:00','g','g'),
+ (25,6,NULL,'22:32:04','x','x'),(26,6,NULL,'16:44:14','f','f'),
+ (27,2,0,'17:38:37','p','p'),(28,9,NULL,'08:46:48','j','j'),
+ (29,6,8,'14:11:27','c','c');
+
+CREATE TABLE t2 like t1;
+INSERT INTO t2 VALUES (1,2,4,'22:34:09','v','v'),
+ (2,150,62,'14:26:02','v','v'),(3,NULL,7,'14:03:03','c','c'),
+ (4,2,1,'01:46:09',NULL,NULL),(5,5,0,'16:21:18','x','x'),
+ (6,3,7,'18:56:33','i','i'),(7,1,7,NULL,'e','e'),
+ (8,4,1,'09:29:08','p','p'),(9,NULL,7,'19:11:10','s','s'),
+ (10,2,1,'11:57:26','j','j'),(11,6,5,'00:39:46','z','z'),
+ (12,6,2,'03:28:15','c','c'),(13,8,0,'06:44:18','a','a'),
+ (14,2,1,'14:36:39','q','q'),(15,6,8,'18:42:45','y','y'),
+ (16,8,1,'02:57:29',NULL,NULL),(17,3,1,'16:46:13','r','r'),
+ (18,3,9,'19:39:02','v','v'),(19,9,1,NULL,NULL,NULL),
+ (20,6,5,'20:58:33','r','r');
+
+explain
+SELECT
+ alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
+ alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
+ alias2.e as a2_e, alias2.f as a2_f,
+ t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
+FROM
+ (SELECT * FROM t2) AS alias1,
+ t1 AS alias2,
+ t2
+WHERE
+ alias1.c IN (SELECT SQ3_alias1.b
+ FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
+LIMIT 100;
+
+create table t3 as
+SELECT
+ alias1.a, alias1.b, alias1.c, alias1.d, alias1.e, alias1.f,
+ alias2.a as a2_a, alias2.b as a2_b, alias2.c as a2_c, alias2.d as a2_d,
+ alias2.e as a2_e, alias2.f as a2_f,
+ t2.a as t2_a, t2.b as t2_b, t2.c as t2_c, t2.d as t2_d, t2.e as t2_e, t2.f as t2_f
+FROM
+ (SELECT * FROM t2) AS alias1,
+ t1 AS alias2,
+ t2
+WHERE
+ alias1.c IN (SELECT SQ3_alias1.b
+ FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
+LIMIT 100;
+
+drop table t1,t2, t3;
+set optimizer_switch=@tmp_830993;
+set join_buffer_size= @tmp_830993_jbs;
+
+--echo #
+--echo # BUG##849717: Crash in Item_func::fix_fields on second execution of a prepared statement with semijoin
+--echo #
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (a int);
+CREATE TABLE t3 (a int, b int) ;
+
+PREPARE st1 FROM "SELECT * FROM t2 LEFT JOIN t1 ON t2.a != 0 AND ('j','r') IN ( SELECT b,a FROM t3)";
+EXECUTE st1;
+EXECUTE st1;
+
+DROP TABLE t1, t2, t3;
+
+--echo #
+--echo # BUG#849776: Wrong result with semijoin + "Impossible where"
+--echo #
+CREATE TABLE t1 ( b varchar(1), a integer) ;
+INSERT INTO t1 VALUES ('z',8);
+
+CREATE TABLE t2 ( a integer, b varchar(1)) ;
+
+CREATE TABLE t4 ( a integer, b varchar(1)) ;
+
+CREATE TABLE t5 ( a integer) ;
+INSERT INTO t5 VALUES (8);
+
+select * from t5 where (a) in (
+ SELECT t1.a
+ FROM t1 LEFT JOIN t2 ON t1.a = t2.a
+ WHERE t2.b NOT IN (SELECT t4.b FROM t4 WHERE t4.b < t1.b)
+);
+
+DROP TABLE t1, t2, t4, t5;
+
+--echo #
+--echo # BUG#861147: Assertion `fixed == 1' failed in Item_func_eq::val_int() with semijoin + materialization + max_join_size
+--echo #
+CREATE TABLE t1 ( f2 int) ;
+CREATE TABLE t2 ( f1 int, f3 int, f4 varchar(3), f5 varchar(35)) ;
+INSERT INTO t2 VALUES (4057,9,'USA','Visalia'),(3993,11,'USA','Waco'),
+ (3948,14,'USA','Warren'),(3813,57,'USA','Washington'),
+ (4010,11,'USA','Waterbury'),(4017,11,'USA','West Covina'),
+ (4004,11,'USA','West Valley City'),(4033,10,'USA','Westminster'),
+ (3842,34,'USA','Wichita'),(4018,10,'USA','Wichita Falls'),
+ (3899,19,'USA','Winston-Salem'),(3914,17,'USA','Worcester'),
+ (3888,20,'USA','Yonkers');
+
+CREATE TABLE t3 ( f3 int, f4 varchar(3)) ;
+INSERT INTO t3 VALUES (86,'USA');
+
+CREATE TABLE t4 ( f3 int, f4 varchar(3), f5 varchar(52)) ;
+INSERT INTO t4 VALUES (0,'RUS','Belorussian'),(0,'USA','Portuguese');
+
+CREATE TABLE t5 ( f2 int) ;
+
+CREATE TABLE t6 ( f4 varchar(3));
+INSERT INTO t6 VALUES ('RUS'),('USA');
+
+set @tmp_mjs_861147= @@max_join_size;
+SET max_join_size=10;
+set @tmp_os_861147= @@optimizer_switch;
+set @@optimizer_switch='semijoin=on,materialization=on';
+
+--error ER_TOO_BIG_SELECT
+SELECT *
+FROM t1
+WHERE ( 1 , 3 ) IN (
+ SELECT t2.f1 , MAX( t3.f3 )
+ FROM t2
+ JOIN t3
+ WHERE t3.f4 IN (
+ SELECT t4.f5
+ FROM t4
+ STRAIGHT_JOIN t5
+ WHERE t4.f4 < t2.f5
+ )
+) AND ( 'p' , 'k' ) IN (
+ SELECT f4 , f4 FROM t6
+);
+set max_join_size= @tmp_mjs_861147;
+set optimizer_switch= @tmp_os_861147;
+
+DROP TABLE t1,t2,t3,t4,t5,t6;
+
+--echo #
+--echo # BUG#877288: Wrong result with semijoin + materialization + multipart key
+--echo #
+set @tmp_877288=@@optimizer_switch;
+set optimizer_switch='semijoin=ON,materialization=ON';
+CREATE TABLE t1 ( a int) ;
+INSERT INTO t1 VALUES (19),(19),(19),(20),(20),(20),(20),(20),(20);
+
+CREATE TABLE t2 ( b int NOT NULL , c int NOT NULL , KEY (b,c)) ;
+INSERT INTO t2 VALUES (14,1),(15,1),(16,1),(17,1),(18,1),(19,1),(20,1);
+
+CREATE TABLE t3 ( a int, d int) ;
+INSERT INTO t3 VALUES (19,1),(7,1),(3,1),(3,1),(20,1),(3,1),(16,1),(17,1),(9,1),(4,1),(6,1),(15,1),(17,1);
+
+explain
+SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
+SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@tmp_877288;
+
+--echo #
+--echo # BUG#878753: Assertion '0' failed in replace_where_subcondition with derived_merge
+--echo #
+set @tmp878753= @@optimizer_switch;
+set optimizer_switch= 'semijoin=on,derived_merge=on';
+CREATE TABLE t1 (b int(11)) ;
+CREATE TABLE t2 (c int, b int, d varchar(52) NOT NULL) ;
+CREATE TABLE t3 (b int(11)) ;
+
+PREPARE st1 FROM '
+ SELECT * FROM t1
+ JOIN (
+ SELECT t2.* FROM t2
+ WHERE t2.d <> "a"
+ AND t2.c IN (
+ SELECT t3.b
+ FROM t3
+ )
+ ) AS alias2
+ ON ( alias2.b = t1.b );
+';
+EXECUTE st1;
+DROP TABLE t1,t2,t3;
+set optimizer_switch=@tmp878753;
+
# The following command must be the last one the file
-set @@optimizer_switch=@save_optimizer_switch;
+set optimizer_switch=@subselect_sj_tmp;
diff --git a/mysql-test/t/subselect_sj2.test b/mysql-test/t/subselect_sj2.test
index f4573a94407..b2721574deb 100644
--- a/mysql-test/t/subselect_sj2.test
+++ b/mysql-test/t/subselect_sj2.test
@@ -2,6 +2,10 @@
# DuplicateElimination strategy test
#
--source include/have_innodb.inc
+
+set @subselect_sj2_tmp= @@optimizer_switch;
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
--disable_warnings
drop table if exists t0, t1, t2, t3;
drop view if exists v1;
@@ -24,6 +28,7 @@ create table t2 (
key(b)
);
insert into t2 select a, a/2 from t0;
+insert into t2 select a+10, a+10/2 from t0;
select * from t1;
select * from t2;
@@ -39,6 +44,8 @@ create table t3 (
primary key(pk1, pk2, pk3)
) engine=innodb;
insert into t3 select a,a, a,a,a from t0;
+insert into t3 select a,a, a+100,a+100,a+100 from t0;
+
explain select * from t3 where b in (select a from t1);
select * from t3 where b in (select a from t1);
@@ -571,6 +578,7 @@ insert into t0 values (0),(1),(2),(3),(4);
create table t1 (a int, b int, key(a));
insert into t1 select a,a from t0;
+insert into t1 select a+5,a from t0;
create table t2 (a int, b int, primary key(a));
insert into t2 select * from t1;
@@ -939,3 +947,124 @@ WHERE alias2.f11 IN (
)
GROUP BY field2;
drop table t1, t2, t3;
+
+--echo #
+--echo # BUG#849763: Wrong result with second execution of prepared statement with semijoin + view
+--echo #
+CREATE TABLE t1 ( c varchar(1)) engine=innodb;
+INSERT INTO t1 VALUES ('r');
+
+CREATE TABLE t2 ( a integer, b varchar(1), c varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES (1,'r','r');
+
+CREATE OR REPLACE VIEW v1 AS SELECT * FROM t1;
+
+PREPARE st1 FROM 'SELECT * FROM t2 WHERE a = SOME (SELECT a FROM v1 WHERE v1.c = t2.c)';
+EXECUTE st1;
+EXECUTE st1;
+
+DROP VIEW v1;
+DROP TABLE t1, t2;
+
+--echo #
+--echo # BUG#858732: Wrong result with semijoin + loosescan + comma join
+--echo #
+CREATE TABLE t1 (f13 int(11) NOT NULL , PRIMARY KEY (f13)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (16),(24);
+
+CREATE TABLE t2 (f14 int(11) NOT NULL, f12 varchar(1) NOT NULL, KEY (f12,f14)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (6,'y');
+
+CREATE TABLE t3 (f12 varchar(1) NOT NULL) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('r'),('s'),('t'),('v'),('w'),('x'),('y');
+
+--echo # The following must use LooseScan but not join buffering
+explain
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+
+SELECT * FROM t3
+WHERE f12 IN (SELECT alias2.f12 FROM t1 AS alias1, t2 AS alias2, t1 WHERE alias1.f13 = 24);
+
+DROP TABLE t1,t2,t3;
+
+--echo #
+--echo # BUG#869012: Wrong result with semijoin + materialization + AND in WHERE
+--echo #
+CREATE TABLE t1 (f3 varchar(1) , f4 varchar(1) ) engine=InnoDB;
+INSERT IGNORE INTO t1 VALUES ('x','x'),('x','x');
+CREATE TABLE t2 ( f4 varchar(1) ) ;
+INSERT IGNORE INTO t2 VALUES ('g');
+CREATE TABLE t3 (f4 varchar(1) ) Engine=InnoDB;
+INSERT IGNORE INTO t3 VALUES ('x');
+
+set @tmp_869012=@@optimizer_switch;
+SET optimizer_switch='semijoin=on,materialization=on';
+SELECT *
+FROM t1 , t2
+WHERE ( t1.f4 ) IN ( SELECT f4 FROM t3 )
+AND t2.f4 != t1.f3 ;
+set optimizer_switch= @tmp_869012;
+
+DROP TABLE t1,t2,t3;
+
+
+--echo #
+--echo # BUG#869001: Wrong result with semijoin + materialization + firstmatch + multipart key
+--echo #
+set @tmp869001_jcl= @@join_cache_level;
+set @tmp869001_os= @@optimizer_switch;
+SET join_cache_level=0;
+SET optimizer_switch='materialization=on,semijoin=on,firstmatch=on,loosescan=off';
+
+CREATE TABLE t1 ( f2 int, f3 varchar(1), KEY (f3,f2)) engine=innodb;
+INSERT INTO t1 VALUES (8,'x'),(NULL,'x'),(8,'c');
+
+CREATE TABLE t2 ( f4 varchar(1)) engine=innodb;
+INSERT INTO t2 VALUES ('x');
+
+CREATE TABLE t3 ( f1 int) engine=innodb;
+INSERT INTO t3 VALUES (8),(6),(2),(9),(6);
+
+CREATE TABLE t4 ( f3 varchar(1)) engine=innodb;
+INSERT INTO t4 VALUES ('p'),('j'),('c');
+
+SELECT *
+FROM t1 JOIN t2 ON (t2.f4 = t1.f3 )
+WHERE ( 8 ) IN (
+ SELECT t3.f1 FROM t3 , t4
+);
+
+DROP TABLE t1, t2, t3, t4;
+set join_cache_level= @tmp869001_jcl;
+set optimizer_switch= @tmp869001_os;
+
+--echo #
+--echo # Bug #881318: join cache + duplicate elimination + left join
+--echo # with empty materialized derived inner table
+--echo #
+
+CREATE TABLE t1 (b varchar(1)) ENGINE=InnoDB;
+
+CREATE TABLE t2 (a varchar(1)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES ('a');
+
+CREATE TABLE t3 (a varchar(1), b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t3 VALUES ('c','c');
+
+CREATE TABLE t4 (b varchar(1)) ENGINE=InnoDB;
+INSERT INTO t4 VALUES ('c'), ('b');
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
+
+EXPLAIN
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+ WHERE t3.b IN (SELECT b FROM t4);
+SELECT * FROM t3 LEFT JOIN (v1,t2) ON t3.a = t2.a
+ WHERE t3.b IN (SELECT b FROM t4);
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3,t4;
+
+--echo # This must be the last in the file:
+set optimizer_switch=@subselect_sj2_tmp;
diff --git a/mysql-test/t/subselect_sj2_jcl6.test b/mysql-test/t/subselect_sj2_jcl6.test
index 5292a56f266..e4ae249c711 100644
--- a/mysql-test/t/subselect_sj2_jcl6.test
+++ b/mysql-test/t/subselect_sj2_jcl6.test
@@ -3,8 +3,10 @@
#
set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set join_cache_level=6;
show variables like 'join_cache_level';
diff --git a/mysql-test/t/subselect_sj2_mat.test b/mysql-test/t/subselect_sj2_mat.test
index 643a287a897..fdfa0f311d3 100644
--- a/mysql-test/t/subselect_sj2_mat.test
+++ b/mysql-test/t/subselect_sj2_mat.test
@@ -2,6 +2,7 @@
# Run subselect_sj2.test with subquery materialization.
#
set optimizer_switch='materialization=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
--source t/subselect_sj2.test
diff --git a/mysql-test/t/subselect_sj_jcl6.test b/mysql-test/t/subselect_sj_jcl6.test
index 086d3bfaa4e..e475adbf9a8 100644
--- a/mysql-test/t/subselect_sj_jcl6.test
+++ b/mysql-test/t/subselect_sj_jcl6.test
@@ -3,9 +3,12 @@
#
set @save_optimizer_switch_jcl6=@@optimizer_switch;
+set @@optimizer_switch='optimize_join_buffer_size=on';
+set @@optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
set @@optimizer_switch='semijoin_with_cache=on';
set @@optimizer_switch='outer_join_with_cache=on';
set @@optimizer_switch='join_cache_hashed=off';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set join_cache_level=6;
show variables like 'join_cache_level';
@@ -19,6 +22,8 @@ CREATE TABLE t0 (a INT);
INSERT INTO t0 VALUES (0),(1),(2),(3),(4);
CREATE TABLE t1 (a INT, b INT, KEY(a));
INSERT INTO t1 SELECT a, a from t0;
+INSERT INTO t1 SELECT a+5, a from t0;
+INSERT INTO t1 SELECT a+10, a from t0;
CREATE TABLE t2 (a INT, b INT, PRIMARY KEY(a));
INSERT INTO t2 SELECT * FROM t1;
UPDATE t1 SET a=3, b=11 WHERE a=4;
diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test
index 728945be880..ef4a40172e2 100644
--- a/mysql-test/t/subselect_sj_mat.test
+++ b/mysql-test/t/subselect_sj_mat.test
@@ -3,8 +3,13 @@
# (WL#1110: Subquery optimization: materialization)
#
+set @subselect_sj_mat_tmp= @@optimizer_switch;
+set optimizer_switch=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on');
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set @optimizer_switch_local_default= @@optimizer_switch;
+
--disable_warnings
-drop table if exists t1, t2, t3, t1i, t2i, t3i;
+drop table if exists t1, t2, t3, t4, t5, t1i, t2i, t3i;
drop table if exists columns;
drop table if exists t1_16, t2_16, t3_16;
drop view if exists v1, v2, v1m, v2m;
@@ -121,20 +126,26 @@ select * from t1 where (a1, a2) in (select b1, min(b2) from t2i limit 1,1);
# test re-optimization/re-execution with different execution methods
# prepare once, exec with different modes
set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch='default,semijoin=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
prepare st1 from
"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
execute st1;
-set @@optimizer_switch='default,semijoin=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
execute st1;
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
prepare st1 from
"select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1)";
-set @@optimizer_switch='default,semijoin=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
execute st1;
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
execute st1;
set @@optimizer_switch=@save_optimizer_switch;
@@ -826,18 +837,21 @@ explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
# Query with group by, executed via IN=>EXISTS
set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
# Executed with materialization
-set @@optimizer_switch='default,semijoin=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='semijoin=off';
explain select min(a1) from t1 where 7 in (select b1 from t2);
select min(a1) from t1 where 7 in (select b1 from t2);
# Executed with semi-join. Notice, this time we get a different result (NULL).
# This is the only correct result of all four queries. This difference is
# filed as BUG#40037.
-set @@optimizer_switch='default,materialization=off';
+set @@optimizer_switch=@optimizer_switch_local_default;
+set @@optimizer_switch='materialization=off,in_to_exists=on';
-- echo # with MariaDB and MWL#90, this particular case is solved:
explain select min(a1) from t1 where 7 in (select b1 from t2);
select min(a1) from t1 where 7 in (select b1 from t2);
@@ -861,6 +875,259 @@ execute st1;
execute st1;
drop table t1;
+--echo #
+--echo # BUG#49630: Segfault in select_describe() with double
+--echo # nested subquery and materialization
+--echo #
+
+CREATE TABLE t1 (t1i int);
+CREATE TABLE t2 (t2i int);
+CREATE TABLE t3 (t3i int);
+CREATE TABLE t4 (t4i int);
+
+INSERT INTO t1 VALUES (1); # Note: t1 must be const table
+INSERT INTO t2 VALUES (1),(2);
+INSERT INTO t3 VALUES (1),(2);
+INSERT INTO t4 VALUES (1),(2);
+
+--echo
+EXPLAIN
+SELECT t1i
+FROM t1 JOIN t4 ON t1i=t4i
+WHERE (t1i) IN (
+ SELECT t2i
+ FROM t2
+ WHERE (t2i) IN (
+ SELECT t3i
+ FROM t3
+ GROUP BY t3i
+ )
+ );
+
+DROP TABLE t1,t2,t3,t4;
+
+
+#
+# Bug #52538 Valgrind bug: Item_in_subselect::init_left_expr_cache()
+#
+CREATE TABLE t1 (
+ pk INTEGER AUTO_INCREMENT,
+ col_int_nokey INTEGER,
+ col_int_key INTEGER,
+
+ col_varchar_key VARCHAR(1),
+
+ PRIMARY KEY (pk),
+ KEY (col_int_key),
+ KEY (col_varchar_key, col_int_key)
+)
+;
+
+INSERT INTO t1 (
+ col_int_key, col_int_nokey, col_varchar_key
+)
+VALUES
+(2, NULL, 'w'),
+(9, 7, 'm'),
+(3, 9, 'm'),
+(9, 7, 'k'),
+(NULL, 4, 'r'),
+(9, 2, 't'),
+(3, 6, 'j'),
+(8, 8, 'u'),
+(8, NULL, 'h'),
+(53, 5, 'o'),
+(0, NULL, NULL),
+(5, 6, 'k'),
+(166, 188, 'e'),
+(3, 2, 'n'),
+(0, 1, 't'),
+(1, 1, 'c'),
+(9, 0, 'm'),
+(5, 9, 'y'),
+(6, NULL, 'f'),
+(2, 4, 'd')
+;
+
+SELECT table2.col_varchar_key AS field1,
+ table2.col_int_nokey AS field2
+FROM ( t1 AS table1 LEFT OUTER JOIN t1 AS table2
+ ON (table2.col_varchar_key = table1.col_varchar_key ) )
+WHERE table1.pk = 6
+HAVING ( field2 ) IN
+( SELECT SUBQUERY2_t2.col_int_nokey AS SUBQUERY2_field2
+ FROM ( t1 AS SUBQUERY2_t1 JOIN t1 AS SUBQUERY2_t2
+ ON (SUBQUERY2_t2.col_varchar_key = SUBQUERY2_t1.col_varchar_key ) ) )
+ORDER BY field2
+;
+
+drop table t1;
+
+
+--echo #
+--echo # BUG#53103: MTR test ps crashes in optimize_cond()
+--echo # when running with --debug
+--echo #
+
+CREATE TABLE t1(track varchar(15));
+
+INSERT INTO t1 VALUES ('CAD'), ('CAD');
+
+PREPARE STMT FROM
+"SELECT 1 FROM t1
+ WHERE
+ track IN (SELECT track FROM t1
+ GROUP BY track
+ HAVING track>='CAD')";
+EXECUTE STMT ;
+EXECUTE STMT ;
+
+DEALLOCATE PREPARE STMT;
+DROP TABLE t1;
+
+--echo # End of BUG#53103
+
+--echo #
+--echo # BUG#54511 - Assertion failed: cache != 0L in file
+--echo # sql_select.cc::sub_select_cache on HAVING
+--echo #
+
+CREATE TABLE t1 (i int(11));
+CREATE TABLE t2 (c char(1));
+CREATE TABLE t3 (c char(1));
+
+# These records are needed for the test to fail with MyISAM. The test
+# fails with InnoDB without these (difference due to optimization of
+# aggregates available only in MyISAM)
+INSERT INTO t1 VALUES (1), (2);
+INSERT INTO t2 VALUES ('a'), ('b');
+INSERT INTO t3 VALUES ('x'), ('y');
+
+SELECT COUNT( i ),i
+FROM t1
+HAVING ('c')
+ IN (SELECT t2.c FROM (t2 JOIN t3));
+
+DROP TABLE t1,t2,t3;
+
+--echo # End BUG#54511
+
+--echo #
+--echo # BUG#56367 - Assertion exec_method != EXEC_MATERIALIZATION...
+--echo # on subquery in FROM
+--echo #
+
+CREATE TABLE t1 (a INTEGER);
+
+CREATE TABLE t2 (b INTEGER);
+INSERT INTO t2 VALUES (1);
+
+let $query =
+SELECT a FROM (
+ SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.a > 3 OR t2.b IN (SELECT a FROM t1)
+) table1;
+eval explain $query;
+eval $query;
+
+DROP TABLE t1, t2;
+
+--echo # End BUG#56367
+
+--echo #
+--echo # Bug#59833 - materialization=on/off leads to different result set
+--echo # when using IN
+--echo #
+
+CREATE TABLE t1 (
+ pk int NOT NULL,
+ f1 int DEFAULT NULL,
+ PRIMARY KEY (pk)
+) ENGINE=MyISAM;
+
+CREATE TABLE t2 (
+ pk int NOT NULL,
+ f1 int DEFAULT NULL,
+ PRIMARY KEY (pk)
+) ENGINE=MyISAM;
+
+INSERT INTO t1 VALUES (10,0);
+INSERT INTO t2 VALUES (10,0),(11,0);
+
+let $query=
+SELECT * FROM t1 JOIN t2 USING (f1)
+WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
+
+eval explain $query;
+eval $query;
+
+DROP TABLE t1, t2;
+
+--echo # End Bug#59833
+
+--echo #
+--echo # Bug#11852644 - CRASH IN ITEM_REF::SAVE_IN_FIELD ON SELECT DISTINCT
+--echo #
+
+CREATE TABLE t1 (
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ KEY col_varchar_key (col_varchar_key))
+;
+
+INSERT INTO t1 VALUES
+('v','v'),('r','r');
+
+CREATE TABLE t2 (
+ col_varchar_key varchar(1) DEFAULT NULL,
+ col_varchar_nokey varchar(1) DEFAULT NULL,
+ KEY col_varchar_key(col_varchar_key))
+;
+
+INSERT INTO t2 VALUES
+('r','r'),('c','c');
+
+CREATE VIEW v3 AS SELECT * FROM t2;
+
+SELECT DISTINCT alias2.col_varchar_key
+FROM t1 AS alias1 JOIN v3 AS alias2
+ON alias2.col_varchar_key = alias1.col_varchar_key
+HAVING col_varchar_key IN (SELECT col_varchar_nokey FROM t2)
+;
+
+DROP TABLE t1, t2;
+DROP VIEW v3;
+
+--echo # End Bug#11852644
+
+--echo
+--echo # Bug#12668294 - GROUP BY ON EMPTY RESULT GIVES EMPTY ROW
+--echo # INSTEAD OF NULL WHEN MATERIALIZATION ON
+--echo
+
+CREATE TABLE t1 (col_int_nokey INT) ENGINE=MEMORY;
+CREATE TABLE t2 (col_int_nokey INT) ENGINE=MEMORY;
+INSERT INTO t2 VALUES (8),(7);
+CREATE TABLE t3 (col_int_nokey INT) ENGINE=MEMORY;
+INSERT INTO t3 VALUES (7);
+
+SELECT MIN(t3.col_int_nokey),t1.col_int_nokey AS field3
+FROM t3
+ LEFT JOIN t1
+ ON t1.col_int_nokey
+WHERE (194, 200) IN (
+ SELECT SQ4_alias1.col_int_nokey,
+ SQ4_alias2.col_int_nokey
+ FROM t2 AS SQ4_alias1
+ JOIN
+ t2 AS SQ4_alias2
+ ON SQ4_alias2.col_int_nokey = 5
+ )
+GROUP BY field3 ;
+
+DROP TABLE t1;
+DROP TABLE t2;
+DROP TABLE t3;
+
#
# Bug #44303 Assertion failures in Field_new_decimal::store_decimal
# when executing materialized InsideOut semijoin
@@ -875,7 +1142,8 @@ INSERT INTO t2 VALUES (1, 1.789);
INSERT INTO t2 VALUES (13, 1.454);
set @save_optimizer_switch=@@optimizer_switch;
-SET @@optimizer_switch='default,semijoin=on,materialization=on';
+set @@optimizer_switch=@optimizer_switch_local_default;
+SET @@optimizer_switch='semijoin=on,materialization=on';
EXPLAIN SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
set @@optimizer_switch= @save_optimizer_switch;
@@ -899,7 +1167,8 @@ CREATE TABLE t2 LIKE t1;
INSERT INTO t2 VALUES (1,'i','iiii','iiii','iiii'),(2,'f','ffff','ffff','ffff');
set @save_optimizer_switch=@@optimizer_switch;
-SET @@optimizer_switch='default,semijoin=on,materialization=on';
+set @@optimizer_switch=@optimizer_switch_local_default;
+SET @@optimizer_switch='semijoin=on,materialization=on';
EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
SELECT pk FROM t1 WHERE (b,c,d) IN (SELECT b,c,d FROM t2 WHERE pk > 0);
@@ -972,3 +1241,191 @@ explain select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select subst
select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,1,1024), count(*) from t2_1024 where b1 > '0');
drop table t1_1024, t2_1024;
+
+--echo #
+--echo # BUG##836491: Crash in Item_field::Item_field from add_ref_to_table_cond() with semijoin+materialization
+--echo #
+
+CREATE TABLE t1 (c int, d varchar(1), KEY(d)) ;
+INSERT INTO t1 VALUES (2,'x'),(2,'x'),(2,'j'),(2,'c');
+
+CREATE TABLE t2 (a int, d varchar(1)) ;
+INSERT INTO t2 VALUES (1,'x');
+
+CREATE TABLE t3 (d varchar(1)) ;
+INSERT INTO t3 VALUES ('x'),('x'),('j'),('c');
+
+SELECT t2.a, t1.c
+FROM t1, t2
+WHERE t2.d IN ( SELECT d FROM t3 )
+AND t1.d = t2.d
+GROUP BY 1 , 2;
+
+drop table t1,t2,t3;
+
+--echo #
+--echo # BUG#836523: Crash in JOIN::get_partial_cost_and_fanout with semijoin+materialization
+--echo #
+CREATE TABLE t1 (a varchar(1));
+INSERT INTO t1 VALUES ('a'),('a');
+
+CREATE TABLE t2 (a varchar(1));
+
+CREATE TABLE t3 (a int);
+INSERT INTO t3 VALUES (1),(2);
+
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('a'),('a');
+
+SELECT t1.a
+FROM t1
+WHERE t1.a IN (
+ SELECT t2.a
+ FROM t2, t3
+)
+HAVING a IN (
+ SELECT a
+ FROM t4
+);
+DROP TABLE t1, t2, t3, t4;
+
+--echo #
+--echo # BUG#836507: Crash in setup_sj_materialization_part1() with semijoin+materialization
+--echo #
+CREATE TABLE t1 (a int) ;
+INSERT IGNORE INTO t1 VALUES (1),(1);
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (1);
+
+CREATE TABLE t3 (a int);
+
+CREATE TABLE t4 (a int);
+INSERT INTO t4 VALUES (2),(2);
+
+CREATE TABLE t5 (a int);
+INSERT INTO t5 VALUES (1);
+
+SELECT * FROM t1
+WHERE (a) IN (
+ SELECT t5.a
+ FROM (
+ t2
+ LEFT JOIN ( t3 , t4 )
+ ON 1 = 1
+ )
+ JOIN t5
+);
+
+DROP TABLE t1,t2,t3,t4,t5;
+
+--echo #
+--echo # BUG#836532: Crash in Item_equal_fields_iterator::get_curr_field with semijoin+materialization
+--echo #
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES ('a'),('a');
+
+CREATE TABLE t4 (a varchar(1));
+INSERT INTO t4 VALUES ('m'),('o');
+
+CREATE TABLE t3 (a varchar(1) , b varchar(1) ) ;
+INSERT INTO t3 VALUES ('b','b');
+
+CREATE TABLE t5 (a varchar(1), KEY (a)) ;
+INSERT INTO t5 VALUES ('d'),('e');
+
+SELECT *
+FROM t2
+WHERE t2.a = ALL (
+ SELECT t4.a
+ FROM t4
+ WHERE t4.a IN (
+ SELECT t3.a
+ FROM t3 , t5
+ WHERE ( t5.a = t3.b )
+ )
+);
+
+DROP TABLE t2,t3,t4,t5;
+
+--echo #
+--echo # BUG#860300: Second crash with get_fanout_with_deps() with semijoin + materialization
+--echo #
+set @tmp_860300=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f2 int);
+INSERT INTO t1 VALUES (9),(6);
+CREATE TABLE t3 (f4 int);
+CREATE TABLE t4 (f6 varchar(1));
+
+SELECT *
+FROM t3
+WHERE 'h' IN (SELECT f6
+ FROM t4
+ WHERE 5 IN (SELECT f2 FROM t1)
+ GROUP BY t4.f6);
+DROP TABLE t1,t3,t4;
+set optimizer_switch=@tmp_860300;
+
+--echo #
+--echo # BUG#860535: Assertion `keypart_map' failed in mi_rkey with semijoin
+--echo #
+set @tmp_860535=@@optimizer_switch;
+set optimizer_switch='semijoin=on,materialization=on,loosescan=off,firstmatch=off';
+CREATE TABLE t1 (f3 int) ;
+INSERT INTO t1 VALUES (1),(7);
+
+CREATE TABLE t2 (f3 int , f5 varchar(1), KEY (f3)) ;
+INSERT INTO t2 VALUES (7,'b');
+
+CREATE TABLE t3 (f3 int , f4 varchar(1) , KEY(f3), KEY (f4,f3)) ;
+INSERT INTO t3 VALUES (1,'t'),(7,'g');
+
+CREATE TABLE t4
+SELECT f3
+FROM t1 WHERE ( f3 ) NOT IN (
+ SELECT f3
+ FROM t2
+ WHERE f5 IN (
+ SELECT f4
+ FROM t3
+ WHERE t3.f3 < 3
+ )
+);
+SELECT * FROM t4;
+DROP TABLE t1, t2, t3, t4;
+set optimizer_switch=@tmp_860535;
+
+--echo #
+--echo # BUG#860553: Crash in create_ref_for_key with semijoin + materialization
+--echo #
+CREATE TABLE t1 (f1 int) ;
+CREATE TABLE t2 (f5 varchar(52) NOT NULL) ;
+
+CREATE TABLE t3 (f1 varchar(3), f4 varchar(52) , KEY (f4), PRIMARY KEY (f1));
+
+CREATE TABLE t4 (f3 int, KEY (f3));
+INSERT INTO t4 VALUES (17),(20);
+
+CREATE TABLE t5 (f2 int);
+INSERT INTO t5 VALUES (0),(0);
+
+SELECT *
+FROM t1
+JOIN t2
+ON ( t2.f5 ) IN (
+ SELECT t3.f4
+ FROM t3
+ WHERE ( 1 ) IN (
+ SELECT t4.f3
+ FROM t4 , t5
+ )
+);
+
+DROP TABLE t1, t2, t3, t4, t5;
+
+
+--echo # This must be at the end:
+set optimizer_switch=@subselect_sj_mat_tmp;
+
diff --git a/mysql-test/t/subselect_sj_nonmerged.test b/mysql-test/t/subselect_sj_nonmerged.test
index 5c8fb6db424..4f50b4cbc4d 100644
--- a/mysql-test/t/subselect_sj_nonmerged.test
+++ b/mysql-test/t/subselect_sj_nonmerged.test
@@ -6,7 +6,8 @@ drop table if exists t0, t1, t2, t3, t4;
--enable_warnings
set @save_optimizer_switch=@@optimizer_switch;
-set optimizer_switch='materialization=on';
+set optimizer_switch='semijoin=on,materialization=on';
+set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
create table t0 (a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
diff --git a/mysql-test/t/table_elim.test b/mysql-test/t/table_elim.test
index 5576362b396..3d17c7f5513 100644
--- a/mysql-test/t/table_elim.test
+++ b/mysql-test/t/table_elim.test
@@ -223,7 +223,8 @@ create table t1 (a char(10) primary key);
insert into t1 values ('foo'),('bar');
create table t2 (a char(10), unique key(a(2)));
-insert into t2 values ('foo'),('bar');
+insert into t2 values
+ ('foo'),('bar'),('boo'),('car'),('coo'),('par'),('doo'),('tar');
explain select t1.* from t1 left join t2 on t2.a=t1.a;
diff --git a/mysql-test/t/table_elim_debug.test b/mysql-test/t/table_elim_debug.test
index 9f793169e4f..6400f798195 100644
--- a/mysql-test/t/table_elim_debug.test
+++ b/mysql-test/t/table_elim_debug.test
@@ -1,7 +1,8 @@
#
# Table elimination (MWL#17) tests that need debug build
#
---source include/have_debug.inc
+# In MariaDB 5.3, one can switch table_elimination on/off without debug, too:
+## --source include/have_debug.inc
--disable_warnings
drop table if exists t1, t2;
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index a968e146d20..8d84330ec44 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -2409,3 +2409,28 @@ DROP DATABASE db1;
USE test;
--echo End of 5.1 tests.
+
+#
+# Test that using a trigger will not open mysql.proc
+#
+
+create table t1 (i int);
+create table t2 (i int);
+flush tables;
+flush status;
+delimiter //;
+CREATE DEFINER=`root`@`localhost` TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW BEGIN DELETE FROM t2 WHERE t2.i = OLD.i; END //
+delimiter ;//
+insert into t1 values (1),(2);
+insert into t2 values (1),(2);
+delete from t1 where i=1;
+#
+# If mysql.proc would be used we would have 4 here. 3 is the correct number.
+# (CREATE TRIGGER will open t1 and then flush it)
+#
+show status like 'Opened_tables';
+select * from t1;
+select * from t2;
+drop table t1,t2;
+
+--echo End of 5.2 tests.
diff --git a/mysql-test/t/user_limits-2.test b/mysql-test/t/user_limits-2.test
new file mode 100644
index 00000000000..a376c78a09b
--- /dev/null
+++ b/mysql-test/t/user_limits-2.test
@@ -0,0 +1,11 @@
+#
+# Test behavior of various per-account limits (aka quotas)
+#
+--source include/not_embedded.inc
+
+#
+# We will get an error as it was set to 0 at startup
+#
+--error ER_OPTION_PREVENTS_STATEMENT
+set global max_user_connections=100;
+
diff --git a/mysql-test/t/user_limits-master.opt b/mysql-test/t/user_limits-master.opt
new file mode 100644
index 00000000000..107b2e4a27f
--- /dev/null
+++ b/mysql-test/t/user_limits-master.opt
@@ -0,0 +1 @@
+--max-user-connections=1000
diff --git a/mysql-test/t/user_limits.test b/mysql-test/t/user_limits.test
index 41af032b97e..becaa0963cc 100644
--- a/mysql-test/t/user_limits.test
+++ b/mysql-test/t/user_limits.test
@@ -8,6 +8,8 @@
# Save the initial number of concurrent sessions
--source include/count_sessions.inc
+set @my_max_user_connections= @@global.max_user_connections;
+
# Prepare play-ground
--disable_warnings
drop table if exists t1;
@@ -120,8 +122,18 @@ select * from t1;
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
--error ER_USER_LIMIT_REACHED
connect (muc5, localhost, mysqltest_1,,);
-# Clean up
+
connection default;
+# Test with negative max_user_connections
+grant usage on *.* to mysqltest_1@localhost with max_user_connections -1;
+show grants for mysqltest_1@localhost;
+flush user_resources;
+show grants for mysqltest_1@localhost;
+--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
+--error ER_USER_LIMIT_REACHED
+connect (muc5, localhost, mysqltest_1,,);
+
+# Clean up
disconnect muc2;
disconnect muc3;
disconnect muc4;
@@ -165,12 +177,37 @@ disconnect muca1;
disconnect muca2;
disconnect muca3;
set global max_user_connections= 0;
-drop user mysqltest_1@localhost;
--enable_ps_protocol
+#
+# Test setting negative values of max_user_connections
+#
+grant usage on *.* to mysqltest_1@localhost with max_user_connections 0;
+set global max_user_connections=-1;
+show variables like "max_user_user_connections";
+select @@max_user_connections;
+select @@global.max_user_connections;
+# Check that we can't connect anymore except as root
+--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
+--error ER_TOO_MANY_USER_CONNECTIONS
+connect (muca2, localhost, mysqltest_1,,);
+connect (muca2, localhost, root,,);
+disconnect muca2;
+connection default;
+set global max_user_connections=1;
+# Check that we can connect one time, not two
+connect (muca2, localhost, mysqltest_1,,);
+--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
+--error ER_TOO_MANY_USER_CONNECTIONS
+connect (muca3, localhost, mysqltest_1,,);
+disconnect muca2;
+connection default;
+drop user mysqltest_1@localhost;
+
# Final cleanup
drop table t1;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
+set global max_user_connections= @my_max_user_connections;
diff --git a/mysql-test/t/variables-master.opt b/mysql-test/t/variables-master.opt
new file mode 100644
index 00000000000..e4b213a0323
--- /dev/null
+++ b/mysql-test/t/variables-master.opt
@@ -0,0 +1 @@
+--max-user-connections=1
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index b8fae29fff5..6a9d0372c0a 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -23,6 +23,7 @@ set @my_max_delayed_threads =@@global.max_delayed_threads;
set @my_max_heap_table_size =@@global.max_heap_table_size;
set @my_max_insert_delayed_threads=@@global.max_insert_delayed_threads;
set @my_max_join_size =@@global.max_join_size;
+set @my_max_user_connections =@@global.max_user_connections;
set @my_myisam_data_pointer_size =@@global.myisam_data_pointer_size;
set @my_myisam_max_sort_file_size =@@global.myisam_max_sort_file_size;
set @my_net_buffer_length =@@global.net_buffer_length;
@@ -36,6 +37,7 @@ set @my_thread_cache_size =@@global.thread_cache_size;
set @my_max_allowed_packet =@@global.max_allowed_packet;
set @my_delay_key_write =@@global.delay_key_write;
set @my_join_buffer_size =@@global.join_buffer_size;
+set @my_log_warnings =@@global.log_warnings;
# case insensitivity tests (new in 5.0)
set @`test`=1;
select @test, @`test`, @TEST, @`TEST`, @"teSt";
@@ -829,7 +831,7 @@ set global max_delayed_threads =@my_max_delayed_threads;
set global max_heap_table_size =@my_max_heap_table_size;
set global max_insert_delayed_threads=@my_max_insert_delayed_threads;
set global max_join_size =@my_max_join_size;
-set global max_user_connections =default;
+set global max_user_connections =@my_max_user_connections;
set global max_write_lock_count =default;
set global myisam_data_pointer_size =@my_myisam_data_pointer_size;
set global myisam_max_sort_file_size =@my_myisam_max_sort_file_size;
@@ -844,6 +846,7 @@ set global thread_cache_size =@my_thread_cache_size;
set global max_allowed_packet = default;
set global delay_key_write =@my_delay_key_write;
set global join_buffer_size =@my_join_buffer_size;
+set global log_warnings =@my_log_warnings;
#
# Bug#28580 Repeatation of status variables
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 626cc506e78..7486ffc38f8 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -3954,6 +3954,26 @@ SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;
+--echo #
+--echo # LP BUG#777809 (a retrograded condition for view ON)
+--echo #
+
+CREATE TABLE t1 ( f1 int NOT NULL , f6 int NOT NULL ) ;
+INSERT IGNORE INTO t1 VALUES (20, 2);
+
+CREATE TABLE t2 ( f3 int NOT NULL ) ;
+INSERT IGNORE INTO t2 VALUES (7);
+
+CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2;
+
+PREPARE prep_stmt FROM 'SELECT t1.f6 FROM t1 RIGHT JOIN v2 ON v2.f3 WHERE t1.f1 != 0';
+
+EXECUTE prep_stmt;
+EXECUTE prep_stmt;
+
+drop view v2;
+drop table t1,t2;
+
--echo # -----------------------------------------------------------------
--echo # -- End of 5.1 tests.
--echo # -----------------------------------------------------------------
@@ -4134,3 +4154,157 @@ DELETE FROM v3;
DROP VIEW v1,v2,v3;
DROP TABLE t1;
+
+--echo #
+--echo # Bug#798621: crash with a view string field equal
+--echo # to a constant
+--echo #
+
+CREATE TABLE t1 (a varchar(32), b int) ;
+INSERT INTO t1 VALUES ('j', NULL), ('c', 8), ('c', 1);
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+CREATE TABLE t2 (a varchar(32)) ;
+INSERT INTO t2 VALUES ('j'), ('c');
+
+SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a
+ WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b;
+EXPLAIN EXTENDED
+SELECT * FROM v1 LEFT JOIN t2 ON t2.a = v1.a
+ WHERE v1.b = 1 OR v1.a = 'a' AND LENGTH(v1.a) >= v1.b;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo # Bug#798625: duplicate of the previous one, but without crash
+
+CREATE TABLE t1 (f1 int NOT NULL, f2 int, f3 int, f4 varchar(32), f5 int) ;
+INSERT INTO t1 VALUES (20,5,2,'r', 0);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+SELECT v1.f4 FROM v1
+ WHERE f1<>0 OR f2<>0 AND f4='v' AND (f2<>0 OR f3<>0 AND f5<>0 OR f4 LIKE '%b%');
+EXPLAIN EXTENDED
+SELECT v1.f4 FROM v1
+ WHERE f1<>0 OR f2<>0 AND f4='v' AND (f2<>0 OR f3<>0 AND f5<>0 OR f4 LIKE '%b%');
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug#798576: abort on a GROUP BY query over a view with left join
+--echo # that can be converted to inner join
+--echo #
+
+CREATE TABLE t1 (a int NOT NULL , b int NOT NULL) ;
+INSERT INTO t1 VALUES (214,0), (6,6), (6,0), (7,0);
+
+CREATE TABLE t2 (b int) ;
+INSERT INTO t2 VALUES (88), (78), (6);
+
+CREATE ALGORITHM=MERGE VIEW v1 AS
+ SELECT t1.a, t2.b FROM (t2 LEFT JOIN t1 ON t2.b > t1.a) WHERE t1.b <= 0;
+
+SELECT * FROM v1;
+SELECT a, MIN(b) FROM v1 GROUP BY a;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
+
+--echo #
+--echo # LP bug #793386: unexpected 'Duplicate column name ''' error
+--echo # at the second execution of a PS using a view
+--echo #
+
+CREATE TABLE t1 (f1 int, f2 int, f3 int, f4 int);
+
+CREATE VIEW v1 AS
+ SELECT t.f1, t.f2, s.f3, s.f4 FROM t1 t, t1 s
+ WHERE t.f4 >= s.f2 AND s.f3 < 0;
+
+PREPARE stmt1 FROM
+ "SELECT s.f1 AS f1, s.f2 AS f2, s.f3 AS f3, t.f4 AS f4
+ FROM v1 AS t LEFT JOIN v1 AS s ON t.f4=s.f4 WHERE t.f2 <> 1225";
+EXECUTE stmt1;
+EXECUTE stmt1;
+
+DEALLOCATE PREPARE stmt1;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo #
+--echo # LP BUG#806071 (2 views with ORDER BY)
+--echo #
+
+CREATE TABLE t1 (f1 int);
+INSERT INTO t1 VALUES (1),(1);
+
+CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT f1 FROM t1;
+CREATE ALGORITHM=MERGE VIEW v2 AS SELECT f1 FROM v1 ORDER BY f1;
+
+SELECT * FROM v2 AS a1, v2 AS a2;
+EXPLAIN EXTENDED SELECT * FROM v2 AS a1, v2 AS a2;
+
+DROP VIEW v1, v2;
+DROP TABLE t1;
+
+--echo #
+--echo # LP bug #823189: dependent subquery with RIGHT JOIN
+--echo # referencing view in WHERE
+--echo #
+
+CREATE TABLE t1 (a varchar(32));
+INSERT INTO t1 VALUES ('y'), ('w');
+
+CREATE TABLE t2 (a int);
+INSERT INTO t2 VALUES (10);
+
+CREATE TABLE t3 (a varchar(32), b int);
+
+CREATE TABLE t4 (a varchar(32));
+INSERT INTO t4 VALUES ('y'), ('w');
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+
+EXPLAIN EXTENDED
+SELECT * FROM t1, t2
+ WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+ WHERE t4.a >= t1.a);
+SELECT * FROM t1, t2
+ WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+ WHERE t4.a >= t1.a);
+
+EXPLAIN EXTENDED
+SELECT * FROM v1, t2
+ WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+ WHERE t4.a >= v1.a);
+SELECT * FROM v1, t2
+ WHERE t2.a NOT IN (SELECT t3.b FROM t3 RIGHT JOIN t4 ON (t4.a = t3.a)
+ WHERE t4.a >= v1.a);
+
+DROP VIEW v1;
+DROP TABLE t1,t2,t3,t4;
+
+
+--echo #
+--echo # BUG#833600: Wrong result with view + outer join + uncorrelated subquery (non-semijoin)
+--echo #
+
+CREATE TABLE t1 ( a int, b int );
+INSERT INTO t1 VALUES (0,0),(0,0);
+
+CREATE TABLE t2 ( a int, b int );
+INSERT IGNORE INTO t2 VALUES (1,0),(1,0);
+
+CREATE TABLE t3 ( b int );
+INSERT IGNORE INTO t3 VALUES (0),(0);
+
+CREATE OR REPLACE VIEW v2 AS SELECT * FROM t2;
+SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ;
+
+SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM t3 ) AND t1.b IS NULL ;
+
+DROP VIEW v2;
+DROP TABLE t1, t2, t3;
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index 685fbf04fde..3edb7df03b3 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -396,6 +396,15 @@
}
{
+ dlsym memory loss from udf_free on SuSE 11.1 x64 variant 2
+ Memcheck:Leak
+ fun:calloc
+ obj:/lib*/ld-*.so
+ fun:dlclose
+ fun:udf_free
+}
+
+{
dlclose memory loss from plugin variant 1
Memcheck:Leak
fun:calloc
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index c5f90a50a01..ce424dd51a5 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -38,7 +38,7 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_
my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c
my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c
my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c
- my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c stacktrace.c
+ my_winerr.c my_winfile.c my_windac.c my_winthread.c my_write.c ptr_cmp.c queues.c stacktrace.c
rijndael.c safemalloc.c sha1.c string.c thr_alarm.c thr_lock.c thr_mutex.c
thr_rwlock.c tree.c typelib.c my_vle.c base64.c my_memmem.c my_getpagesize.c ma_dyncol.c
lf_alloc-pin.c lf_dynarray.c lf_hash.c
@@ -48,4 +48,5 @@ SET(MYSYS_SOURCES array.c charset-def.c charset.c checksum.c default.c default_
IF(NOT SOURCE_SUBLIBS)
ADD_LIBRARY(mysys ${MYSYS_SOURCES})
+ TARGET_LINK_LIBRARIES(mysys IPHLPAPI)
ENDIF(NOT SOURCE_SUBLIBS)
diff --git a/mysys/Makefile.am b/mysys/Makefile.am
index 3c0b9743616..e479134df8e 100644
--- a/mysys/Makefile.am
+++ b/mysys/Makefile.am
@@ -74,7 +74,7 @@ endif
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
thr_mutex.c thr_rwlock.c waiting_threads.c \
CMakeLists.txt mf_soundex.c \
- my_conio.c my_wincond.c my_winthread.c
+ my_conio.c my_wincond.c my_winthread.c my_winfile.c my_winerr.c
# test_dir_DEPENDENCIES= $(LIBRARIES)
# testhash_DEPENDENCIES= $(LIBRARIES)
# test_charset_DEPENDENCIES= $(LIBRARIES)
diff --git a/mysys/default_modify.c b/mysys/default_modify.c
index 88df0122da2..ccbf47176a6 100644
--- a/mysys/default_modify.c
+++ b/mysys/default_modify.c
@@ -21,7 +21,7 @@
#define BUFF_SIZE 1024
#define RESERVE 1024 /* Extend buffer with this extent */
-#ifdef __WIN__
+#ifdef _WIN32
#define NEWLINE "\r\n"
#define NEWLINE_LEN 2
#else
@@ -78,7 +78,7 @@ int modify_defaults_file(const char *file_location, const char *option,
DBUG_RETURN(2);
/* my_fstat doesn't use the flag parameter */
- if (my_fstat(fileno(cnf_file), &file_stat, MYF(0)))
+ if (my_fstat(my_fileno(cnf_file), &file_stat, MYF(0)))
goto malloc_err;
if (option && option_value)
@@ -96,7 +96,7 @@ int modify_defaults_file(const char *file_location, const char *option,
NEWLINE_LEN + /* Space for newline */
RESERVE); /* Some additional space */
- buffer_size= (file_stat.st_size +
+ buffer_size= (uint)(file_stat.st_size +
1); /* The ending zero */
/*
@@ -213,7 +213,7 @@ int modify_defaults_file(const char *file_location, const char *option,
if (opt_applied)
{
/* Don't write the file if there are no changes to be made */
- if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0,
+ if (my_chsize(my_fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0,
MYF(MY_WME)) ||
my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) ||
my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer),
diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c
index dcb03d7f073..03d9007c7cb 100644
--- a/mysys/ma_dyncol.c
+++ b/mysys/ma_dyncol.c
@@ -238,7 +238,7 @@ dynamic_column_uint_read(DYNAMIC_COLUMN_VALUE *store_it_here,
for (i= 0; i < length; i++)
value+= ((ulonglong)data[i]) << (i*8);
- store_it_here->ulong_value= value;
+ store_it_here->x.ulong_value= value;
return ER_DYNCOL_OK;
}
@@ -297,12 +297,12 @@ dynamic_column_sint_read(DYNAMIC_COLUMN_VALUE *store_it_here,
{
ulonglong val;
dynamic_column_uint_read(store_it_here, data, length);
- val= store_it_here->ulong_value;
+ val= store_it_here->x.ulong_value;
if (val & 1)
val= (val >> 1) ^ ULL(0xffffffffffffffff);
else
val>>= 1;
- store_it_here->long_value= (longlong) val;
+ store_it_here->x.long_value= (longlong) val;
return ER_DYNCOL_OK;
}
@@ -324,30 +324,30 @@ dynamic_column_value_len(DYNAMIC_COLUMN_VALUE *value)
case DYN_COL_NULL:
return 0;
case DYN_COL_INT:
- return dynamic_column_sint_bytes(value->long_value);
+ return dynamic_column_sint_bytes(value->x.long_value);
case DYN_COL_UINT:
- return dynamic_column_uint_bytes(value->ulong_value);
+ return dynamic_column_uint_bytes(value->x.ulong_value);
case DYN_COL_DOUBLE:
return 8;
case DYN_COL_STRING:
- return (dynamic_column_var_uint_bytes(value->charset->number) +
- value->string_value.length);
+ return (dynamic_column_var_uint_bytes(value->x.string.charset->number) +
+ value->x.string.value.length);
case DYN_COL_DECIMAL:
{
- int precision= value->decimal_value.intg + value->decimal_value.frac;
- int scale= value->decimal_value.frac;
+ int precision= value->x.decimal.value.intg + value->x.decimal.value.frac;
+ int scale= value->x.decimal.value.frac;
- if (precision == 0 || decimal_is_zero(&value->decimal_value))
+ if (precision == 0 || decimal_is_zero(&value->x.decimal.value))
{
/* This is here to simplify dynamic_column_decimal_store() */
- value->decimal_value.intg= value->decimal_value.frac= 0;
+ value->x.decimal.value.intg= value->x.decimal.value.frac= 0;
return 0;
}
/*
Check if legal decimal; This is needed to not get an assert in
decimal_bin_size(). However this should be impossible as all
decimals entered here should be valid and we have the special check
- above to handle the unlikely but possible case that decimal_value.intg
+ above to handle the unlikely but possible case that decimal.value.intg
and decimal.frac is 0.
*/
if (scale < 0 || precision <= 0)
@@ -355,8 +355,8 @@ dynamic_column_value_len(DYNAMIC_COLUMN_VALUE *value)
DBUG_ASSERT(0); /* Impossible */
return (size_t) ~0;
}
- return (dynamic_column_var_uint_bytes(value->decimal_value.intg) +
- dynamic_column_var_uint_bytes(value->decimal_value.frac) +
+ return (dynamic_column_var_uint_bytes(value->x.decimal.value.intg) +
+ dynamic_column_var_uint_bytes(value->x.decimal.value.frac) +
decimal_bin_size(precision, scale));
}
case DYN_COL_DATETIME:
@@ -410,7 +410,7 @@ dynamic_column_double_read(DYNAMIC_COLUMN_VALUE *store_it_here,
{
if (length != 8)
return ER_DYNCOL_FORMAT;
- float8get(store_it_here->double_value, data);
+ float8get(store_it_here->x.double_value, data);
return ER_DYNCOL_OK;
}
@@ -455,12 +455,12 @@ dynamic_column_string_read(DYNAMIC_COLUMN_VALUE *store_it_here,
uint charset_nr= (uint)dynamic_column_var_uint_get(data, length, &len);
if (len == 0) /* Wrong packed number */
return ER_DYNCOL_FORMAT;
- store_it_here->charset= get_charset(charset_nr, MYF(MY_WME));
- if (store_it_here->charset == NULL)
+ store_it_here->x.string.charset= get_charset(charset_nr, MYF(MY_WME));
+ if (store_it_here->x.string.charset == NULL)
return ER_DYNCOL_UNKNOWN_CHARSET;
data+= len;
- store_it_here->string_value.length= (length-= len);
- store_it_here->string_value.str= (char*) data;
+ store_it_here->x.string.value.length= (length-= len);
+ store_it_here->x.string.value.str= (char*) data;
return ER_DYNCOL_OK;
}
@@ -508,11 +508,11 @@ dynamic_column_decimal_store(DYNAMIC_COLUMN *str,
void dynamic_column_prepare_decimal(DYNAMIC_COLUMN_VALUE *value)
{
- value->decimal_value.buf= value->decimal_buffer;
- value->decimal_value.len= DECIMAL_BUFF_LENGTH;
+ value->x.decimal.value.buf= value->x.decimal.buffer;
+ value->x.decimal.value.len= DECIMAL_BUFF_LENGTH;
/* just to be safe */
value->type= DYN_COL_DECIMAL;
- decimal_make_zero(&value->decimal_value);
+ decimal_make_zero(&value->x.decimal.value);
}
@@ -553,7 +553,7 @@ dynamic_column_decimal_read(DYNAMIC_COLUMN_VALUE *store_it_here,
(int) (length - intg_len - frac_len))
return ER_DYNCOL_FORMAT;
- if (bin2decimal(data, &store_it_here->decimal_value, precision, scale) !=
+ if (bin2decimal(data, &store_it_here->x.decimal.value, precision, scale) !=
E_DEC_OK)
return ER_DYNCOL_FORMAT;
return ER_DYNCOL_OK;
@@ -607,14 +607,14 @@ dynamic_column_date_time_read(DYNAMIC_COLUMN_VALUE *store_it_here,
*/
if (length != 9)
goto err;
- store_it_here->time_value.time_type= MYSQL_TIMESTAMP_DATETIME;
+ store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_DATETIME;
if ((rc= dynamic_column_date_read_internal(store_it_here, data, 3)) ||
(rc= dynamic_column_time_read_internal(store_it_here, data + 3, 6)))
goto err;
return ER_DYNCOL_OK;
err:
- store_it_here->time_value.time_type= MYSQL_TIMESTAMP_ERROR;
+ store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_ERROR;
return rc;
}
@@ -682,9 +682,9 @@ static enum enum_dyncol_func_result
dynamic_column_time_read(DYNAMIC_COLUMN_VALUE *store_it_here,
uchar *data, size_t length)
{
- store_it_here->time_value.year= store_it_here->time_value.month=
- store_it_here->time_value.day= 0;
- store_it_here->time_value.time_type= MYSQL_TIMESTAMP_TIME;
+ store_it_here->x.time_value.year= store_it_here->x.time_value.month=
+ store_it_here->x.time_value.day= 0;
+ store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_TIME;
return dynamic_column_time_read_internal(store_it_here, data, length);
}
@@ -709,23 +709,23 @@ dynamic_column_time_read_internal(DYNAMIC_COLUMN_VALUE *store_it_here,
1123456789012345612345612345678901234567890
<123456><123456><123456><123456><123456><123456>
*/
- store_it_here->time_value.second_part= (data[0] |
+ store_it_here->x.time_value.second_part= (data[0] |
(data[1] << 8) |
((data[2] & 0xf) << 16));
- store_it_here->time_value.second= ((data[2] >> 4) |
+ store_it_here->x.time_value.second= ((data[2] >> 4) |
((data[3] & 0x3) << 4));
- store_it_here->time_value.minute= (data[3] >> 2);
- store_it_here->time_value.hour= (((((uint)data[5]) & 0x3 ) << 8) | data[4]);
- store_it_here->time_value.neg= ((data[5] & 0x4) ? 1 : 0);
- if (store_it_here->time_value.second > 59 ||
- store_it_here->time_value.minute > 59 ||
- store_it_here->time_value.hour > 838 ||
- store_it_here->time_value.second_part > 999999)
+ store_it_here->x.time_value.minute= (data[3] >> 2);
+ store_it_here->x.time_value.hour= (((((uint)data[5]) & 0x3 ) << 8) | data[4]);
+ store_it_here->x.time_value.neg= ((data[5] & 0x4) ? 1 : 0);
+ if (store_it_here->x.time_value.second > 59 ||
+ store_it_here->x.time_value.minute > 59 ||
+ store_it_here->x.time_value.hour > 838 ||
+ store_it_here->x.time_value.second_part > 999999)
goto err;
return ER_DYNCOL_OK;
err:
- store_it_here->time_value.time_type= MYSQL_TIMESTAMP_ERROR;
+ store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_ERROR;
return ER_DYNCOL_FORMAT;
}
@@ -783,12 +783,12 @@ static enum enum_dyncol_func_result
dynamic_column_date_read(DYNAMIC_COLUMN_VALUE *store_it_here,
uchar *data, size_t length)
{
- store_it_here->time_value.neg= 0;
- store_it_here->time_value.second_part= 0;
- store_it_here->time_value.hour= 0;
- store_it_here->time_value.minute= 0;
- store_it_here->time_value.second= 0;
- store_it_here->time_value.time_type= MYSQL_TIMESTAMP_DATE;
+ store_it_here->x.time_value.neg= 0;
+ store_it_here->x.time_value.second_part= 0;
+ store_it_here->x.time_value.hour= 0;
+ store_it_here->x.time_value.minute= 0;
+ store_it_here->x.time_value.second= 0;
+ store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_DATE;
return dynamic_column_date_read_internal(store_it_here, data, length);
}
@@ -814,19 +814,19 @@ dynamic_column_date_read_internal(DYNAMIC_COLUMN_VALUE *store_it_here,
12345678901234123412345
<123456><123456><123456>
*/
- store_it_here->time_value.day= (data[0] & 0x1f);
- store_it_here->time_value.month= (((data[1] & 0x1) << 3) |
+ store_it_here->x.time_value.day= (data[0] & 0x1f);
+ store_it_here->x.time_value.month= (((data[1] & 0x1) << 3) |
(data[0] >> 5));
- store_it_here->time_value.year= ((((uint)data[2]) << 7) |
+ store_it_here->x.time_value.year= ((((uint)data[2]) << 7) |
(data[1] >> 1));
- if (store_it_here->time_value.day > 31 ||
- store_it_here->time_value.month > 12 ||
- store_it_here->time_value.year > 9999)
+ if (store_it_here->x.time_value.day > 31 ||
+ store_it_here->x.time_value.month > 12 ||
+ store_it_here->x.time_value.year > 9999)
goto err;
return ER_DYNCOL_OK;
err:
- store_it_here->time_value.time_type= MYSQL_TIMESTAMP_ERROR;
+ store_it_here->x.time_value.time_type= MYSQL_TIMESTAMP_ERROR;
return ER_DYNCOL_FORMAT;
}
@@ -845,25 +845,25 @@ data_store(DYNAMIC_COLUMN *str, DYNAMIC_COLUMN_VALUE *value)
{
switch (value->type) {
case DYN_COL_INT:
- return dynamic_column_sint_store(str, value->long_value);
+ return dynamic_column_sint_store(str, value->x.long_value);
case DYN_COL_UINT:
- return dynamic_column_uint_store(str, value->ulong_value);
+ return dynamic_column_uint_store(str, value->x.ulong_value);
case DYN_COL_DOUBLE:
- return dynamic_column_double_store(str, value->double_value);
+ return dynamic_column_double_store(str, value->x.double_value);
case DYN_COL_STRING:
- return dynamic_column_string_store(str, &value->string_value,
- value->charset);
+ return dynamic_column_string_store(str, &value->x.string.value,
+ value->x.string.charset);
case DYN_COL_DECIMAL:
- return dynamic_column_decimal_store(str, &value->decimal_value);
+ return dynamic_column_decimal_store(str, &value->x.decimal.value);
case DYN_COL_DATETIME:
/* date+time in bits: 14 + 4 + 5 + 5 + 6 + 6 40bits = 5 bytes */
- return dynamic_column_date_time_store(str, &value->time_value);
+ return dynamic_column_date_time_store(str, &value->x.time_value);
case DYN_COL_DATE:
/* date in dits: 14 + 4 + 5 = 23bits ~= 3bytes*/
- return dynamic_column_date_store(str, &value->time_value);
+ return dynamic_column_date_store(str, &value->x.time_value);
case DYN_COL_TIME:
/* time in bits: 5 + 6 + 6 = 17bits ~= 3bytes*/
- return dynamic_column_time_store(str, &value->time_value);
+ return dynamic_column_time_store(str, &value->x.time_value);
case DYN_COL_NULL:
break; /* Impossible */
}
@@ -1743,11 +1743,10 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str,
uint i, j, k;
uint new_column_count, column_count, not_null;
enum enum_dyncol_func_result rc;
- int header_delta, header_delta_sign, data_delta_sign;
+ int header_delta;
size_t offset_size, entry_size, header_size, data_size;
size_t new_offset_size, new_entry_size, new_header_size, new_data_size;
size_t max_offset;
- my_bool copy;
if (add_column_count == 0)
return ER_DYNCOL_OK;
@@ -1878,7 +1877,7 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str,
if (plan[i].val->type == DYN_COL_NULL)
{
- plan[i].act= PLAN_NOP; /* Mark entry to be skiped */
+ plan[i].act= PLAN_NOP; /* Mark entry to be skiped */
}
else
{
@@ -1915,17 +1914,17 @@ dynamic_column_update_many(DYNAMIC_COLUMN *str,
goto end;
}
+#ifdef NOT_IMPLEMENTED
/* if (new_offset_size != offset_size) then we have to rewrite header */
header_delta_sign= new_offset_size - offset_size;
data_delta_sign= 0;
- copy= FALSE;
for (i= 0; i < add_column_count; i++)
{
/* This is the check for increasing/decreasing */
DELTA_CHECK(header_delta_sign, plan[i].hdelta, copy);
DELTA_CHECK(data_delta_sign, plan[i].ddelta, copy);
}
-
+#endif
calc_param(&new_entry_size, &new_header_size,
new_offset_size, new_column_count);
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index 3824669365f..ef5d53710d2 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -178,11 +178,9 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize,
if ((pos == (my_off_t) -1) && (my_errno == ESPIPE))
{
/*
- This kind of object doesn't support seek() or tell(). Don't set a
- flag that will make us again try to seek() later and fail.
- */
- info->seek_not_done= 0;
- /*
+ This kind of object doesn't support seek() or tell(). Don't set a
+ seek_not_done that will make us again try to seek() later and fail.
+
Additionally, if we're supposed to start somewhere other than the
the beginning of whatever this file is, then somebody made a bad
assumption.
@@ -1659,9 +1657,6 @@ int my_block_write(register IO_CACHE *info, const uchar *Buffer, size_t Count,
Buffer+=length;
pos+= length;
Count-= length;
-#ifndef HAVE_PREAD
- info->seek_not_done=1;
-#endif
}
/* Check if we want to write inside the used part of the buffer.*/
@@ -1744,7 +1739,7 @@ int my_b_flush_io_cache(IO_CACHE *info,
*/
if (!append_cache && info->seek_not_done)
{ /* File touched, do seek */
- if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
+ if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(info->myflags & MY_WME)) ==
MY_FILEPOS_ERROR)
{
UNLOCK_APPEND_BUFFER;
diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c
index b1dbb22c687..b9013811b34 100644
--- a/mysys/my_chsize.c
+++ b/mysys/my_chsize.c
@@ -52,20 +52,13 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
if (oldsize > newlength)
{
-#if defined(HAVE_SETFILEPOINTER)
- /* This is for the moment only true on windows */
- long is_success;
- HANDLE win_file= (HANDLE) _get_osfhandle(fd);
- long length_low, length_high;
- length_low= (long) (ulong) newlength;
- length_high= (long) ((ulonglong) newlength >> 32);
- is_success= SetFilePointer(win_file, length_low, &length_high, FILE_BEGIN);
- if (is_success == -1 && (my_errno= GetLastError()) != NO_ERROR)
+#ifdef _WIN32
+ if (my_win_chsize(fd, newlength))
+ {
+ my_errno= errno;
goto err;
- if (SetEndOfFile(win_file))
- DBUG_RETURN(0);
- my_errno= GetLastError();
- goto err;
+ }
+ DBUG_RETURN(0);
#elif defined(HAVE_FTRUNCATE)
if (ftruncate(fd, (off_t) newlength))
{
diff --git a/mysys/my_create.c b/mysys/my_create.c
index 5c9a1e027d2..d0436276d03 100644
--- a/mysys/my_create.c
+++ b/mysys/my_create.c
@@ -18,7 +18,7 @@
#include "mysys_err.h"
#include <errno.h>
#include <my_sys.h>
-#if defined(__WIN__)
+#if defined(_WIN32)
#include <share.h>
#endif
@@ -41,16 +41,12 @@ File my_create(const char *FileName, int CreateFlags, int access_flags,
FileName, CreateFlags, access_flags, MyFlags));
#if !defined(NO_OPEN_3)
- fd = open((char *) FileName, access_flags | O_CREAT,
+ fd= open((char *) FileName, access_flags | O_CREAT,
CreateFlags ? CreateFlags : my_umask);
-#elif defined(VMS)
- fd = open((char *) FileName, access_flags | O_CREAT, 0,
- "ctx=stm","ctx=bin");
-#elif defined(__WIN__)
- fd= my_sopen((char *) FileName, access_flags | O_CREAT | O_BINARY,
- SH_DENYNO, MY_S_IREAD | MY_S_IWRITE);
+#elif defined(_WIN32)
+ fd= my_win_open(FileName, access_flags | O_CREAT);
#else
- fd = open(FileName, access_flags);
+ fd= open(FileName, access_flags);
#endif
if ((MyFlags & MY_SYNC_DIR) && (fd >=0) &&
@@ -71,6 +67,7 @@ File my_create(const char *FileName, int CreateFlags, int access_flags,
if (unlikely(fd >= 0 && rc < 0))
{
int tmp= my_errno;
+ my_close(fd, MyFlags);
my_delete(FileName, MyFlags);
my_errno= tmp;
}
diff --git a/mysys/my_dup.c b/mysys/my_dup.c
index 55f5e0c0099..5fdd6e9f364 100644
--- a/mysys/my_dup.c
+++ b/mysys/my_dup.c
@@ -29,7 +29,11 @@ File my_dup(File file, myf MyFlags)
const char *filename;
DBUG_ENTER("my_dup");
DBUG_PRINT("my",("file: %d MyFlags: %d", file, MyFlags));
- fd = dup(file);
+#ifdef _WIN32
+ fd= my_win_dup(file);
+#else
+ fd= dup(file);
+#endif
filename= (((uint) file < my_file_limit) ?
my_file_info[(int) file].name : "Unknown");
DBUG_RETURN(my_register_filename(fd, filename, FILE_BY_DUP,
diff --git a/mysys/my_file.c b/mysys/my_file.c
index 594f361437f..d8d51b91ab2 100644
--- a/mysys/my_file.c
+++ b/mysys/my_file.c
@@ -97,6 +97,7 @@ uint my_set_max_open_files(uint files)
DBUG_ENTER("my_set_max_open_files");
DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
+ files+= MY_FILE_MIN;
files= set_max_open_files(min(files, OS_FILE_LIMIT));
if (files <= MY_NFILE)
DBUG_RETURN(files);
diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c
index a4b0c9f895d..ae631a59353 100644
--- a/mysys/my_fopen.c
+++ b/mysys/my_fopen.c
@@ -46,24 +46,14 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags)
DBUG_ENTER("my_fopen");
DBUG_PRINT("my",("Name: '%s' flags: %d MyFlags: %d",
filename, flags, MyFlags));
- /*
- if we are not creating, then we need to use my_access to make sure
- the file exists since Windows doesn't handle files like "com1.sym"
- very well
- */
-#ifdef __WIN__
- if (check_if_legal_filename(filename))
- {
- errno= EACCES;
- fd= 0;
- }
- else
+
+ make_ftype(type,flags);
+
+#ifdef _WIN32
+ fd= my_win_fopen(filename, type);
+#else
+ fd= fopen(filename, type);
#endif
- {
- make_ftype(type,flags);
- fd = fopen(filename, type);
- }
-
if (fd != 0)
{
/*
@@ -71,18 +61,20 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags)
on some OS (SUNOS). Actually the filename save isn't that important
so we can ignore if this doesn't work.
*/
- if ((uint) fileno(fd) >= my_file_limit)
+
+ int filedesc= my_fileno(fd);
+ if ((uint)filedesc >= my_file_limit)
{
thread_safe_increment(my_stream_opened,&THR_LOCK_open);
DBUG_RETURN(fd); /* safeguard */
}
pthread_mutex_lock(&THR_LOCK_open);
- if ((my_file_info[fileno(fd)].name = (char*)
+ if ((my_file_info[filedesc].name= (char*)
my_strdup(filename,MyFlags)))
{
my_stream_opened++;
my_file_total_opened++;
- my_file_info[fileno(fd)].type = STREAM_BY_FOPEN;
+ my_file_info[filedesc].type= STREAM_BY_FOPEN;
pthread_mutex_unlock(&THR_LOCK_open);
DBUG_PRINT("exit",("stream: 0x%lx", (long) fd));
DBUG_RETURN(fd);
@@ -240,8 +232,13 @@ int my_fclose(FILE *fd, myf MyFlags)
DBUG_PRINT("my",("stream: 0x%lx MyFlags: %d", (long) fd, MyFlags));
pthread_mutex_lock(&THR_LOCK_open);
- file=fileno(fd);
- if ((err = fclose(fd)) < 0)
+ file= my_fileno(fd);
+#ifndef _WIN32
+ err= fclose(fd);
+#else
+ err= my_win_fclose(fd);
+#endif
+ if(err < 0)
{
my_errno=errno;
if (MyFlags & (MY_FAE | MY_WME))
@@ -272,7 +269,12 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags)
Filedes, Flags, MyFlags));
make_ftype(type,Flags);
- if ((fd = fdopen(Filedes, type)) == 0)
+#ifdef _WIN32
+ fd= my_win_fdopen(Filedes, type);
+#else
+ fd= fdopen(Filedes, type);
+#endif
+ if (!fd)
{
my_errno=errno;
if (MyFlags & (MY_FAE | MY_WME))
diff --git a/mysys/my_fstream.c b/mysys/my_fstream.c
index f3b5418b906..2059e1a9f18 100644
--- a/mysys/my_fstream.c
+++ b/mysys/my_fstream.c
@@ -56,11 +56,11 @@ size_t my_fread(FILE *stream, uchar *Buffer, size_t Count, myf MyFlags)
{
if (ferror(stream))
my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
- my_filename(fileno(stream)),errno);
+ my_filename(my_fileno(stream)),errno);
else
if (MyFlags & (MY_NABP | MY_FNABP))
my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
- my_filename(fileno(stream)),errno);
+ my_filename(my_fileno(stream)),errno);
}
my_errno=errno ? errno : -1;
if (ferror(stream) || MyFlags & (MY_NABP | MY_FNABP))
@@ -142,7 +142,7 @@ size_t my_fwrite(FILE *stream, const uchar *Buffer, size_t Count, myf MyFlags)
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
{
my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG),
- my_filename(fileno(stream)),errno);
+ my_filename(my_fileno(stream)),errno);
}
writtenbytes= (size_t) -1; /* Return that we got error */
break;
@@ -182,3 +182,14 @@ my_off_t my_ftell(FILE *stream, myf MyFlags __attribute__((unused)))
DBUG_PRINT("exit",("ftell: %lu",(ulong) pos));
DBUG_RETURN((my_off_t) pos);
} /* my_ftell */
+
+
+/* Get a File corresponding to the stream*/
+int my_fileno(FILE *f)
+{
+#ifdef _WIN32
+ return my_win_fileno(f);
+#else
+ return fileno(f);
+#endif
+}
diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c
index 90908bd1c0d..e8e8c15bca1 100644
--- a/mysys/my_gethwaddr.c
+++ b/mysys/my_gethwaddr.c
@@ -16,13 +16,23 @@
/* get hardware address for an interface */
/* if there are many available, any non-zero one can be used */
+#define DONT_DEFINE_VOID /* windows includes break if we do */
#include "mysys_priv.h"
#include <m_string.h>
#ifndef MAIN
-#ifdef __FreeBSD__
+static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
+{
+ uint i, res= 1;
+
+ for (i= 0; i < len; i++)
+ if ((*to++= *from++))
+ res= 0;
+ return res;
+}
+#if defined(__APPLE__) || defined(__FreeBSD__)
#include <net/ethernet.h>
#include <sys/sysctl.h>
#include <net/route.h>
@@ -32,11 +42,10 @@
my_bool my_gethwaddr(uchar *to)
{
size_t len;
- char *buf, *next, *end;
+ uchar *buf, *next, *end, *addr;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
- int res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0};
- char zero_array[ETHER_ADDR_LEN] = {0};
+ int res= 1, mib[6]= {CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0};
if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
goto err;
@@ -52,9 +61,9 @@ my_bool my_gethwaddr(uchar *to)
ifm = (struct if_msghdr *)next;
if (ifm->ifm_type == RTM_IFINFO)
{
- sdl= (struct sockaddr_dl *)(ifm + 1);
- memcpy(to, LLADDR(sdl), ETHER_ADDR_LEN);
- res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1;
+ sdl = (struct sockaddr_dl *)(ifm + 1);
+ addr= (uchar *)LLADDR(sdl);
+ res= memcpy_and_test(to, addr, ETHER_ADDR_LEN);
}
}
@@ -62,40 +71,97 @@ err:
return res;
}
-#elif __linux__
-
+#elif defined(__linux__) || defined(__sun__)
#include <net/if.h>
#include <sys/ioctl.h>
-#include <net/ethernet.h>
+#include <net/if_arp.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+
+#define ETHER_ADDR_LEN 6
my_bool my_gethwaddr(uchar *to)
{
int fd, res= 1;
- struct ifreq ifr;
- char zero_array[ETHER_ADDR_LEN] = {0};
+ struct ifreq ifr[32];
+ struct ifconf ifc;
+
+ ifc.ifc_req= ifr;
+ ifc.ifc_len= sizeof(ifr);
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
goto err;
- bzero(&ifr, sizeof(ifr));
- strnmov(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1);
-
- do
+ if (ioctl(fd, SIOCGIFCONF, (char*)&ifc) >= 0)
{
- if (ioctl(fd, SIOCGIFHWADDR, &ifr) >= 0)
+ uint i;
+ for (i= 0; res && i < ifc.ifc_len / sizeof(ifr[0]); i++)
{
- memcpy(to, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
- res= memcmp(to, zero_array, ETHER_ADDR_LEN) ? 0 : 1;
+#ifdef SIOCGIFHWADDR
+ if (ioctl(fd, SIOCGIFHWADDR, &ifr[i]) >= 0)
+ res= memcpy_and_test(to, (uchar *)&ifr[i].ifr_hwaddr.sa_data,
+ ETHER_ADDR_LEN);
+#else
+ /*
+ A bug in OpenSolaris prevents non-root from getting a mac address:
+ http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4720634
+
+ Thus, we'll use an alternative method and extract the address from the
+ arp table.
+ */
+ struct arpreq arpr;
+ arpr.arp_pa= ifr[i].ifr_addr;
+
+ if (ioctl(fd, SIOCGARP, (char*)&arpr) >= 0)
+ res= memcpy_and_test(to, (uchar *)&arpr.arp_ha.sa_data,
+ ETHER_ADDR_LEN);
+#endif
}
- } while (res && (errno == 0 || errno == ENODEV) && ifr.ifr_name[3]++ < '6');
+ }
close(fd);
err:
return res;
}
-#else /* FreeBSD elif linux */
+#elif defined(_WIN32)
+#include <winsock2.h>
+#include <iphlpapi.h>
+
+#define ETHER_ADDR_LEN 6
+
+my_bool my_gethwaddr(uchar *to)
+{
+ my_bool res= 1;
+
+ IP_ADAPTER_INFO *info= NULL;
+ ULONG info_len= 0;
+
+ if (GetAdaptersInfo(info, &info_len) != ERROR_BUFFER_OVERFLOW)
+ goto err;
+
+ info= alloca(info_len);
+
+ if (GetAdaptersInfo(info, &info_len) != NO_ERROR)
+ goto err;
+
+ while (info && res)
+ {
+ if (info->Type == MIB_IF_TYPE_ETHERNET &&
+ info->AddressLength == ETHER_ADDR_LEN)
+ {
+ res= memcpy_and_test(to, info->Address, ETHER_ADDR_LEN);
+ }
+ info = info->Next;
+ }
+
+err:
+ return res;
+}
+
+#else /* neither FreeBSD nor linux not Windows */
/* just fail */
my_bool my_gethwaddr(uchar *to __attribute__((unused)))
{
@@ -114,7 +180,7 @@ int main(int argc __attribute__((unused)),char **argv)
printf("my_gethwaddr failed with errno %d\n", errno);
exit(1);
}
- for (i=0; i < sizeof(mac); i++)
+ for (i= 0; i < sizeof(mac); i++)
{
if (i) printf(":");
printf("%02x", mac[i]);
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index 5d0703f09a8..82f2b6962e5 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -396,10 +396,12 @@ int handle_options(int *argc, char ***argv,
*/
(*argc)--;
if (!optend || *optend == '1' ||
- !my_strcasecmp(&my_charset_latin1, optend, "true"))
+ !my_strcasecmp(&my_charset_latin1, optend, "true") ||
+ !my_strcasecmp(&my_charset_latin1, optend, "on"))
*((my_bool*) value)= (my_bool) 1;
else if (*optend == '0' ||
- !my_strcasecmp(&my_charset_latin1, optend, "false"))
+ !my_strcasecmp(&my_charset_latin1, optend, "false") ||
+ !my_strcasecmp(&my_charset_latin1, optend, "off"))
*((my_bool*) value)= (my_bool) 0;
else
{
diff --git a/mysys/my_init.c b/mysys/my_init.c
index 356dbe6070f..bb9900b425c 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -77,6 +77,8 @@ my_bool my_init(void)
mysys_usage_id++;
my_umask= 0660; /* Default umask for new files */
my_umask_dir= 0700; /* Default umask for new directories */
+ my_global_flags= 0;
+
init_glob_errs();
my_progname_short= "unknown";
if (my_progname)
@@ -274,6 +276,7 @@ void my_parameter_handler(const wchar_t * expression, const wchar_t * function,
{
DBUG_PRINT("my",("Expression: %s function: %s file: %s, line: %d",
expression, function, file, line));
+ __debugbreak();
}
@@ -298,7 +301,7 @@ int handle_rtc_failure(int err_type, const char *file, int line,
fprintf(stderr, " At %s:%d\n", file, line);
va_end(args);
(void) fflush(stderr);
-
+ __debugbreak();
return 0; /* Error is handled */
}
#pragma runtime_checks("", restore)
diff --git a/mysys/my_lib.c b/mysys/my_lib.c
index c18d14fb549..033f8789b49 100644
--- a/mysys/my_lib.c
+++ b/mysys/my_lib.c
@@ -35,8 +35,7 @@
# if defined(HAVE_NDIR_H)
# include <ndir.h>
# endif
-# if defined(__WIN__)
-# include <dos.h>
+# if defined(_WIN32)
# ifdef __BORLANDC__
# include <dir.h>
# endif
@@ -92,7 +91,7 @@ static int comp_names(struct fileinfo *a, struct fileinfo *b)
} /* comp_names */
-#if !defined(__WIN__)
+#if !defined(_WIN32)
MY_DIR *my_dir(const char *path, myf MyFlags)
{
@@ -507,19 +506,24 @@ error:
DBUG_RETURN((MY_DIR *) NULL);
} /* my_dir */
-#endif /* __WIN__ */
+#endif /* _WIN32 */
/****************************************************************************
** File status
** Note that MY_STAT is assumed to be same as struct stat
****************************************************************************/
-int my_fstat(int Filedes, MY_STAT *stat_area,
+
+int my_fstat(File Filedes, MY_STAT *stat_area,
myf MyFlags __attribute__((unused)))
{
DBUG_ENTER("my_fstat");
DBUG_PRINT("my",("fd: %d MyFlags: %d", Filedes, MyFlags));
+#ifdef _WIN32
+ DBUG_RETURN(my_win_fstat(Filedes, stat_area));
+#else
DBUG_RETURN(fstat(Filedes, (struct stat *) stat_area));
+#endif
}
@@ -531,11 +535,15 @@ MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
(long) stat_area, my_flags));
if ((m_used= (stat_area == NULL)))
- if (!(stat_area = (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags)))
+ if (!(stat_area= (MY_STAT *) my_malloc(sizeof(MY_STAT), my_flags)))
goto error;
- if (! stat((char *) path, (struct stat *) stat_area) )
- DBUG_RETURN(stat_area);
-
+#ifndef _WIN32
+ if (! stat((char *) path, (struct stat *) stat_area) )
+ DBUG_RETURN(stat_area);
+#else
+ if (! my_win_stat(path, stat_area) )
+ DBUG_RETURN(stat_area);
+#endif
DBUG_PRINT("error",("Got errno: %d from stat", errno));
my_errno= errno;
if (m_used) /* Free if new area */
diff --git a/mysys/my_lock.c b/mysys/my_lock.c
index 8450fcfc30a..6bbb177e4b6 100644
--- a/mysys/my_lock.c
+++ b/mysys/my_lock.c
@@ -22,13 +22,113 @@
#undef NO_ALARM_LOOP
#endif
#include <my_alarm.h>
-#ifdef __WIN__
-#include <sys/locking.h>
-#endif
#ifdef __NETWARE__
#include <nks/fsio.h>
#endif
+#ifdef _WIN32
+#define WIN_LOCK_INFINITE -1
+#define WIN_LOCK_SLEEP_MILLIS 100
+
+static int win_lock(File fd, int locktype, my_off_t start, my_off_t length,
+ int timeout_sec)
+{
+ LARGE_INTEGER liOffset,liLength;
+ DWORD dwFlags;
+ OVERLAPPED ov= {0};
+ HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
+ DWORD lastError= 0;
+ int i;
+ int timeout_millis= timeout_sec * 1000;
+
+ DBUG_ENTER("win_lock");
+
+ liOffset.QuadPart= start;
+ liLength.QuadPart= length;
+
+ ov.Offset= liOffset.LowPart;
+ ov.OffsetHigh= liOffset.HighPart;
+
+ if (locktype == F_UNLCK)
+ {
+ if (UnlockFileEx(hFile, 0, liLength.LowPart, liLength.HighPart, &ov))
+ DBUG_RETURN(0);
+ /*
+ For compatibility with fcntl implementation, ignore error,
+ if region was not locked
+ */
+ if (GetLastError() == ERROR_NOT_LOCKED)
+ {
+ SetLastError(0);
+ DBUG_RETURN(0);
+ }
+ goto error;
+ }
+ else if (locktype == F_RDLCK)
+ /* read lock is mapped to a shared lock. */
+ dwFlags= 0;
+ else
+ /* write lock is mapped to an exclusive lock. */
+ dwFlags= LOCKFILE_EXCLUSIVE_LOCK;
+
+ /*
+ Drop old lock first to avoid double locking.
+ During analyze of Bug#38133 (Myisamlog test fails on Windows)
+ I met the situation that the program myisamlog locked the file
+ exclusively, then additionally shared, then did one unlock, and
+ then blocked on an attempt to lock it exclusively again.
+ Unlocking before every lock fixed the problem.
+ Note that this introduces a race condition. When the application
+ wants to convert an exclusive lock into a shared one, it will now
+ first unlock the file and then lock it shared. A waiting exclusive
+ lock could step in here. For reasons described in Bug#38133 and
+ Bug#41124 (Server hangs on Windows with --external-locking after
+ INSERT...SELECT) and in the review thread at
+ http://lists.mysql.com/commits/60721 it seems to be the better
+ option than not to unlock here.
+ If one day someone notices a way how to do file lock type changes
+ on Windows without unlocking before taking the new lock, please
+ change this code accordingly to fix the race condition.
+ */
+ if (!UnlockFileEx(hFile, 0, liLength.LowPart, liLength.HighPart, &ov) &&
+ (GetLastError() != ERROR_NOT_LOCKED))
+ goto error;
+
+ if (timeout_sec == WIN_LOCK_INFINITE)
+ {
+ if (LockFileEx(hFile, dwFlags, 0, liLength.LowPart, liLength.HighPart, &ov))
+ DBUG_RETURN(0);
+ goto error;
+ }
+
+ dwFlags|= LOCKFILE_FAIL_IMMEDIATELY;
+ timeout_millis= timeout_sec * 1000;
+ /* Try lock in a loop, until the lock is acquired or timeout happens */
+ for(i= 0; ;i+= WIN_LOCK_SLEEP_MILLIS)
+ {
+ if (LockFileEx(hFile, dwFlags, 0, liLength.LowPart, liLength.HighPart, &ov))
+ DBUG_RETURN(0);
+
+ if (GetLastError() != ERROR_LOCK_VIOLATION)
+ goto error;
+
+ if (i >= timeout_millis)
+ break;
+ Sleep(WIN_LOCK_SLEEP_MILLIS);
+ }
+
+ /* timeout */
+ errno= EAGAIN;
+ DBUG_RETURN(-1);
+
+error:
+ my_osmaperr(GetLastError());
+ DBUG_RETURN(-1);
+}
+#endif
+
+
+
/*
Lock a part of a file
@@ -97,29 +197,16 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length,
DBUG_RETURN(0);
}
}
-#elif defined(HAVE_LOCKING)
- /* Windows */
+#elif defined(_WIN32)
{
- my_bool error= FALSE;
- pthread_mutex_lock(&my_file_info[fd].mutex);
- if (MyFlags & MY_SEEK_NOT_DONE)
- {
- if( my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE))
- == MY_FILEPOS_ERROR )
- {
- /*
- If my_seek fails my_errno will already contain an error code;
- just unlock and return error code.
- */
- DBUG_PRINT("error",("my_errno: %d (%d)",my_errno,errno));
- pthread_mutex_unlock(&my_file_info[fd].mutex);
- DBUG_RETURN(-1);
- }
- }
- error= locking(fd,locktype,(ulong) length) && errno != EINVAL;
- pthread_mutex_unlock(&my_file_info[fd].mutex);
- if (!error)
- DBUG_RETURN(0);
+ int timeout_sec;
+ if (MyFlags & MY_NO_WAIT)
+ timeout_sec= 0;
+ else
+ timeout_sec= WIN_LOCK_INFINITE;
+
+ if(win_lock(fd, locktype, start, length, timeout_sec) == 0)
+ DBUG_RETURN(0);
}
#else
#if defined(HAVE_FCNTL)
diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c
index 330ef07ed30..25180edc06f 100644
--- a/mysys/my_malloc.c
+++ b/mysys/my_malloc.c
@@ -31,6 +31,8 @@ void *my_malloc(size_t size, myf my_flags)
void* point;
DBUG_ENTER("my_malloc");
DBUG_PRINT("my",("size: %lu my_flags: %d", (ulong) size, my_flags));
+ if (!(my_flags & (MY_WME | MY_FAE)))
+ my_flags|= my_global_flags;
if (!size)
size=1; /* Safety */
@@ -48,7 +50,9 @@ void *my_malloc(size_t size, myf my_flags)
if (my_flags & MY_FAE)
error_handler_hook=fatal_error_handler_hook;
if (my_flags & (MY_FAE+MY_WME))
- my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH),size);
+ my_error(EE_OUTOFMEMORY,
+ MYF(ME_BELL | ME_WAITTANG | ME_NOREFRESH | (my_flags & ME_JUST_INFO)),
+ size);
DBUG_EXECUTE_IF("simulate_out_of_memory",
DBUG_SET("-d,simulate_out_of_memory"););
if (my_flags & MY_FAE)
diff --git a/mysys/my_mmap.c b/mysys/my_mmap.c
index 023a06fd896..303d8efaf30 100644
--- a/mysys/my_mmap.c
+++ b/mysys/my_mmap.c
@@ -27,17 +27,17 @@ int my_msync(int fd, void *addr, size_t len, int flags)
return my_sync(fd, MYF(0));
}
-#elif defined(__WIN__)
+#elif defined(_WIN32)
static SECURITY_ATTRIBUTES mmap_security_attributes=
{sizeof(SECURITY_ATTRIBUTES), 0, TRUE};
void *my_mmap(void *addr, size_t len, int prot,
- int flags, int fd, my_off_t offset)
+ int flags, File fd, my_off_t offset)
{
HANDLE hFileMap;
LPVOID ptr;
- HANDLE hFile= (HANDLE)_get_osfhandle(fd);
+ HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
if (hFile == INVALID_HANDLE_VALUE)
return MAP_FAILED;
diff --git a/mysys/my_open.c b/mysys/my_open.c
index fe7f65c450b..dc2fcaf04c6 100644
--- a/mysys/my_open.c
+++ b/mysys/my_open.c
@@ -17,9 +17,7 @@
#include "mysys_err.h"
#include <my_dir.h>
#include <errno.h>
-#if defined(__WIN__)
-#include <share.h>
-#endif
+
/*
Open a file
@@ -43,29 +41,10 @@ File my_open(const char *FileName, int Flags, myf MyFlags)
DBUG_ENTER("my_open");
DBUG_PRINT("my",("Name: '%s' Flags: %d MyFlags: %d",
FileName, Flags, MyFlags));
-#if defined(__WIN__)
- /*
- Check that we don't try to open or create a file name that may
- cause problems for us in the future (like PRN)
- */
- if (check_if_legal_filename(FileName))
- {
- errno= EACCES;
- DBUG_RETURN(my_register_filename(-1, FileName, FILE_BY_OPEN,
- EE_FILENOTFOUND, MyFlags));
- }
-#ifndef __WIN__
- if (Flags & O_SHARE)
- fd = sopen((char *) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO,
- MY_S_IREAD | MY_S_IWRITE);
- else
- fd = open((char *) FileName, Flags | O_BINARY,
- MY_S_IREAD | MY_S_IWRITE);
-#else
- fd= my_sopen((char *) FileName, (Flags & ~O_SHARE) | O_BINARY, SH_DENYNO,
- MY_S_IREAD | MY_S_IWRITE);
-#endif
-
+ if (!(MyFlags & (MY_WME | MY_FAE | MY_FFNF)))
+ MyFlags|= my_global_flags;
+#if defined(_WIN32)
+ fd= my_win_open(FileName, Flags);
#elif !defined(NO_OPEN_3)
fd = open(FileName, Flags, my_umask); /* Normal unix */
#else
@@ -92,26 +71,29 @@ int my_close(File fd, myf MyFlags)
int err;
DBUG_ENTER("my_close");
DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags));
+ if (!(MyFlags & (MY_WME | MY_FAE)))
+ MyFlags|= my_global_flags;
pthread_mutex_lock(&THR_LOCK_open);
+#ifndef _WIN32
do
{
err= close(fd);
} while (err == -1 && errno == EINTR);
-
+#else
+ err= my_win_close(fd);
+#endif
if (err)
{
DBUG_PRINT("error",("Got error %d on close",err));
my_errno=errno;
if (MyFlags & (MY_FAE | MY_WME))
- my_error(EE_BADCLOSE, MYF(ME_BELL+ME_WAITTANG),my_filename(fd),errno);
+ my_error(EE_BADCLOSE, MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))),
+ my_filename(fd),errno);
}
if ((uint) fd < my_file_limit && my_file_info[fd].type != UNOPEN)
{
my_free(my_file_info[fd].name, MYF(0));
-#if defined(THREAD) && !defined(HAVE_PREAD)
- pthread_mutex_destroy(&my_file_info[fd].mutex);
-#endif
my_file_info[fd].type = UNOPEN;
}
my_file_opened--;
@@ -141,16 +123,12 @@ File my_register_filename(File fd, const char *FileName, enum file_type
type_of_file, uint error_message_number, myf MyFlags)
{
DBUG_ENTER("my_register_filename");
- if ((int) fd >= 0)
+ if ((int) fd >= MY_FILE_MIN)
{
if ((uint) fd >= my_file_limit)
{
-#if defined(THREAD) && !defined(HAVE_PREAD)
- my_errno= EMFILE;
-#else
thread_safe_increment(my_file_opened,&THR_LOCK_open);
DBUG_RETURN(fd); /* safeguard */
-#endif
}
else
{
@@ -160,9 +138,6 @@ File my_register_filename(File fd, const char *FileName, enum file_type
my_file_opened++;
my_file_total_opened++;
my_file_info[fd].type = type_of_file;
-#if defined(THREAD) && !defined(HAVE_PREAD)
- pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST);
-#endif
pthread_mutex_unlock(&THR_LOCK_open);
DBUG_PRINT("exit",("fd: %d",fd));
DBUG_RETURN(fd);
@@ -180,195 +155,14 @@ File my_register_filename(File fd, const char *FileName, enum file_type
{
if (my_errno == EMFILE)
error_message_number= EE_OUT_OF_FILERESOURCES;
- DBUG_PRINT("error",("print err: %d",error_message_number));
- my_error(error_message_number, MYF(ME_BELL+ME_WAITTANG),
+ my_error(error_message_number,
+ MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))),
FileName, my_errno);
}
DBUG_RETURN(-1);
}
-#ifdef __WIN__
-
-extern void __cdecl _dosmaperr(unsigned long);
-
-/*
- Open a file with sharing. Similar to _sopen() from libc, but allows managing
- share delete on win32
-
- SYNOPSIS
- my_sopen()
- path fully qualified file name
- oflag operation flags
- shflag share flag
- pmode permission flags
-
- RETURN VALUE
- File descriptor of opened file if success
- -1 and sets errno if fails.
-*/
-
-File my_sopen(const char *path, int oflag, int shflag, int pmode)
-{
- int fh; /* handle of opened file */
- int mask;
- HANDLE osfh; /* OS handle of opened file */
- DWORD fileaccess; /* OS file access (requested) */
- DWORD fileshare; /* OS file sharing mode */
- DWORD filecreate; /* OS method of opening/creating */
- DWORD fileattrib; /* OS file attribute flags */
- SECURITY_ATTRIBUTES SecurityAttributes;
-
- SecurityAttributes.nLength= sizeof(SecurityAttributes);
- SecurityAttributes.lpSecurityDescriptor= NULL;
- SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT);
- /*
- * decode the access flags
- */
- switch (oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
- case _O_RDONLY: /* read access */
- fileaccess= GENERIC_READ;
- break;
- case _O_WRONLY: /* write access */
- fileaccess= GENERIC_WRITE;
- break;
- case _O_RDWR: /* read and write access */
- fileaccess= GENERIC_READ | GENERIC_WRITE;
- break;
- default: /* error, bad oflag */
- errno= EINVAL;
- _doserrno= 0L; /* not an OS error */
- return -1;
- }
-
- /*
- * decode sharing flags
- */
- switch (shflag) {
- case _SH_DENYRW: /* exclusive access except delete */
- fileshare= FILE_SHARE_DELETE;
- break;
- case _SH_DENYWR: /* share read and delete access */
- fileshare= FILE_SHARE_READ | FILE_SHARE_DELETE;
- break;
- case _SH_DENYRD: /* share write and delete access */
- fileshare= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- break;
- case _SH_DENYNO: /* share read, write and delete access */
- fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- break;
- case _SH_DENYRWD: /* exclusive access */
- fileshare= 0L;
- break;
- case _SH_DENYWRD: /* share read access */
- fileshare= FILE_SHARE_READ;
- break;
- case _SH_DENYRDD: /* share write access */
- fileshare= FILE_SHARE_WRITE;
- break;
- case _SH_DENYDEL: /* share read and write access */
- fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE;
- break;
- default: /* error, bad shflag */
- errno= EINVAL;
- _doserrno= 0L; /* not an OS error */
- return -1;
- }
-
- /*
- * decode open/create method flags
- */
- switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
- case 0:
- case _O_EXCL: /* ignore EXCL w/o CREAT */
- filecreate= OPEN_EXISTING;
- break;
-
- case _O_CREAT:
- filecreate= OPEN_ALWAYS;
- break;
-
- case _O_CREAT | _O_EXCL:
- case _O_CREAT | _O_TRUNC | _O_EXCL:
- filecreate= CREATE_NEW;
- break;
-
- case _O_TRUNC:
- case _O_TRUNC | _O_EXCL: /* ignore EXCL w/o CREAT */
- filecreate= TRUNCATE_EXISTING;
- break;
-
- case _O_CREAT | _O_TRUNC:
- filecreate= CREATE_ALWAYS;
- break;
-
- default:
- /* this can't happen ... all cases are covered */
- errno= EINVAL;
- _doserrno= 0L;
- return -1;
- }
-
- /*
- * decode file attribute flags if _O_CREAT was specified
- */
- fileattrib= FILE_ATTRIBUTE_NORMAL; /* default */
- if (oflag & _O_CREAT)
- {
- _umask((mask= _umask(0)));
-
- if (!((pmode & ~mask) & _S_IWRITE))
- fileattrib= FILE_ATTRIBUTE_READONLY;
- }
-
- /*
- * Set temporary file (delete-on-close) attribute if requested.
- */
- if (oflag & _O_TEMPORARY)
- {
- fileattrib|= FILE_FLAG_DELETE_ON_CLOSE;
- fileaccess|= DELETE;
- }
-
- /*
- * Set temporary file (delay-flush-to-disk) attribute if requested.
- */
- if (oflag & _O_SHORT_LIVED)
- fileattrib|= FILE_ATTRIBUTE_TEMPORARY;
-
- /*
- * Set sequential or random access attribute if requested.
- */
- if (oflag & _O_SEQUENTIAL)
- fileattrib|= FILE_FLAG_SEQUENTIAL_SCAN;
- else if (oflag & _O_RANDOM)
- fileattrib|= FILE_FLAG_RANDOM_ACCESS;
-
- /*
- * try to open/create the file
- */
- if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes,
- filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE)
- {
- /*
- * OS call to open/create file failed! map the error, release
- * the lock, and return -1. note that it's not necessary to
- * call _free_osfhnd (it hasn't been used yet).
- */
- _dosmaperr(GetLastError()); /* map error */
- return -1; /* return error to caller */
- }
-
- if ((fh= _open_osfhandle((intptr_t)osfh,
- oflag & (_O_APPEND | _O_RDONLY | _O_TEXT))) == -1)
- {
- _dosmaperr(GetLastError()); /* map error */
- CloseHandle(osfh);
- }
-
- return fh; /* return handle */
-}
-#endif /* __WIN__ */
#ifdef EXTRA_DEBUG
diff --git a/mysys/my_pread.c b/mysys/my_pread.c
index 836f5a92963..f8799561c09 100644
--- a/mysys/my_pread.c
+++ b/mysys/my_pread.c
@@ -18,7 +18,7 @@
#include "my_base.h"
#include <m_string.h>
#include <errno.h>
-#ifdef HAVE_PREAD
+#ifndef _WIN32
#include <unistd.h>
#endif
@@ -48,9 +48,7 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
{
size_t readbytes;
int error= 0;
-#ifndef HAVE_PREAD
- int save_errno;
-#endif
+
#ifndef DBUG_OFF
char llbuf[22];
DBUG_ENTER("my_pread");
@@ -58,23 +56,21 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
Filedes, ullstr(offset, llbuf), (long) Buffer,
(ulong)Count, MyFlags));
#endif
+ if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP)))
+ MyFlags|= my_global_flags;
+
for (;;)
{
errno= 0; /* Linux, Windows don't reset this on EOF/success */
-#ifndef HAVE_PREAD
- pthread_mutex_lock(&my_file_info[Filedes].mutex);
- readbytes= (uint) -1;
- error= (lseek(Filedes, offset, MY_SEEK_SET) == (my_off_t) -1 ||
- (readbytes= read(Filedes, Buffer, (uint) Count)) != Count);
- save_errno= errno;
- pthread_mutex_unlock(&my_file_info[Filedes].mutex);
- if (error)
- {
- errno= save_errno;
+#ifdef _WIN32
+ readbytes= my_win_pread(Filedes, Buffer, Count, offset);
#else
- if ((error= ((readbytes= pread(Filedes, Buffer, Count, offset)) != Count)))
- {
+ readbytes= pread(Filedes, Buffer, Count, offset);
#endif
+ error = (readbytes != Count);
+
+ if (error)
+ {
my_errno= errno ? errno : -1;
if (errno == 0 || (readbytes != (size_t) -1 &&
(MyFlags & (MY_NABP | MY_FNABP))))
@@ -92,18 +88,20 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
{
if (readbytes == (size_t) -1)
- my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
+ my_error(EE_READ,
+ MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))),
my_filename(Filedes),my_errno);
else if (MyFlags & (MY_NABP | MY_FNABP))
- my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
- my_filename(Filedes),my_errno);
+ my_error(EE_EOFERR,
+ MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))),
+ my_filename(Filedes),my_errno);
}
if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP)))
- DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
+ DBUG_RETURN(MY_FILE_ERROR); /* Return with error */
}
if (MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN(0); /* Read went ok; Return 0 */
- DBUG_RETURN(readbytes); /* purecov: inspected */
+ DBUG_RETURN(0); /* Read went ok; Return 0 */
+ DBUG_RETURN(readbytes); /* purecov: inspected */
}
} /* my_pread */
@@ -132,7 +130,7 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
my_off_t offset, myf MyFlags)
{
- size_t writenbytes, written;
+ size_t writtenbytes, written;
uint errors;
#ifndef DBUG_OFF
char llbuf[22];
@@ -143,31 +141,27 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
#endif
errors= 0;
written= 0;
+ if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP)))
+ MyFlags|= my_global_flags;
for (;;)
{
-#ifndef HAVE_PREAD
- int error;
- writenbytes= (size_t) -1;
- pthread_mutex_lock(&my_file_info[Filedes].mutex);
- error= (lseek(Filedes, offset, MY_SEEK_SET) != (my_off_t) -1 &&
- (writenbytes = write(Filedes, Buffer, (uint) Count)) == Count);
- pthread_mutex_unlock(&my_file_info[Filedes].mutex);
- if (error)
- break;
+#ifdef _WIN32
+ writtenbytes= my_win_pwrite(Filedes, Buffer, Count,offset);
#else
- if ((writenbytes= pwrite(Filedes, Buffer, Count,offset)) == Count)
+ writtenbytes= pwrite(Filedes, Buffer, Count, offset);
+#endif
+ if (writtenbytes == Count)
break;
my_errno= errno;
-#endif
- if (writenbytes != (size_t) -1)
+ if (writtenbytes != (size_t) -1)
{ /* Safegueard */
- written+=writenbytes;
- Buffer+=writenbytes;
- Count-=writenbytes;
- offset+=writenbytes;
+ written+=writtenbytes;
+ Buffer+=writtenbytes;
+ Count-=writtenbytes;
+ offset+=writtenbytes;
}
- DBUG_PRINT("error",("Write only %u bytes", (uint) writenbytes));
+ DBUG_PRINT("error",("Write only %u bytes", (uint) writtenbytes));
#ifndef NO_BACKGROUND
#ifdef THREAD
if (my_thread_var->abort)
@@ -180,23 +174,22 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
errors++;
continue;
}
- if ((writenbytes && writenbytes != (size_t) -1) || my_errno == EINTR)
+ if ((writtenbytes && writtenbytes != (size_t) -1) || my_errno == EINTR)
continue; /* Retry */
#endif
+
+ /* Don't give a warning if it's ok that we only write part of the data */
if (MyFlags & (MY_NABP | MY_FNABP))
{
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
- {
- my_error(EE_WRITE, MYF(ME_BELL | ME_WAITTANG),
- my_filename(Filedes),my_errno);
- }
- DBUG_RETURN(MY_FILE_ERROR); /* Error on read */
+ my_error(EE_WRITE, MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))),
+ my_filename(Filedes),my_errno);
+ DBUG_RETURN(MY_FILE_ERROR); /* Error on write */
}
- else
- break; /* Return bytes written */
+ break; /* Return bytes written */
}
DBUG_EXECUTE_IF("check", my_seek(Filedes, -1, SEEK_SET, MYF(0)););
if (MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN(0); /* Want only errors */
- DBUG_RETURN(writenbytes+written); /* purecov: inspected */
+ DBUG_RETURN(0); /* Want only errors */
+ DBUG_RETURN(writtenbytes+written); /* purecov: inspected */
} /* my_pwrite */
diff --git a/mysys/my_quick.c b/mysys/my_quick.c
index 0ba20a5bdee..b93e7e17224 100644
--- a/mysys/my_quick.c
+++ b/mysys/my_quick.c
@@ -19,11 +19,19 @@
#include "my_nosys.h"
+#ifdef _WIN32
+extern size_t my_win_read(File Filedes,uchar *Buffer,size_t Count);
+#endif
+
size_t my_quick_read(File Filedes,uchar *Buffer,size_t Count,myf MyFlags)
{
size_t readbytes;
-
- if ((readbytes = read(Filedes, Buffer, (uint) Count)) != Count)
+#ifdef _WIN32
+ readbytes= my_win_read(Filedes, Buffer, Count);
+#else
+ readbytes= read(Filedes, Buffer, Count);
+#endif
+ if(readbytes != Count)
{
#ifndef DBUG_OFF
if ((readbytes == 0 || readbytes == (size_t) -1) && errno == EINTR)
@@ -40,8 +48,13 @@ size_t my_quick_read(File Filedes,uchar *Buffer,size_t Count,myf MyFlags)
}
-size_t my_quick_write(File Filedes,const uchar *Buffer,size_t Count)
+
+size_t my_quick_write(File Filedes, const uchar *Buffer, size_t Count)
{
+#ifdef _WIN32
+ return my_win_write(Filedes, Buffer, Count);
+#else
+
#ifndef DBUG_OFF
size_t writtenbytes;
#endif
@@ -50,7 +63,7 @@ size_t my_quick_write(File Filedes,const uchar *Buffer,size_t Count)
#ifndef DBUG_OFF
writtenbytes =
#endif
- (size_t) write(Filedes,Buffer, (uint) Count)) != Count)
+ (size_t) write(Filedes,Buffer,Count)) != Count)
{
#ifndef DBUG_OFF
if ((writtenbytes == 0 || writtenbytes == (size_t) -1) && errno == EINTR)
@@ -64,4 +77,5 @@ size_t my_quick_write(File Filedes,const uchar *Buffer,size_t Count)
return (size_t) -1;
}
return 0;
+#endif
}
diff --git a/mysys/my_read.c b/mysys/my_read.c
index 25ffe73d813..8ababb31324 100644
--- a/mysys/my_read.c
+++ b/mysys/my_read.c
@@ -40,11 +40,18 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
Filedes, (long) Buffer, (ulong) Count, MyFlags));
save_count= Count;
+ if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP)))
+ MyFlags|= my_global_flags;
for (;;)
{
errno= 0; /* Linux, Windows don't reset this on EOF/success */
- if ((readbytes= read(Filedes, Buffer, (uint) Count)) != Count)
+#ifdef _WIN32
+ readbytes= my_win_read(Filedes, Buffer, Count);
+#else
+ readbytes= read(Filedes, Buffer, Count);
+#endif
+ if (readbytes != Count)
{
my_errno= errno;
if (errno == 0 || (readbytes != (size_t) -1 &&
@@ -64,10 +71,12 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
{
if (readbytes == (size_t) -1)
- my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG),
+ my_error(EE_READ,
+ MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))),
my_filename(Filedes),my_errno);
else if (MyFlags & (MY_NABP | MY_FNABP))
- my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
+ my_error(EE_EOFERR,
+ MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))),
my_filename(Filedes),my_errno);
}
if (readbytes == (size_t) -1 ||
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index d186d56869a..24941517487 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -56,16 +56,11 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags)
Make sure we are using a valid file descriptor!
*/
DBUG_ASSERT(fd != -1);
-#if defined(THREAD) && !defined(HAVE_PREAD)
- if (MyFlags & MY_THREADSAFE)
- {
- pthread_mutex_lock(&my_file_info[fd].mutex);
- newpos= lseek(fd, pos, whence);
- pthread_mutex_unlock(&my_file_info[fd].mutex);
- }
- else
+#ifdef _WIN32
+ newpos= my_win_lseek(fd, pos, whence);
+#else
+ newpos= lseek(fd, pos, whence);
#endif
- newpos= lseek(fd, pos, whence);
if (newpos == (os_off_t) -1)
{
my_errno= errno;
@@ -91,7 +86,9 @@ my_off_t my_tell(File fd, myf MyFlags)
DBUG_ENTER("my_tell");
DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags));
DBUG_ASSERT(fd >= 0);
-#ifdef HAVE_TELL
+#ifdef _WIN32
+ pos= my_seek(fd, 0, MY_SEEK_CUR,0);
+#elif defined(HAVE_TELL)
pos=tell(fd);
#else
pos=lseek(fd, 0L, MY_SEEK_CUR);
diff --git a/mysys/my_static.c b/mysys/my_static.c
index 52c8c6aff0e..a117bed1496 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -32,10 +32,12 @@ char NEAR curr_dir[FN_REFLEN]= {0},
ulong my_stream_opened=0,my_file_opened=0, my_tmp_file_created=0;
ulong my_file_total_opened= 0;
int NEAR my_umask=0664, NEAR my_umask_dir=0777;
+myf my_global_flags= 0;
+my_bool my_assert_on_error= 0;
#ifndef THREAD
int NEAR my_errno=0;
#endif
-struct st_my_file_info my_file_info_default[MY_NFILE]= {{0,UNOPEN}};
+struct st_my_file_info my_file_info_default[MY_NFILE];
uint my_file_limit= MY_NFILE;
struct st_my_file_info *my_file_info= my_file_info_default;
diff --git a/mysys/my_sync.c b/mysys/my_sync.c
index dae20b0163e..9c5fbce7ab7 100644
--- a/mysys/my_sync.c
+++ b/mysys/my_sync.c
@@ -71,7 +71,7 @@ int my_sync(File fd, myf my_flags)
if (res == -1 && errno == ENOLCK)
res= 0; /* Result Bug in Old FreeBSD */
#elif defined(__WIN__)
- res= _commit(fd);
+ res= my_win_fsync(fd);
#else
#error Cannot find a way to sync a file, durability in danger
res= 0; /* No sync (strange OS) */
diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c
index e181b24cdef..a6483ae61a3 100644
--- a/mysys/my_wincond.c
+++ b/mysys/my_wincond.c
@@ -26,7 +26,92 @@
#include <process.h>
#include <sys/timeb.h>
-int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+
+/*
+ Windows native condition variables. We use runtime loading / function
+ pointers, because they are not available on XP
+*/
+
+/* Prototypes and function pointers for condition variable functions */
+typedef void (WINAPI * InitializeConditionVariableProc)
+ (PCONDITION_VARIABLE ConditionVariable);
+
+typedef BOOL (WINAPI * SleepConditionVariableCSProc)
+ (PCONDITION_VARIABLE ConditionVariable,
+ PCRITICAL_SECTION CriticalSection,
+ DWORD dwMilliseconds);
+
+typedef void (WINAPI * WakeAllConditionVariableProc)
+ (PCONDITION_VARIABLE ConditionVariable);
+
+typedef void (WINAPI * WakeConditionVariableProc)
+ (PCONDITION_VARIABLE ConditionVariable);
+
+static InitializeConditionVariableProc my_InitializeConditionVariable;
+static SleepConditionVariableCSProc my_SleepConditionVariableCS;
+static WakeAllConditionVariableProc my_WakeAllConditionVariable;
+static WakeConditionVariableProc my_WakeConditionVariable;
+
+
+/**
+ Indicates if we have native condition variables,
+ initialized first time pthread_cond_init is called.
+*/
+
+static BOOL have_native_conditions= FALSE;
+
+
+/**
+ Check if native conditions can be used, load function pointers
+*/
+
+static void check_native_cond_availability(void)
+{
+ HMODULE module= GetModuleHandle("kernel32");
+
+ my_InitializeConditionVariable= (InitializeConditionVariableProc)
+ GetProcAddress(module, "InitializeConditionVariable");
+ my_SleepConditionVariableCS= (SleepConditionVariableCSProc)
+ GetProcAddress(module, "SleepConditionVariableCS");
+ my_WakeAllConditionVariable= (WakeAllConditionVariableProc)
+ GetProcAddress(module, "WakeAllConditionVariable");
+ my_WakeConditionVariable= (WakeConditionVariableProc)
+ GetProcAddress(module, "WakeConditionVariable");
+
+ if (my_InitializeConditionVariable)
+ have_native_conditions= TRUE;
+}
+
+
+
+/**
+ Convert abstime to milliseconds
+*/
+
+static DWORD get_milliseconds(const struct timespec *abstime)
+{
+ struct timespec current_time;
+ long long ms;
+
+ if (abstime == NULL)
+ return INFINITE;
+
+ set_timespec_nsec(current_time, 0);
+ ms= (abstime->tv_sec - current_time.tv_sec)*1000LL +
+ (abstime->tv_nsec - current_time.tv_nsec)/1000000LL;
+ if(ms < 0 )
+ ms= 0;
+ if(ms > UINT_MAX)
+ ms= INFINITE;
+ return (DWORD)ms;
+}
+
+
+/*
+ Old (pre-vista) implementation using events
+*/
+
+static int legacy_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
{
cond->waiting= 0;
InitializeCriticalSection(&cond->lock_waiting);
@@ -55,7 +140,8 @@ int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
return 0;
}
-int pthread_cond_destroy(pthread_cond_t *cond)
+
+static int legacy_cond_destroy(pthread_cond_t *cond)
{
DeleteCriticalSection(&cond->lock_waiting);
@@ -67,13 +153,7 @@ int pthread_cond_destroy(pthread_cond_t *cond)
}
-int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
-{
- return pthread_cond_timedwait(cond,mutex,NULL);
-}
-
-
-int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
+static int legacy_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
struct timespec *abstime)
{
int result;
@@ -135,7 +215,7 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
return result == WAIT_TIMEOUT ? ETIMEDOUT : 0;
}
-int pthread_cond_signal(pthread_cond_t *cond)
+static int legacy_cond_signal(pthread_cond_t *cond)
{
EnterCriticalSection(&cond->lock_waiting);
@@ -148,7 +228,7 @@ int pthread_cond_signal(pthread_cond_t *cond)
}
-int pthread_cond_broadcast(pthread_cond_t *cond)
+static int legacy_cond_broadcast(pthread_cond_t *cond)
{
EnterCriticalSection(&cond->lock_waiting);
/*
@@ -170,6 +250,87 @@ int pthread_cond_broadcast(pthread_cond_t *cond)
}
+/*
+ Posix API functions. Just choose between native and legacy implementation.
+*/
+
+int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
+{
+ /*
+ Once initialization is used here rather than in my_init(), to
+ 1) avoid my_init() pitfalls- undefined order in which initialization should
+ run
+ 2) be potentially useful C++ (in static constructors that run before main())
+ 3) just to simplify the API.
+ Also, the overhead of my_pthread_once is very small.
+ */
+ static my_pthread_once_t once_control= MY_PTHREAD_ONCE_INIT;
+ my_pthread_once(&once_control, check_native_cond_availability);
+
+ if (have_native_conditions)
+ {
+ my_InitializeConditionVariable(&cond->native_cond);
+ return 0;
+ }
+ else
+ return legacy_cond_init(cond, attr);
+}
+
+
+int pthread_cond_destroy(pthread_cond_t *cond)
+{
+ if (have_native_conditions)
+ return 0; /* no destroy function */
+ else
+ return legacy_cond_destroy(cond);
+}
+
+
+int pthread_cond_broadcast(pthread_cond_t *cond)
+{
+ if (have_native_conditions)
+ {
+ my_WakeAllConditionVariable(&cond->native_cond);
+ return 0;
+ }
+ else
+ return legacy_cond_broadcast(cond);
+}
+
+
+int pthread_cond_signal(pthread_cond_t *cond)
+{
+ if (have_native_conditions)
+ {
+ my_WakeConditionVariable(&cond->native_cond);
+ return 0;
+ }
+ else
+ return legacy_cond_signal(cond);
+}
+
+
+int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
+ struct timespec *abstime)
+{
+ if (have_native_conditions)
+ {
+ DWORD timeout= get_milliseconds(abstime);
+ if (!my_SleepConditionVariableCS(&cond->native_cond, mutex, timeout))
+ return ETIMEDOUT;
+ return 0;
+ }
+ else
+ return legacy_cond_timedwait(cond, mutex, abstime);
+}
+
+
+int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
+{
+ return pthread_cond_timedwait(cond, mutex, NULL);
+}
+
+
int pthread_attr_init(pthread_attr_t *connect_att)
{
connect_att->dwStackSize = 0;
diff --git a/mysys/my_winerr.c b/mysys/my_winerr.c
new file mode 100644
index 00000000000..534078b6737
--- /dev/null
+++ b/mysys/my_winerr.c
@@ -0,0 +1,123 @@
+/* Copyright (C) 2008 MySQL AB
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ Convert Windows API error (GetLastError() to Posix equivalent (errno)
+ The exported function my_osmaperr() is modelled after and borrows
+ heavily from undocumented _dosmaperr()(found of the static Microsoft C runtime).
+*/
+
+#include <my_global.h>
+#include <my_sys.h>
+
+
+struct errentry
+{
+ unsigned long oscode; /* OS return value */
+ int sysv_errno; /* System V error code */
+};
+
+static struct errentry errtable[]= {
+ { ERROR_INVALID_FUNCTION, EINVAL }, /* 1 */
+ { ERROR_FILE_NOT_FOUND, ENOENT }, /* 2 */
+ { ERROR_PATH_NOT_FOUND, ENOENT }, /* 3 */
+ { ERROR_TOO_MANY_OPEN_FILES, EMFILE }, /* 4 */
+ { ERROR_ACCESS_DENIED, EACCES }, /* 5 */
+ { ERROR_INVALID_HANDLE, EBADF }, /* 6 */
+ { ERROR_ARENA_TRASHED, ENOMEM }, /* 7 */
+ { ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, /* 8 */
+ { ERROR_INVALID_BLOCK, ENOMEM }, /* 9 */
+ { ERROR_BAD_ENVIRONMENT, E2BIG }, /* 10 */
+ { ERROR_BAD_FORMAT, ENOEXEC }, /* 11 */
+ { ERROR_INVALID_ACCESS, EINVAL }, /* 12 */
+ { ERROR_INVALID_DATA, EINVAL }, /* 13 */
+ { ERROR_INVALID_DRIVE, ENOENT }, /* 15 */
+ { ERROR_CURRENT_DIRECTORY, EACCES }, /* 16 */
+ { ERROR_NOT_SAME_DEVICE, EXDEV }, /* 17 */
+ { ERROR_NO_MORE_FILES, ENOENT }, /* 18 */
+ { ERROR_LOCK_VIOLATION, EACCES }, /* 33 */
+ { ERROR_BAD_NETPATH, ENOENT }, /* 53 */
+ { ERROR_NETWORK_ACCESS_DENIED, EACCES }, /* 65 */
+ { ERROR_BAD_NET_NAME, ENOENT }, /* 67 */
+ { ERROR_FILE_EXISTS, EEXIST }, /* 80 */
+ { ERROR_CANNOT_MAKE, EACCES }, /* 82 */
+ { ERROR_FAIL_I24, EACCES }, /* 83 */
+ { ERROR_INVALID_PARAMETER, EINVAL }, /* 87 */
+ { ERROR_NO_PROC_SLOTS, EAGAIN }, /* 89 */
+ { ERROR_DRIVE_LOCKED, EACCES }, /* 108 */
+ { ERROR_BROKEN_PIPE, EPIPE }, /* 109 */
+ { ERROR_DISK_FULL, ENOSPC }, /* 112 */
+ { ERROR_INVALID_TARGET_HANDLE, EBADF }, /* 114 */
+ { ERROR_INVALID_HANDLE, EINVAL }, /* 124 */
+ { ERROR_WAIT_NO_CHILDREN, ECHILD }, /* 128 */
+ { ERROR_CHILD_NOT_COMPLETE, ECHILD }, /* 129 */
+ { ERROR_DIRECT_ACCESS_HANDLE, EBADF }, /* 130 */
+ { ERROR_NEGATIVE_SEEK, EINVAL }, /* 131 */
+ { ERROR_SEEK_ON_DEVICE, EACCES }, /* 132 */
+ { ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, /* 145 */
+ { ERROR_NOT_LOCKED, EACCES }, /* 158 */
+ { ERROR_BAD_PATHNAME, ENOENT }, /* 161 */
+ { ERROR_MAX_THRDS_REACHED, EAGAIN }, /* 164 */
+ { ERROR_LOCK_FAILED, EACCES }, /* 167 */
+ { ERROR_ALREADY_EXISTS, EEXIST }, /* 183 */
+ { ERROR_FILENAME_EXCED_RANGE, ENOENT }, /* 206 */
+ { ERROR_NESTING_NOT_ALLOWED, EAGAIN }, /* 215 */
+ { ERROR_NOT_ENOUGH_QUOTA, ENOMEM } /* 1816 */
+};
+
+/* size of the table */
+#define ERRTABLESIZE (sizeof(errtable)/sizeof(errtable[0]))
+
+/* The following two constants must be the minimum and maximum
+values in the (contiguous) range of Exec Failure errors. */
+#define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
+#define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
+
+/* These are the low and high value in the range of errors that are
+access violations */
+#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
+#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
+
+
+static int get_errno_from_oserr(unsigned long oserrno)
+{
+ int i;
+
+ /* check the table for the OS error code */
+ for (i= 0; i < ERRTABLESIZE; ++i)
+ {
+ if (oserrno == errtable[i].oscode)
+ {
+ return errtable[i].sysv_errno;
+ }
+ }
+
+ /* The error code wasn't in the table. We check for a range of */
+ /* EACCES errors or exec failure errors (ENOEXEC). Otherwise */
+ /* EINVAL is returned. */
+
+ if (oserrno >= MIN_EACCES_RANGE && oserrno <= MAX_EACCES_RANGE)
+ return EACCES;
+ else if (oserrno >= MIN_EXEC_ERROR && oserrno <= MAX_EXEC_ERROR)
+ return ENOEXEC;
+ else
+ return EINVAL;
+}
+
+/* Set errno corresponsing to GetLastError() value */
+void my_osmaperr ( unsigned long oserrno)
+{
+ errno= get_errno_from_oserr(oserrno);
+}
diff --git a/mysys/my_winfile.c b/mysys/my_winfile.c
new file mode 100644
index 00000000000..f63c35ba47b
--- /dev/null
+++ b/mysys/my_winfile.c
@@ -0,0 +1,681 @@
+/* Copyright (C) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc
+
+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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ The purpose of this file is to provide implementation of file IO routines on
+ Windows that can be thought as drop-in replacement for corresponding C runtime
+ functionality.
+
+ Compared to Windows CRT, this one
+ - does not have the same file descriptor
+ limitation (default is 16384 and can be increased further, whereas CRT poses
+ a hard limit of 2048 file descriptors)
+ - the file operations are not serialized
+ - positional IO pread/pwrite is ported here.
+ - no text mode for files, all IO is "binary"
+
+ Naming convention:
+ All routines are prefixed with my_win_, e.g Posix open() is implemented with
+ my_win_open()
+
+ Implemented are
+ - POSIX routines(e.g open, read, lseek ...)
+ - Some ANSI C stream routines (fopen, fdopen, fileno, fclose)
+ - Windows CRT equvalients (my_get_osfhandle, open_osfhandle)
+
+ Worth to note:
+ - File descriptors used here are located in a range that is not compatible
+ with CRT on purpose. Attempt to use a file descriptor from Windows CRT library
+ range in my_win_* function will be punished with DBUG_ASSERT()
+
+ - File streams (FILE *) are actually from the C runtime. The routines provided
+ here are useful only in scernarios that use low-level IO with my_win_fileno()
+*/
+
+#ifdef _WIN32
+
+#include "mysys_priv.h"
+#include <share.h>
+#include <sys/stat.h>
+
+/* Associates a file descriptor with an existing operating-system file handle.*/
+File my_open_osfhandle(HANDLE handle, int oflag)
+{
+ int offset= -1;
+ uint i;
+ DBUG_ENTER("my_open_osfhandle");
+
+ pthread_mutex_lock(&THR_LOCK_open);
+ for(i= MY_FILE_MIN; i < my_file_limit;i++)
+ {
+ if(my_file_info[i].fhandle == 0)
+ {
+ struct st_my_file_info *finfo= &(my_file_info[i]);
+ finfo->type= FILE_BY_OPEN;
+ finfo->fhandle= handle;
+ finfo->oflag= oflag;
+ offset= i;
+ break;
+ }
+ }
+ pthread_mutex_unlock(&THR_LOCK_open);
+ if(offset == -1)
+ errno= EMFILE; /* to many file handles open */
+ DBUG_RETURN(offset);
+}
+
+
+static void invalidate_fd(File fd)
+{
+ DBUG_ENTER("invalidate_fd");
+ DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit);
+ my_file_info[fd].fhandle= 0;
+ DBUG_VOID_RETURN;
+}
+
+
+/* Get Windows handle for a file descriptor */
+HANDLE my_get_osfhandle(File fd)
+{
+ DBUG_ENTER("my_get_osfhandle");
+ DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit);
+ DBUG_RETURN(my_file_info[fd].fhandle);
+}
+
+
+static int my_get_open_flags(File fd)
+{
+ DBUG_ENTER("my_get_open_flags");
+ DBUG_ASSERT(fd >= MY_FILE_MIN && fd < (int)my_file_limit);
+ DBUG_RETURN(my_file_info[fd].oflag);
+}
+
+
+/*
+ Open a file with sharing. Similar to _sopen() from libc, but allows managing
+ share delete on win32
+
+ SYNOPSIS
+ my_win_sopen()
+ path file name
+ oflag operation flags
+ shflag share flag
+ pmode permission flags
+
+ RETURN VALUE
+ File descriptor of opened file if success
+ -1 and sets errno if fails.
+*/
+
+File my_win_sopen(const char *path, int oflag, int shflag, int pmode)
+{
+ int fh; /* handle of opened file */
+ int mask;
+ HANDLE osfh; /* OS handle of opened file */
+ DWORD fileaccess; /* OS file access (requested) */
+ DWORD fileshare; /* OS file sharing mode */
+ DWORD filecreate; /* OS method of opening/creating */
+ DWORD fileattrib; /* OS file attribute flags */
+ SECURITY_ATTRIBUTES SecurityAttributes;
+
+ DBUG_ENTER("my_win_sopen");
+
+ if (check_if_legal_filename(path))
+ {
+ errno= EACCES;
+ DBUG_RETURN(-1);
+ }
+ SecurityAttributes.nLength= sizeof(SecurityAttributes);
+ SecurityAttributes.lpSecurityDescriptor= NULL;
+ SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT);
+
+ /* decode the access flags */
+ switch (oflag & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
+ case _O_RDONLY: /* read access */
+ fileaccess= GENERIC_READ;
+ break;
+ case _O_WRONLY: /* write access */
+ fileaccess= GENERIC_WRITE;
+ break;
+ case _O_RDWR: /* read and write access */
+ fileaccess= GENERIC_READ | GENERIC_WRITE;
+ break;
+ default: /* error, bad oflag */
+ errno= EINVAL;
+ DBUG_RETURN(-1);
+ }
+
+ /* decode sharing flags */
+ switch (shflag) {
+ case _SH_DENYRW: /* exclusive access except delete */
+ fileshare= FILE_SHARE_DELETE;
+ break;
+ case _SH_DENYWR: /* share read and delete access */
+ fileshare= FILE_SHARE_READ | FILE_SHARE_DELETE;
+ break;
+ case _SH_DENYRD: /* share write and delete access */
+ fileshare= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+ break;
+ case _SH_DENYNO: /* share read, write and delete access */
+ fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
+ break;
+ case _SH_DENYRWD: /* exclusive access */
+ fileshare= 0L;
+ break;
+ case _SH_DENYWRD: /* share read access */
+ fileshare= FILE_SHARE_READ;
+ break;
+ case _SH_DENYRDD: /* share write access */
+ fileshare= FILE_SHARE_WRITE;
+ break;
+ case _SH_DENYDEL: /* share read and write access */
+ fileshare= FILE_SHARE_READ | FILE_SHARE_WRITE;
+ break;
+ default: /* error, bad shflag */
+ errno= EINVAL;
+ DBUG_RETURN(-1);
+ }
+
+ /* decode open/create method flags */
+ switch (oflag & (_O_CREAT | _O_EXCL | _O_TRUNC)) {
+ case 0:
+ case _O_EXCL: /* ignore EXCL w/o CREAT */
+ filecreate= OPEN_EXISTING;
+ break;
+
+ case _O_CREAT:
+ filecreate= OPEN_ALWAYS;
+ break;
+
+ case _O_CREAT | _O_EXCL:
+ case _O_CREAT | _O_TRUNC | _O_EXCL:
+ filecreate= CREATE_NEW;
+ break;
+
+ case _O_TRUNC:
+ case _O_TRUNC | _O_EXCL: /* ignore EXCL w/o CREAT */
+ filecreate= TRUNCATE_EXISTING;
+ break;
+
+ case _O_CREAT | _O_TRUNC:
+ filecreate= CREATE_ALWAYS;
+ break;
+
+ default:
+ /* this can't happen ... all cases are covered */
+ errno= EINVAL;
+ DBUG_RETURN(-1);
+ }
+
+ /* decode file attribute flags if _O_CREAT was specified */
+ fileattrib= FILE_ATTRIBUTE_NORMAL; /* default */
+ if (oflag & _O_CREAT)
+ {
+ _umask((mask= _umask(0)));
+
+ if (!((pmode & ~mask) & _S_IWRITE))
+ fileattrib= FILE_ATTRIBUTE_READONLY;
+ }
+
+ /* Set temporary file (delete-on-close) attribute if requested. */
+ if (oflag & _O_TEMPORARY)
+ {
+ fileattrib|= FILE_FLAG_DELETE_ON_CLOSE;
+ fileaccess|= DELETE;
+ }
+
+ /* Set temporary file (delay-flush-to-disk) attribute if requested.*/
+ if (oflag & _O_SHORT_LIVED)
+ fileattrib|= FILE_ATTRIBUTE_TEMPORARY;
+
+ /* Set sequential or random access attribute if requested. */
+ if (oflag & _O_SEQUENTIAL)
+ fileattrib|= FILE_FLAG_SEQUENTIAL_SCAN;
+ else if (oflag & _O_RANDOM)
+ fileattrib|= FILE_FLAG_RANDOM_ACCESS;
+
+ /* try to open/create the file */
+ if ((osfh= CreateFile(path, fileaccess, fileshare, &SecurityAttributes,
+ filecreate, fileattrib, NULL)) == INVALID_HANDLE_VALUE)
+ {
+ /*
+ OS call to open/create file failed! map the error, release
+ the lock, and return -1. note that it's not necessary to
+ call _free_osfhnd (it hasn't been used yet).
+ */
+ my_osmaperr(GetLastError()); /* map error */
+ DBUG_RETURN(-1); /* return error to caller */
+ }
+
+ if ((fh= my_open_osfhandle(osfh,
+ oflag & (_O_APPEND | _O_RDONLY | _O_TEXT))) == -1)
+ {
+ CloseHandle(osfh);
+ }
+
+ DBUG_RETURN(fh); /* return handle */
+}
+
+
+File my_win_open(const char *path, int flags)
+{
+ DBUG_ENTER("my_win_open");
+ DBUG_RETURN(my_win_sopen((char *) path, flags | _O_BINARY, _SH_DENYNO,
+ _S_IREAD | S_IWRITE));
+}
+
+
+int my_win_close(File fd)
+{
+ DBUG_ENTER("my_win_close");
+ if(CloseHandle(my_get_osfhandle(fd)))
+ {
+ invalidate_fd(fd);
+ DBUG_RETURN(0);
+ }
+ my_osmaperr(GetLastError());
+ DBUG_RETURN(-1);
+}
+
+
+size_t my_win_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset)
+{
+ DWORD nBytesRead;
+ HANDLE hFile;
+ OVERLAPPED ov= {0};
+ LARGE_INTEGER li;
+
+ DBUG_ENTER("my_win_pread");
+
+ if(!Count)
+ DBUG_RETURN(0);
+#ifdef _WIN64
+ if(Count > UINT_MAX)
+ Count= UINT_MAX;
+#endif
+
+ hFile= (HANDLE)my_get_osfhandle(Filedes);
+ li.QuadPart= offset;
+ ov.Offset= li.LowPart;
+ ov.OffsetHigh= li.HighPart;
+
+ if(!ReadFile(hFile, Buffer, (DWORD)Count, &nBytesRead, &ov))
+ {
+ DWORD lastError= GetLastError();
+ /*
+ ERROR_BROKEN_PIPE is returned when no more data coming
+ through e.g. a command pipe in windows : see MSDN on ReadFile.
+ */
+ if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE)
+ DBUG_RETURN(0); /*return 0 at EOF*/
+ my_osmaperr(lastError);
+ DBUG_RETURN((size_t)-1);
+ }
+ DBUG_RETURN(nBytesRead);
+}
+
+
+size_t my_win_read(File Filedes, uchar *Buffer, size_t Count)
+{
+ DWORD nBytesRead;
+ HANDLE hFile;
+
+ DBUG_ENTER("my_win_read");
+ if(!Count)
+ DBUG_RETURN(0);
+#ifdef _WIN64
+ if(Count > UINT_MAX)
+ Count= UINT_MAX;
+#endif
+
+ hFile= (HANDLE)my_get_osfhandle(Filedes);
+
+ if(!ReadFile(hFile, Buffer, (DWORD)Count, &nBytesRead, NULL))
+ {
+ DWORD lastError= GetLastError();
+ /*
+ ERROR_BROKEN_PIPE is returned when no more data coming
+ through e.g. a command pipe in windows : see MSDN on ReadFile.
+ */
+ if(lastError == ERROR_HANDLE_EOF || lastError == ERROR_BROKEN_PIPE)
+ DBUG_RETURN(0); /*return 0 at EOF*/
+ my_osmaperr(lastError);
+ DBUG_RETURN((size_t)-1);
+ }
+ DBUG_RETURN(nBytesRead);
+}
+
+
+size_t my_win_pwrite(File Filedes, const uchar *Buffer, size_t Count,
+ my_off_t offset)
+{
+ DWORD nBytesWritten;
+ HANDLE hFile;
+ OVERLAPPED ov= {0};
+ LARGE_INTEGER li;
+
+ DBUG_ENTER("my_win_pwrite");
+ DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count: %llu, offset: %llu",
+ Filedes, Buffer, (ulonglong)Count, (ulonglong)offset));
+
+ if(!Count)
+ DBUG_RETURN(0);
+
+#ifdef _WIN64
+ if(Count > UINT_MAX)
+ Count= UINT_MAX;
+#endif
+
+ hFile= (HANDLE)my_get_osfhandle(Filedes);
+ li.QuadPart= offset;
+ ov.Offset= li.LowPart;
+ ov.OffsetHigh= li.HighPart;
+
+ if(!WriteFile(hFile, Buffer, (DWORD)Count, &nBytesWritten, &ov))
+ {
+ my_osmaperr(GetLastError());
+ DBUG_RETURN((size_t)-1);
+ }
+ else
+ DBUG_RETURN(nBytesWritten);
+}
+
+
+my_off_t my_win_lseek(File fd, my_off_t pos, int whence)
+{
+ LARGE_INTEGER offset;
+ LARGE_INTEGER newpos;
+
+ DBUG_ENTER("my_win_lseek");
+
+ /* Check compatibility of Windows and Posix seek constants */
+ compile_time_assert(FILE_BEGIN == SEEK_SET && FILE_CURRENT == SEEK_CUR
+ && FILE_END == SEEK_END);
+
+ offset.QuadPart= pos;
+ if(!SetFilePointerEx(my_get_osfhandle(fd), offset, &newpos, whence))
+ {
+ my_osmaperr(GetLastError());
+ newpos.QuadPart= -1;
+ }
+ DBUG_RETURN(newpos.QuadPart);
+}
+
+
+#ifndef FILE_WRITE_TO_END_OF_FILE
+#define FILE_WRITE_TO_END_OF_FILE 0xffffffff
+#endif
+size_t my_win_write(File fd, const uchar *Buffer, size_t Count)
+{
+ DWORD nWritten;
+ OVERLAPPED ov;
+ OVERLAPPED *pov= NULL;
+ HANDLE hFile;
+
+ DBUG_ENTER("my_win_write");
+ DBUG_PRINT("my",("Filedes: %d, Buffer: %p, Count %llu", fd, Buffer,
+ (ulonglong)Count));
+
+ if(!Count)
+ DBUG_RETURN(0);
+
+#ifdef _WIN64
+ if(Count > UINT_MAX)
+ Count= UINT_MAX;
+#endif
+
+ if(my_get_open_flags(fd) & _O_APPEND)
+ {
+ /*
+ Atomic append to the end of file is is done by special initialization of
+ the OVERLAPPED structure. See MSDN WriteFile documentation for more info.
+ */
+ memset(&ov, 0, sizeof(ov));
+ ov.Offset= FILE_WRITE_TO_END_OF_FILE;
+ ov.OffsetHigh= -1;
+ pov= &ov;
+ }
+
+ hFile= my_get_osfhandle(fd);
+ if(!WriteFile(hFile, Buffer, (DWORD)Count, &nWritten, pov))
+ {
+ my_osmaperr(GetLastError());
+ DBUG_RETURN((size_t)-1);
+ }
+ DBUG_RETURN(nWritten);
+}
+
+
+int my_win_chsize(File fd, my_off_t newlength)
+{
+ HANDLE hFile;
+ LARGE_INTEGER length;
+ DBUG_ENTER("my_win_chsize");
+
+ hFile= (HANDLE) my_get_osfhandle(fd);
+ length.QuadPart= newlength;
+ if (!SetFilePointerEx(hFile, length , NULL , FILE_BEGIN))
+ goto err;
+ if (!SetEndOfFile(hFile))
+ goto err;
+ DBUG_RETURN(0);
+err:
+ my_osmaperr(GetLastError());
+ my_errno= errno;
+ DBUG_RETURN(-1);
+}
+
+
+/* Get the file descriptor for stdin,stdout or stderr */
+static File my_get_stdfile_descriptor(FILE *stream)
+{
+ HANDLE hFile;
+ DWORD nStdHandle;
+ DBUG_ENTER("my_get_stdfile_descriptor");
+
+ if(stream == stdin)
+ nStdHandle= STD_INPUT_HANDLE;
+ else if(stream == stdout)
+ nStdHandle= STD_OUTPUT_HANDLE;
+ else if(stream == stderr)
+ nStdHandle= STD_ERROR_HANDLE;
+ else
+ DBUG_RETURN(-1);
+
+ hFile= GetStdHandle(nStdHandle);
+ if(hFile != INVALID_HANDLE_VALUE)
+ DBUG_RETURN(my_open_osfhandle(hFile, 0));
+ DBUG_RETURN(-1);
+}
+
+
+File my_win_fileno(FILE *file)
+{
+ HANDLE hFile= (HANDLE)_get_osfhandle(fileno(file));
+ int retval= -1;
+ uint i;
+
+ DBUG_ENTER("my_win_fileno");
+
+ for(i= MY_FILE_MIN; i < my_file_limit; i++)
+ {
+ if(my_file_info[i].fhandle == hFile)
+ {
+ retval= i;
+ break;
+ }
+ }
+ if(retval == -1)
+ /* try std stream */
+ DBUG_RETURN(my_get_stdfile_descriptor(file));
+ DBUG_RETURN(retval);
+}
+
+
+FILE *my_win_fopen(const char *filename, const char *type)
+{
+ FILE *file;
+ int flags= 0;
+ DBUG_ENTER("my_win_open");
+
+ /*
+ If we are not creating, then we need to use my_access to make sure
+ the file exists since Windows doesn't handle files like "com1.sym"
+ very well
+ */
+ if (check_if_legal_filename(filename))
+ {
+ errno= EACCES;
+ DBUG_RETURN(NULL);
+ }
+
+ file= fopen(filename, type);
+ if(!file)
+ DBUG_RETURN(NULL);
+
+ if(strchr(type,'a') != NULL)
+ flags= O_APPEND;
+
+ /*
+ Register file handle in my_table_info.
+ Necessary for my_fileno()
+ */
+ if(my_open_osfhandle((HANDLE)_get_osfhandle(fileno(file)), flags) < 0)
+ {
+ fclose(file);
+ DBUG_RETURN(NULL);
+ }
+ DBUG_RETURN(file);
+}
+
+
+FILE * my_win_fdopen(File fd, const char *type)
+{
+ FILE *file;
+ int crt_fd;
+ int flags= 0;
+
+ DBUG_ENTER("my_win_fdopen");
+
+ if(strchr(type,'a') != NULL)
+ flags= O_APPEND;
+ /* Convert OS file handle to CRT file descriptor and then call fdopen*/
+ crt_fd= _open_osfhandle((intptr_t)my_get_osfhandle(fd), flags);
+ if(crt_fd < 0)
+ file= NULL;
+ else
+ file= fdopen(crt_fd, type);
+ DBUG_RETURN(file);
+}
+
+
+int my_win_fclose(FILE *file)
+{
+ File fd;
+
+ DBUG_ENTER("my_win_close");
+ fd= my_fileno(file);
+ if(fd < 0)
+ DBUG_RETURN(-1);
+ if(fclose(file) < 0)
+ DBUG_RETURN(-1);
+ invalidate_fd(fd);
+ DBUG_RETURN(0);
+}
+
+
+
+/*
+ Quick and dirty my_fstat() implementation for Windows.
+ Use CRT fstat on temporarily allocated file descriptor.
+ Patch file size, because size that fstat returns is not
+ reliable (may be outdated)
+*/
+int my_win_fstat(File fd, struct _stati64 *buf)
+{
+ int crt_fd;
+ int retval;
+ HANDLE hFile, hDup;
+
+ DBUG_ENTER("my_win_fstat");
+
+ hFile= my_get_osfhandle(fd);
+ if(!DuplicateHandle( GetCurrentProcess(), hFile, GetCurrentProcess(),
+ &hDup ,0,FALSE,DUPLICATE_SAME_ACCESS))
+ {
+ my_osmaperr(GetLastError());
+ DBUG_RETURN(-1);
+ }
+ if ((crt_fd= _open_osfhandle((intptr_t)hDup,0)) < 0)
+ DBUG_RETURN(-1);
+
+ retval= _fstati64(crt_fd, buf);
+ if(retval == 0)
+ {
+ /* File size returned by stat is not accurate (may be outdated), fix it*/
+ GetFileSizeEx(hDup, (PLARGE_INTEGER) (&(buf->st_size)));
+ }
+ _close(crt_fd);
+ DBUG_RETURN(retval);
+}
+
+
+
+int my_win_stat( const char *path, struct _stati64 *buf)
+{
+ DBUG_ENTER("my_win_stat");
+ if(_stati64( path, buf) == 0)
+ {
+ /* File size returned by stat is not accurate (may be outdated), fix it*/
+ WIN32_FILE_ATTRIBUTE_DATA data;
+ if (GetFileAttributesEx(path, GetFileExInfoStandard, &data))
+ {
+ LARGE_INTEGER li;
+ li.LowPart= data.nFileSizeLow;
+ li.HighPart= data.nFileSizeHigh;
+ buf->st_size= li.QuadPart;
+ }
+ DBUG_RETURN(0);
+ }
+ DBUG_RETURN(-1);
+}
+
+
+
+int my_win_fsync(File fd)
+{
+ DBUG_ENTER("my_win_fsync");
+ if(FlushFileBuffers(my_get_osfhandle(fd)))
+ DBUG_RETURN(0);
+ my_osmaperr(GetLastError());
+ DBUG_RETURN(-1);
+}
+
+
+
+int my_win_dup(File fd)
+{
+ HANDLE hDup;
+ DBUG_ENTER("my_win_dup");
+ if (DuplicateHandle(GetCurrentProcess(), my_get_osfhandle(fd),
+ GetCurrentProcess(), &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS))
+ {
+ DBUG_RETURN(my_open_osfhandle(hDup, my_get_open_flags(fd)));
+ }
+ my_osmaperr(GetLastError());
+ DBUG_RETURN(-1);
+}
+
+#endif /*_WIN32*/
diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c
index 6adf24ef543..5fbad39597c 100644
--- a/mysys/my_winthread.c
+++ b/mysys/my_winthread.c
@@ -156,8 +156,19 @@ int win_pthread_setspecific(void *a,void *b,uint length)
int my_pthread_once(my_pthread_once_t *once_control,
void (*init_routine)(void))
{
- LONG state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS,
- MY_PTHREAD_ONCE_INIT);
+ LONG state;
+
+ /*
+ Do "dirty" read to find out if initialization is already done, to
+ save an interlocked operation in common case. Memory barriers are ensured by
+ Visual C++ volatile implementation.
+ */
+ if (*once_control == MY_PTHREAD_ONCE_DONE)
+ return 0;
+
+ state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS,
+ MY_PTHREAD_ONCE_INIT);
+
switch(state)
{
case MY_PTHREAD_ONCE_INIT:
diff --git a/mysys/my_write.c b/mysys/my_write.c
index 52127545888..ae2eb155068 100644
--- a/mysys/my_write.c
+++ b/mysys/my_write.c
@@ -22,12 +22,14 @@
size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
{
- size_t writenbytes, written;
+ size_t writtenbytes, written;
uint errors;
DBUG_ENTER("my_write");
DBUG_PRINT("my",("fd: %d Buffer: 0x%lx Count: %lu MyFlags: %d",
Filedes, (long) Buffer, (ulong) Count, MyFlags));
errors=0; written=0;
+ if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP)))
+ MyFlags|= my_global_flags;
/* The behavior of write(fd, buf, 0) is not portable */
if (unlikely(!Count))
@@ -35,17 +37,27 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
for (;;)
{
- if ((writenbytes= write(Filedes, Buffer, Count)) == Count)
+#ifdef _WIN32
+ if(Filedes < 0)
+ {
+ my_errno= errno= EBADF;
+ DBUG_RETURN((size_t)-1);
+ }
+ writtenbytes= my_win_write(Filedes, Buffer, Count);
+#else
+ writtenbytes= write(Filedes, Buffer, Count);
+#endif
+ if (writtenbytes == Count)
break;
- if (writenbytes != (size_t) -1)
+ if (writtenbytes != (size_t) -1)
{ /* Safeguard */
- written+=writenbytes;
- Buffer+=writenbytes;
- Count-=writenbytes;
+ written+= writtenbytes;
+ Buffer+= writtenbytes;
+ Count-= writtenbytes;
}
- my_errno=errno;
+ my_errno= errno;
DBUG_PRINT("error",("Write only %ld bytes, error: %d",
- (long) writenbytes, my_errno));
+ (long) writtenbytes, my_errno));
#ifndef NO_BACKGROUND
#ifdef THREAD
if (my_thread_var->abort)
@@ -59,38 +71,39 @@ size_t my_write(int Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
continue;
}
- if ((writenbytes == 0 || writenbytes == (size_t) -1))
+ if ((writtenbytes == 0 || writtenbytes == (size_t) -1))
{
if (my_errno == EINTR)
{
DBUG_PRINT("debug", ("my_write() was interrupted and returned %ld",
- (long) writenbytes));
+ (long) writtenbytes));
continue; /* Interrupted */
}
- if (!writenbytes && !errors++) /* Retry once */
+ if (!writtenbytes && !errors++) /* Retry once */
{
/* We may come here if the file quota is exeeded */
- errno=EFBIG; /* Assume this is the error */
+ errno= EFBIG; /* Assume this is the error */
continue;
}
}
else
continue; /* Retry */
#endif
+
+ /* Don't give a warning if it's ok that we only write part of the data */
if (MyFlags & (MY_NABP | MY_FNABP))
{
if (MyFlags & (MY_WME | MY_FAE | MY_FNABP))
{
- my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG),
+ my_error(EE_WRITE, MYF(ME_BELL | ME_WAITTANG | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))),
my_filename(Filedes),my_errno);
}
DBUG_RETURN(MY_FILE_ERROR); /* Error on read */
}
- else
- break; /* Return bytes written */
+ break; /* Return bytes written */
}
if (MyFlags & (MY_NABP | MY_FNABP))
- DBUG_RETURN(0); /* Want only errors */
- DBUG_RETURN(writenbytes+written);
+ DBUG_RETURN(0); /* Want only errors */
+ DBUG_RETURN(writtenbytes+written);
} /* my_write */
diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h
index 113b64005f2..6d39999aa86 100644
--- a/mysys/mysys_priv.h
+++ b/mysys/mysys_priv.h
@@ -45,3 +45,27 @@ extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time;
void my_error_unregister_all(void);
void my_thread_destroy_mutex(void);
my_bool my_wait_for_other_threads_to_die(uint number_of_threads);
+
+#ifdef _WIN32
+/* my_winfile.c exports, should not be used outside mysys */
+extern File my_win_open(const char *path, int oflag);
+extern int my_win_close(File fd);
+extern size_t my_win_read(File fd, uchar *buffer, size_t count);
+extern size_t my_win_write(File fd, const uchar *buffer, size_t count);
+extern size_t my_win_pread(File fd, uchar *buffer, size_t count,
+ my_off_t offset);
+extern size_t my_win_pwrite(File fd, const uchar *buffer, size_t count,
+ my_off_t offset);
+extern my_off_t my_win_lseek(File fd, my_off_t pos, int whence);
+extern int my_win_chsize(File fd, my_off_t newlength);
+extern FILE* my_win_fopen(const char *filename, const char *type);
+extern File my_win_fclose(FILE *file);
+extern File my_win_fileno(FILE *file);
+extern FILE* my_win_fdopen(File Filedes, const char *type);
+extern int my_win_stat(const char *path, struct _stat64 *buf);
+extern int my_win_fstat(File fd, struct _stat64 *buf);
+extern int my_win_fsync(File fd);
+extern File my_win_dup(File fd);
+extern File my_win_sopen(const char *path, int oflag, int shflag, int perm);
+extern File my_open_osfhandle(HANDLE handle, int oflag);
+#endif
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index 9421a3b2d98..d284badfef4 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -836,6 +836,7 @@ static void print_deadlock_warning(safe_mutex_t *new_mutex,
mutex_root->file, mutex_root->line));
}
fflush(stderr);
+ DBUG_ASSERT(my_assert_on_error == 0);
DBUG_VOID_RETURN;
}
diff --git a/mysys/thr_rwlock.c b/mysys/thr_rwlock.c
index ea98a854a4d..2978d91090d 100644
--- a/mysys/thr_rwlock.c
+++ b/mysys/thr_rwlock.c
@@ -19,6 +19,119 @@
#if defined(THREAD) && !defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && !defined(HAVE_RWLOCK_INIT)
#include <errno.h>
+#ifdef _WIN32
+
+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);
+
+static srw_func my_InitializeSRWLock;
+static srw_func my_AcquireSRWLockExclusive;
+static srw_func my_ReleaseSRWLockExclusive;
+static srw_func my_AcquireSRWLockShared;
+static srw_func my_ReleaseSRWLockShared;
+
+static srw_bool_func my_TryAcquireSRWLockExclusive;
+static srw_bool_func my_TryAcquireSRWLockShared;
+
+/**
+ Check for presence of Windows slim reader writer lock function.
+ Load function pointers.
+*/
+
+static void check_srwlock_availability(void)
+{
+ HMODULE module= GetModuleHandle("kernel32");
+
+ my_InitializeSRWLock= (srw_func) GetProcAddress(module,
+ "InitializeSRWLock");
+ my_AcquireSRWLockExclusive= (srw_func) GetProcAddress(module,
+ "AcquireSRWLockExclusive");
+ my_AcquireSRWLockShared= (srw_func) GetProcAddress(module,
+ "AcquireSRWLockShared");
+ my_ReleaseSRWLockExclusive= (srw_func) GetProcAddress(module,
+ "ReleaseSRWLockExclusive");
+ my_ReleaseSRWLockShared= (srw_func) GetProcAddress(module,
+ "ReleaseSRWLockShared");
+ my_TryAcquireSRWLockExclusive= (srw_bool_func) GetProcAddress(module,
+ "TryAcquireSRWLockExclusive");
+ my_TryAcquireSRWLockShared= (srw_bool_func) GetProcAddress(module,
+ "TryAcquireSRWLockShared");
+
+ /*
+ We currently require TryAcquireSRWLockExclusive. This API is missing on
+ Vista, this means SRWLock are only used starting with Win7.
+
+ If "trylock" usage for rwlocks is eliminated from server codebase (it is used
+ in a single place currently, in query cache), then SRWLock can be enabled on
+ Vista too. In this case condition below needs to be changed to e.g check
+ for my_InitializeSRWLock.
+ */
+
+ if (my_TryAcquireSRWLockExclusive)
+ have_srwlock= TRUE;
+
+}
+
+
+static int srw_init(my_rw_lock_t *rwp)
+{
+ my_InitializeSRWLock(&rwp->srwlock);
+ rwp->have_exclusive_srwlock = FALSE;
+ return 0;
+}
+
+
+static int srw_rdlock(my_rw_lock_t *rwp)
+{
+ my_AcquireSRWLockShared(&rwp->srwlock);
+ return 0;
+}
+
+
+static int srw_tryrdlock(my_rw_lock_t *rwp)
+{
+
+ if (!my_TryAcquireSRWLockShared(&rwp->srwlock))
+ return EBUSY;
+ return 0;
+}
+
+
+static int srw_wrlock(my_rw_lock_t *rwp)
+{
+ my_AcquireSRWLockExclusive(&rwp->srwlock);
+ rwp->have_exclusive_srwlock= TRUE;
+ return 0;
+}
+
+
+static int srw_trywrlock(my_rw_lock_t *rwp)
+{
+ if (!my_TryAcquireSRWLockExclusive(&rwp->srwlock))
+ return EBUSY;
+ rwp->have_exclusive_srwlock= TRUE;
+ return 0;
+}
+
+
+static int srw_unlock(my_rw_lock_t *rwp)
+{
+ if (rwp->have_exclusive_srwlock)
+ {
+ rwp->have_exclusive_srwlock= FALSE;
+ my_ReleaseSRWLockExclusive(&rwp->srwlock);
+ }
+ else
+ {
+ my_ReleaseSRWLockShared(&rwp->srwlock);
+ }
+ return 0;
+}
+
+#endif /*_WIN32 */
+
/*
Source base from Sun Microsystems SPILT, simplified for MySQL use
-- Joshua Chamas
@@ -62,6 +175,22 @@ int my_rwlock_init(rw_lock_t *rwp, void *arg __attribute__((unused)))
{
pthread_condattr_t cond_attr;
+#ifdef _WIN32
+ /*
+ Once initialization is used here rather than in my_init(), in order to
+ - avoid my_init() pitfalls- (undefined order in which initialization should
+ run)
+ - be potentially useful C++ (static constructors)
+ - just to simplify the API.
+ Also, the overhead is of my_pthread_once is very small.
+ */
+ static my_pthread_once_t once_control= MY_PTHREAD_ONCE_INIT;
+ my_pthread_once(&once_control, check_srwlock_availability);
+
+ if (have_srwlock)
+ return srw_init(rwp);
+#endif
+
pthread_mutex_init( &rwp->lock, MY_MUTEX_INIT_FAST);
pthread_condattr_init( &cond_attr );
pthread_cond_init( &rwp->readers, &cond_attr );
@@ -77,6 +206,10 @@ int my_rwlock_init(rw_lock_t *rwp, void *arg __attribute__((unused)))
int my_rwlock_destroy(rw_lock_t *rwp)
{
+#ifdef _WIN32
+ if (have_srwlock)
+ return 0; /* no destroy function */
+#endif
pthread_mutex_destroy( &rwp->lock );
pthread_cond_destroy( &rwp->readers );
pthread_cond_destroy( &rwp->writers );
@@ -86,6 +219,11 @@ int my_rwlock_destroy(rw_lock_t *rwp)
int my_rw_rdlock(rw_lock_t *rwp)
{
+#ifdef _WIN32
+ if (have_srwlock)
+ return srw_rdlock(rwp);
+#endif
+
pthread_mutex_lock(&rwp->lock);
/* active or queued writers */
@@ -100,6 +238,12 @@ int my_rw_rdlock(rw_lock_t *rwp)
int my_rw_tryrdlock(rw_lock_t *rwp)
{
int res;
+
+#ifdef _WIN32
+ if (have_srwlock)
+ return srw_tryrdlock(rwp);
+#endif
+
pthread_mutex_lock(&rwp->lock);
if ((rwp->state < 0 ) || rwp->waiters)
res= EBUSY; /* Can't get lock */
@@ -115,6 +259,11 @@ int my_rw_tryrdlock(rw_lock_t *rwp)
int my_rw_wrlock(rw_lock_t *rwp)
{
+#ifdef _WIN32
+ if (have_srwlock)
+ return srw_wrlock(rwp);
+#endif
+
pthread_mutex_lock(&rwp->lock);
rwp->waiters++; /* another writer queued */
@@ -130,6 +279,12 @@ int my_rw_wrlock(rw_lock_t *rwp)
int my_rw_trywrlock(rw_lock_t *rwp)
{
int res;
+
+#ifdef _WIN32
+ if (have_srwlock)
+ return srw_trywrlock(rwp);
+#endif
+
pthread_mutex_lock(&rwp->lock);
if (rwp->state)
res= EBUSY; /* Can't get lock */
@@ -145,6 +300,11 @@ int my_rw_trywrlock(rw_lock_t *rwp)
int my_rw_unlock(rw_lock_t *rwp)
{
+#ifdef _WIN32
+ if (have_srwlock)
+ return srw_unlock(rwp);
+#endif
+
DBUG_PRINT("rw_unlock",
("state: %d waiters: %d", rwp->state, rwp->waiters));
pthread_mutex_lock(&rwp->lock);
diff --git a/plugin/feedback/CMakeLists.txt b/plugin/feedback/CMakeLists.txt
new file mode 100644
index 00000000000..a94232a4698
--- /dev/null
+++ b/plugin/feedback/CMakeLists.txt
@@ -0,0 +1,11 @@
+INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/sql ${CMAKE_SOURCE_DIR}/regex
+ ${CMAKE_SOURCE_DIR}/extra/yassl/include)
+
+SET(FEEDBACK_SOURCES feedback.cc sender_thread.cc
+ url_base.cc url_http.cc utils.cc)
+
+SET(FEEDBACK_LIBS Ws2_32)
+
+MYSQL_PLUGIN(FEEDBACK)
diff --git a/plugin/feedback/Makefile.am b/plugin/feedback/Makefile.am
new file mode 100644
index 00000000000..7d2a61d593f
--- /dev/null
+++ b/plugin/feedback/Makefile.am
@@ -0,0 +1,18 @@
+pkgplugindir = $(pkglibdir)/plugin
+INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
+ -I$(top_srcdir)/regex -I$(top_srcdir)/sql
+
+EXTRA_LTLIBRARIES = feedback.la libfeedback.la
+pkgplugin_LTLIBRARIES = @plugin_feedback_shared_target@
+feedback_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices
+feedback_la_CXXFLAGS = -shared -DMYSQL_DYNAMIC_PLUGIN
+feedback_la_SOURCES = feedback.cc utils.cc url_base.cc url_http.cc \
+ sender_thread.cc
+
+noinst_LTLIBRARIES = @plugin_feedback_static_target@
+libfeedback_la_SOURCES= feedback.cc utils.cc url_base.cc url_http.cc \
+ sender_thread.cc
+
+noinst_HEADERS = feedback.h
+EXTRA_DIST = CMakeLists.txt plug.in
+
diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc
new file mode 100644
index 00000000000..e0d76706a0e
--- /dev/null
+++ b/plugin/feedback/feedback.cc
@@ -0,0 +1,373 @@
+/* Copyright (C) 2010 Sergei Golubchik and 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
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "feedback.h"
+
+/* MySQL functions/variables not declared in mysql_priv.h */
+int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond);
+int fill_status(THD *thd, TABLE_LIST *tables, COND *cond);
+extern ST_SCHEMA_TABLE schema_tables[];
+
+namespace feedback {
+
+char server_uid_buf[SERVER_UID_SIZE+1]; ///< server uid will be written here
+
+/* backing store for system variables */
+static char *server_uid= server_uid_buf, *url;
+char *user_info;
+ulong send_timeout, send_retry_wait;
+
+/**
+ these three are used to communicate the shutdown signal to the
+ background thread
+*/
+pthread_mutex_t sleep_mutex;
+pthread_cond_t sleep_condition;
+volatile bool shutdown_plugin;
+static pthread_t sender_thread;
+
+Url **urls; ///< list of urls to send the report to
+uint url_count;
+
+ST_SCHEMA_TABLE *i_s_feedback; ///< table descriptor for our I_S table
+
+/*
+ the column names *must* match column names in GLOBAL_VARIABLES and
+ GLOBAL_STATUS tables otherwise condition pushdown below will not work
+*/
+static ST_FIELD_INFO feedback_fields[] =
+{
+ {"VARIABLE_NAME", 255, MYSQL_TYPE_STRING, 0, 0, 0, 0},
+ {"VARIABLE_VALUE", 1024, MYSQL_TYPE_STRING, 0, 0, 0, 0},
+ {0, 0, MYSQL_TYPE_NULL, 0, 0, 0, 0}
+};
+
+static COND * const OOM= (COND*)1;
+
+/**
+ Generate the COND tree for the condition pushdown
+
+ This function takes a list of strings and generates an Item tree
+ corresponding to the following expression:
+
+ field LIKE str1 OR field LIKE str2 OR field LIKE str3 OR ...
+
+ where 'field' is the first field in the table - VARIABLE_NAME field -
+ and str1, str2... are strings from the list.
+
+ This condition is used to filter the selected rows, emulating
+
+ SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE ...
+*/
+static COND* make_cond(THD *thd, TABLE_LIST *tables, LEX_STRING *filter)
+{
+ Item_cond_or *res= NULL;
+ Name_resolution_context nrc;
+ const char *db= tables->db, *table= tables->alias,
+ *field= tables->table->field[0]->field_name;
+ CHARSET_INFO *cs= &my_charset_latin1;
+
+ if (!filter->str)
+ return 0;
+
+ nrc.init();
+ nrc.resolve_in_table_list_only(tables);
+
+ res= new Item_cond_or();
+ if (!res)
+ return OOM;
+
+ for (; filter->str; filter++)
+ {
+ Item_field *fld= new Item_field(&nrc, db, table, field);
+ Item_string *pattern= new Item_string(filter->str, filter->length, cs);
+ Item_string *escape= new Item_string("\\", 1, cs);
+
+ if (!fld || !pattern || !escape)
+ return OOM;
+
+ Item_func_like *like= new Item_func_like(fld, pattern, escape, 0);
+
+ if (!like)
+ return OOM;
+
+ res->add(like);
+ }
+
+ if (res->fix_fields(thd, (Item**)&res))
+ return OOM;
+
+ return res;
+}
+
+/**
+ System variables that we want to see in the feedback report
+*/
+static LEX_STRING vars_filter[]= {
+ {C_STRING_WITH_LEN("auto\\_increment%")},
+ {C_STRING_WITH_LEN("binlog\\_format")},
+ {C_STRING_WITH_LEN("character\\_set\\_%")},
+ {C_STRING_WITH_LEN("collation%")},
+ {C_STRING_WITH_LEN("engine\\_condition\\_pushdown")},
+ {C_STRING_WITH_LEN("event\\_scheduler")},
+ {C_STRING_WITH_LEN("feedback\\_%")},
+ {C_STRING_WITH_LEN("ft\\_m%")},
+ {C_STRING_WITH_LEN("have\\_%")},
+ {C_STRING_WITH_LEN("%\\_size")},
+ {C_STRING_WITH_LEN("%\\_length%")},
+ {C_STRING_WITH_LEN("%\\_timeout")},
+ {C_STRING_WITH_LEN("large\\_%")},
+ {C_STRING_WITH_LEN("lc_time_names")},
+ {C_STRING_WITH_LEN("log")},
+ {C_STRING_WITH_LEN("log_bin")},
+ {C_STRING_WITH_LEN("log_output")},
+ {C_STRING_WITH_LEN("log_slow_queries")},
+ {C_STRING_WITH_LEN("log_slow_time")},
+ {C_STRING_WITH_LEN("lower_case%")},
+ {C_STRING_WITH_LEN("max_allowed_packet")},
+ {C_STRING_WITH_LEN("max_connections")},
+ {C_STRING_WITH_LEN("max_prepared_stmt_count")},
+ {C_STRING_WITH_LEN("max_sp_recursion_depth")},
+ {C_STRING_WITH_LEN("max_user_connections")},
+ {C_STRING_WITH_LEN("max_write_lock_count")},
+ {C_STRING_WITH_LEN("myisam_recover_options")},
+ {C_STRING_WITH_LEN("myisam_repair_threads")},
+ {C_STRING_WITH_LEN("myisam_stats_method")},
+ {C_STRING_WITH_LEN("myisam_use_mmap")},
+ {C_STRING_WITH_LEN("net\\_%")},
+ {C_STRING_WITH_LEN("new")},
+ {C_STRING_WITH_LEN("old%")},
+ {C_STRING_WITH_LEN("optimizer%")},
+ {C_STRING_WITH_LEN("profiling")},
+ {C_STRING_WITH_LEN("query_cache%")},
+ {C_STRING_WITH_LEN("secure_auth")},
+ {C_STRING_WITH_LEN("slow_launch_time")},
+ {C_STRING_WITH_LEN("sql%")},
+ {C_STRING_WITH_LEN("storage_engine")},
+ {C_STRING_WITH_LEN("sync_binlog")},
+ {C_STRING_WITH_LEN("table_definition_cache")},
+ {C_STRING_WITH_LEN("table_open_cache")},
+ {C_STRING_WITH_LEN("thread_handling")},
+ {C_STRING_WITH_LEN("time_zone")},
+ {C_STRING_WITH_LEN("timed_mutexes")},
+ {C_STRING_WITH_LEN("version%")},
+ {0, 0}
+};
+
+/**
+ Status variables that we want to see in the feedback report
+
+ (empty list = no WHERE condition)
+*/
+static LEX_STRING status_filter[]= {{0, 0}};
+
+/**
+ Fill our I_S table with data
+
+ This function works by invoking fill_variables() and
+ fill_status() of the corresponding I_S tables - to have
+ their data UNION-ed in the same target table.
+ After that it invokes our own fill_* functions
+ from the utils.cc - to get the data that aren't available in the
+ I_S.GLOBAL_VARIABLES and I_S.GLOBAL_STATUS.
+*/
+int fill_feedback(THD *thd, TABLE_LIST *tables, COND *unused)
+{
+ int res;
+ COND *cond;
+
+ tables->schema_table= schema_tables + SCH_GLOBAL_VARIABLES;
+ cond= make_cond(thd, tables, vars_filter);
+ res= (cond == OOM) ? 1 : fill_variables(thd, tables, cond);
+
+ tables->schema_table= schema_tables + SCH_GLOBAL_STATUS;
+ if (!res)
+ {
+ cond= make_cond(thd, tables, status_filter);
+ res= (cond == OOM) ? 1 : fill_status(thd, tables, cond);
+ }
+
+ tables->schema_table= i_s_feedback;
+ res= res || fill_plugin_version(thd, tables)
+ || fill_misc_data(thd, tables)
+ || fill_linux_info(thd, tables);
+
+ return res;
+}
+
+/**
+ plugin initialization function
+*/
+static int init(void *p)
+{
+ i_s_feedback= (ST_SCHEMA_TABLE*) p;
+ /* initialize the I_S descriptor structure */
+ i_s_feedback->fields_info= feedback_fields; ///< field descriptor
+ i_s_feedback->fill_table= fill_feedback; ///< how to fill the I_S table
+ i_s_feedback->idx_field1 = 0; ///< virtual index on the 1st col
+
+ if (calculate_server_uid(server_uid_buf))
+ return 1;
+
+ prepare_linux_info();
+
+ url_count= 0;
+ if (*url)
+ {
+ // now we split url on spaces and store them in Url objects
+ int slot;
+ char *s, *e;
+
+ for (s= url, url_count= 1; *s; s++)
+ if (*s == ' ')
+ url_count++;
+
+ urls= (Url **)my_malloc(url_count*sizeof(Url*), MYF(MY_WME));
+ if (!urls)
+ return 1;
+
+ for (s= url, e = url+1, slot= 0; e[-1]; e++)
+ if (*e == 0 || *e == ' ')
+ {
+ if (e > s && (urls[slot]= Url::create(s, e - s)))
+ slot++;
+ else
+ {
+ if (e > s)
+ sql_print_error("feedback plugin: invalid url '%.*s'", (int)(e-s), s);
+ url_count--;
+ }
+ s= e + 1;
+ }
+
+ // create a background thread to handle urls, if any
+ if (url_count)
+ {
+ pthread_mutex_init(&sleep_mutex, 0);
+ pthread_cond_init(&sleep_condition, 0);
+ shutdown_plugin= false;
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+ if (pthread_create(&sender_thread, &attr, background_thread, 0) != 0)
+ {
+ sql_print_error("feedback plugin: failed to start a background thread");
+ return 1;
+ }
+ }
+ else
+ my_free(urls, MYF(0));
+ }
+
+ return 0;
+}
+
+/**
+ plugin deinitialization function
+*/
+static int free(void *p)
+{
+ if (url_count)
+ {
+ pthread_mutex_lock(&sleep_mutex);
+ shutdown_plugin= true;
+ pthread_cond_signal(&sleep_condition);
+ pthread_mutex_unlock(&sleep_mutex);
+ pthread_join(sender_thread, NULL);
+
+ pthread_mutex_destroy(&sleep_mutex);
+ pthread_cond_destroy(&sleep_condition);
+
+ for (uint i= 0; i < url_count; i++)
+ delete urls[i];
+ my_free(urls, MYF(0));
+ }
+ return 0;
+}
+
+#ifdef HAVE_OPENSSL
+#define DEFAULT_PROTO "https://"
+#else
+#define DEFAULT_PROTO "http://"
+#endif
+
+static MYSQL_SYSVAR_STR(server_uid, server_uid,
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_NOCMDOPT,
+ "Automatically calculated server unique id hash.", NULL, NULL, 0);
+static MYSQL_SYSVAR_STR(user_info, user_info,
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_RQCMDARG,
+ "User specified string that will be included in the feedback report.",
+ NULL, NULL, "");
+static MYSQL_SYSVAR_STR(url, url, PLUGIN_VAR_READONLY | PLUGIN_VAR_RQCMDARG,
+ "Space separated URLs to send the feedback report to.", NULL, NULL,
+ DEFAULT_PROTO "mariadb.org/feedback_plugin/post");
+static MYSQL_SYSVAR_ULONG(send_timeout, send_timeout, PLUGIN_VAR_RQCMDARG,
+ "Timeout (in seconds) for the sending the report.",
+ NULL, NULL, 60, 1, 60*60*24, 1);
+static MYSQL_SYSVAR_ULONG(send_retry_wait, send_retry_wait, PLUGIN_VAR_RQCMDARG,
+ "Wait this many seconds before retrying a failed send.",
+ NULL, NULL, 60, 1, 60*60*24, 1);
+
+static struct st_mysql_sys_var* settings[] = {
+ MYSQL_SYSVAR(server_uid),
+ MYSQL_SYSVAR(user_info),
+ MYSQL_SYSVAR(url),
+ MYSQL_SYSVAR(send_timeout),
+ MYSQL_SYSVAR(send_retry_wait),
+ NULL
+};
+
+
+static struct st_mysql_information_schema feedback =
+{ MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION };
+
+} // namespace feedback
+
+mysql_declare_plugin(feedback)
+{
+ MYSQL_INFORMATION_SCHEMA_PLUGIN,
+ &feedback::feedback,
+ "FEEDBACK",
+ "Sergei Golubchik",
+ "MariaDB User Feedback Plugin",
+ PLUGIN_LICENSE_GPL,
+ feedback::init,
+ feedback::free,
+ 0x0100,
+ NULL,
+ feedback::settings,
+ NULL
+}
+mysql_declare_plugin_end;
+#ifdef MARIA_PLUGIN_INTERFACE_VERSION
+maria_declare_plugin(feedback)
+{
+ MYSQL_INFORMATION_SCHEMA_PLUGIN,
+ &feedback::feedback,
+ "FEEDBACK",
+ "Sergei Golubchik",
+ "MariaDB User Feedback Plugin",
+ PLUGIN_LICENSE_GPL,
+ feedback::init,
+ feedback::free,
+ 0x0100,
+ NULL,
+ feedback::settings,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+}
+maria_declare_plugin_end;
+#endif
diff --git a/plugin/feedback/feedback.h b/plugin/feedback/feedback.h
new file mode 100644
index 00000000000..60ef72eed84
--- /dev/null
+++ b/plugin/feedback/feedback.h
@@ -0,0 +1,67 @@
+/* Copyright (C) 2010 Sergei Golubchik and 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
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#define MYSQL_SERVER
+#include <mysql_priv.h>
+
+namespace feedback {
+
+int fill_feedback(THD *thd, TABLE_LIST *tables, COND *cond);
+int fill_plugin_version(THD *thd, TABLE_LIST *tables);
+int fill_misc_data(THD *thd, TABLE_LIST *tables);
+int fill_linux_info(THD *thd, TABLE_LIST *tables);
+
+static const int SERVER_UID_SIZE= 29;
+extern char server_uid_buf[SERVER_UID_SIZE+1], *user_info;
+int calculate_server_uid(char *);
+int prepare_linux_info();
+
+extern ST_SCHEMA_TABLE *i_s_feedback;
+
+extern ulong send_timeout, send_retry_wait;
+
+pthread_handler_t background_thread(void *arg);
+
+/**
+ The class for storing urls to send report data to.
+
+ Constructors are private, the object should be created with create() method.
+ send() method does the actual sending.
+*/
+class Url {
+ protected:
+ Url(LEX_STRING &url_arg) : full_url(url_arg) {}
+ const LEX_STRING full_url;
+
+ public:
+ virtual ~Url() { my_free(full_url.str, MYF(0)); }
+
+ const char *url() { return full_url.str; }
+ size_t url_length() { return full_url.length; }
+ virtual int send(const char* data, size_t data_length) = 0;
+
+ static Url* create(const char *url, size_t url_length);
+};
+
+extern Url **urls;
+extern uint url_count;
+
+/* these are used to communicate with the background thread */
+extern pthread_mutex_t sleep_mutex;
+extern pthread_cond_t sleep_condition;
+extern volatile bool shutdown_plugin;
+
+} // namespace feedback
+
diff --git a/plugin/feedback/plug.in b/plugin/feedback/plug.in
new file mode 100644
index 00000000000..88a4448321d
--- /dev/null
+++ b/plugin/feedback/plug.in
@@ -0,0 +1,28 @@
+MYSQL_PLUGIN(feedback,[MariaDB User Feedback Plugin],
+ [MariaDB User Feedback Plugin])
+
+dnl Although it's not exactly obvious, top-level CMakeLists.txt parses plug.in
+dnl files, in particular looking for what the library name should be. It uses
+dnl regexp that matches MYSQL_PLUGIN_DYNAMIC or MYSQL_PLUGIN_STATIC, followed
+dnl by an open parenthesys, and the plugin name. Having engine name enclosed in
+dnl square brackets below causes this regexp to fail and as a result feedback
+dnl plugin will not be considered for dynamic builds on Windows.
+dnl Unfortunately, feedback cannot be built dynamically on Windows, because it
+dnl needs to access server internals that aren't designed for plugin use and
+dnl aren't marked with MYSQL_PLUGIN_IMPORT.
+MYSQL_PLUGIN_DYNAMIC([feedback], [feedback.la])
+ifelse(index(AC_PACKAGE_NAME, [MariaDB]), -1, [], [
+
+dnl MariaDB and MySQL define static plugins differently.
+dnl I only support MariaDB here, for now.
+MYSQL_PLUGIN_STATIC(feedback, [libfeedback.la])
+
+])
+
+dnl MariaDB before 5.5 needs this define:
+MYSQL_PLUGIN_DEFINE(feedback, [WITH_FEEDBACK_PLUGIN])
+
+MYSQL_PLUGIN_ACTIONS(feedback, [
+ AC_CHECK_HEADERS([netdb.h sys/utsname.h])
+])
+
diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc
new file mode 100644
index 00000000000..bcfb0348e11
--- /dev/null
+++ b/plugin/feedback/sender_thread.cc
@@ -0,0 +1,301 @@
+/* Copyright (C) 2010 Sergei Golubchik and 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
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "feedback.h"
+#include <time.h>
+
+namespace feedback {
+
+static THD *thd= 0; ///< background thread thd
+static my_thread_id thd_thread_id; ///< its thread_id
+
+static size_t needed_size= 20480;
+
+static const time_t startup_interval= 60*5; ///< in seconds (5 minutes)
+static const time_t first_interval= 60*60*24; ///< in seconds (one day)
+static const time_t interval= 60*60*24*7; ///< in seconds (one week)
+
+/**
+ reads the rows from a table and puts them, concatenated, in a String
+
+ @note
+ 1. only supports two column tables - no less, no more.
+ 2. it emulates mysql -e "select * from..." and thus it separates
+ columns with \t and starts the output with column names.
+*/
+static int table_to_string(TABLE *table, String *result)
+{
+ bool res;
+ char buff1[MAX_FIELD_WIDTH], buff2[MAX_FIELD_WIDTH];
+ String str1(buff1, sizeof(buff1), system_charset_info);
+ String str2(buff2, sizeof(buff2), system_charset_info);
+
+ res= table->file->ha_rnd_init(1);
+
+ dbug_tmp_use_all_columns(table, table->read_set);
+
+ while(!res && !table->file->ha_rnd_next(table->record[0]))
+ {
+ table->field[0]->val_str(&str1);
+ table->field[1]->val_str(&str2);
+ if (result->reserve(str1.length() + str2.length() + 3))
+ res= 1;
+ else
+ {
+ result->qs_append(str1.ptr(), str1.length());
+ result->qs_append('\t');
+ result->qs_append(str2.ptr(), str2.length());
+ result->qs_append('\n');
+ }
+ }
+
+ res = res || result->append('\n');
+
+ /*
+ Note, "|=" and not "||" - because we want to call ha_rnd_end()
+ even if res is already 1.
+ */
+ res |= table->file->ha_rnd_end();
+
+ return res;
+}
+
+/**
+ Initialize the THD and TABLE_LIST
+
+ The structures must be sufficiently initialized for create_tmp_table()
+ and fill_feedback() to work.
+*/
+static int prepare_for_fill(TABLE_LIST *tables)
+{
+ /*
+ Add our thd to the list, for it to be visible in SHOW PROCESSLIST.
+ But don't generate thread_id every time - use the saved value
+ (every increment of global thread_id counts as a new connection
+ in SHOW STATUS and we want to avoid skewing the statistics)
+ */
+ thd->thread_id= thd->variables.pseudo_thread_id= thd_thread_id;
+ pthread_mutex_lock(&LOCK_thread_count);
+ thread_count++;
+ threads.append(thd);
+ pthread_mutex_unlock(&LOCK_thread_count);
+ thd->thread_stack= (char*) &tables;
+ if (thd->store_globals())
+ return 1;
+
+ thd->mysys_var->current_cond= &sleep_condition;
+ thd->mysys_var->current_mutex= &sleep_mutex;
+ thd->proc_info="feedback";
+ thd->command=COM_SLEEP;
+ thd->version=refresh_version;
+ thd->system_thread= SYSTEM_THREAD_EVENT_WORKER; // whatever
+ thd->set_time();
+ thd->init_for_queries();
+ thd->real_id= pthread_self();
+ thd->db= NULL;
+ thd->db_length= 0;
+ thd->security_ctx->host_or_ip= "";
+ thd->security_ctx->db_access= DB_ACLS;
+ thd->security_ctx->master_access= ~NO_ACCESS;
+ bzero((char*) &thd->net, sizeof(thd->net));
+ lex_start(thd);
+ mysql_init_select(thd->lex);
+
+ tables->init_one_table(INFORMATION_SCHEMA_NAME.str,
+ i_s_feedback->table_name, TL_READ);
+ tables->schema_table= i_s_feedback;
+ tables->table= i_s_feedback->create_table(thd, tables);
+ if (!tables->table)
+ return 1;
+
+ tables->table->pos_in_table_list= tables;
+
+ return 0;
+}
+
+/**
+ Try to detect if this thread is going down
+
+ which can happen for different reasons:
+ * plugin is being unloaded
+ * mysqld server is being shut down
+ * the thread is being killed
+
+*/
+static bool going_down()
+{
+ return shutdown_plugin || shutdown_in_progress || (thd && thd->killed);
+}
+
+/**
+ just like sleep, but waits on a condition and checks "plugin shutdown" status
+*/
+static int slept_ok(time_t sec)
+{
+ struct timespec abstime;
+ int ret= 0;
+
+ set_timespec(abstime, sec);
+
+ pthread_mutex_lock(&sleep_mutex);
+ while (!going_down() && ret != ETIMEDOUT)
+ ret= pthread_cond_timedwait(&sleep_condition, &sleep_mutex, &abstime);
+ pthread_mutex_unlock(&sleep_mutex);
+
+ return !going_down();
+}
+
+/**
+ create a feedback report and send it to all specified urls
+
+ If "when" argument is not null, only it and the server uid are sent.
+ Otherwise a full report is generated.
+*/
+static void send_report(const char *when)
+{
+ TABLE_LIST tables;
+ String str;
+ int i, last_todo;
+ Url **todo= (Url**)alloca(url_count*sizeof(Url*));
+
+ str.alloc(needed_size); // preallocate it to avoid many small mallocs
+
+ /*
+ on startup and shutdown the server may not be completely
+ initialized, and full report won't work.
+ We send a short status notice only.
+ */
+ if (when)
+ {
+ str.length(0);
+ str.append(STRING_WITH_LEN("FEEDBACK_SERVER_UID"));
+ str.append('\t');
+ str.append(server_uid_buf);
+ str.append('\n');
+ str.append(STRING_WITH_LEN("FEEDBACK_WHEN"));
+ str.append('\t');
+ str.append(when);
+ str.append('\n');
+ str.append(STRING_WITH_LEN("FEEDBACK_USER_INFO"));
+ str.append('\t');
+ str.append(user_info);
+ str.append('\n');
+ str.append('\n');
+ }
+ else
+ {
+ /*
+ otherwise, prepare the THD and TABLE_LIST,
+ create and fill the temporary table with data just like
+ SELECT * FROM IFROEMATION_SCHEMA.feedback is doing,
+ read and concatenate table data into a String.
+ */
+ if (!(thd= new THD()))
+ return;
+
+ if (prepare_for_fill(&tables))
+ goto ret;
+
+ if (fill_feedback(thd, &tables, NULL))
+ goto ret;
+
+ if (table_to_string(tables.table, &str))
+ goto ret;
+
+ needed_size= (size_t)(str.length() * 1.1);
+
+ free_tmp_table(thd, tables.table);
+ tables.table= 0;
+ }
+
+ /*
+ Try to send the report on every url from the list, remove url on success,
+ keep failed in the list. Repeat until the list is empty.
+ */
+ memcpy(todo, urls, url_count*sizeof(Url*));
+ last_todo= url_count - 1;
+ do
+ {
+ for (i= 0; i <= last_todo;)
+ {
+ Url *url= todo[i];
+
+ if (thd) // for nicer SHOW PROCESSLIST
+ thd->set_query(const_cast<char*>(url->url()), url->url_length());
+
+ if (url->send(str.ptr(), str.length()))
+ i++;
+ else
+ todo[i]= todo[last_todo--];
+ }
+ if (last_todo < 0)
+ break;
+ } while (slept_ok(send_retry_wait)); // wait a little bit before retrying
+
+ret:
+ if (thd)
+ {
+ if (tables.table)
+ free_tmp_table(thd, tables.table);
+ /*
+ clean up, free the thd.
+ reset all thread local status variables to minimize
+ the effect of the background thread on SHOW STATUS.
+ */
+ pthread_mutex_lock(&LOCK_thread_count);
+ bzero(&thd->status_var, sizeof(thd->status_var));
+ thread_count--;
+ thd->killed= KILL_CONNECTION;
+ pthread_cond_broadcast(&COND_thread_count);
+ pthread_mutex_unlock(&LOCK_thread_count);
+ delete thd;
+ thd= 0;
+ }
+}
+
+/**
+ background sending thread
+*/
+pthread_handler_t background_thread(void *arg __attribute__((unused)))
+{
+ if (my_thread_init())
+ return 0;
+
+ pthread_mutex_lock(&LOCK_thread_count);
+ thd_thread_id= thread_id++;
+ pthread_mutex_unlock(&LOCK_thread_count);
+
+ if (slept_ok(startup_interval))
+ {
+ send_report("startup");
+
+ if (slept_ok(first_interval))
+ {
+ send_report(NULL);
+
+ while(slept_ok(interval))
+ send_report(NULL);
+ }
+
+ send_report("shutdown");
+ }
+
+ my_thread_end();
+ pthread_exit(0);
+ return 0;
+}
+
+} // namespace feedback
+
diff --git a/plugin/feedback/url_base.cc b/plugin/feedback/url_base.cc
new file mode 100644
index 00000000000..38b2ca86e9f
--- /dev/null
+++ b/plugin/feedback/url_base.cc
@@ -0,0 +1,51 @@
+/* Copyright (C) 2010 Sergei Golubchik and 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
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "feedback.h"
+
+namespace feedback {
+
+Url* http_create(const char *url, size_t url_length);
+
+/**
+ creates an Url object out of an url, if possible.
+
+ This is done by invoking corresponding creator functions
+ of the derived classes, until the first not NULL result.
+*/
+Url* Url::create(const char *url, size_t url_length)
+{
+ url= my_strndup(url, url_length, MYF(MY_WME));
+
+ if (!url)
+ return NULL;
+
+ Url *self= http_create(url, url_length);
+
+ /*
+ here we can add
+
+ if (!self) self= smtp_create(url, url_length);
+ if (!self) self= tftp_create(url, url_length);
+ etc
+ */
+
+ if (!self)
+ my_free(const_cast<char*>(url), MYF(0));
+
+ return self;
+}
+
+} // namespace feedback
diff --git a/plugin/feedback/url_http.cc b/plugin/feedback/url_http.cc
new file mode 100644
index 00000000000..e1f60d60de7
--- /dev/null
+++ b/plugin/feedback/url_http.cc
@@ -0,0 +1,303 @@
+/* Copyright (C) 2010 Sergei Golubchik and 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
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "feedback.h"
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+#ifdef _WIN32
+#undef VOID
+#define VOID void
+#include <ws2tcpip.h>
+#define addrinfo ADDRINFOA
+#endif
+
+namespace feedback {
+
+static const uint FOR_READING= 0;
+static const uint FOR_WRITING= 1;
+
+#ifdef MARIADB_BASE_VERSION
+#define ssl_connect(A,B,C,D) sslconnect(A,B,C,D)
+#else
+#define ssl_connect(A,B,C,D) sslconnect(A,B,C)
+#endif
+
+/**
+ implementation of the Url class that sends the data via HTTP POST request.
+
+ Both http:// and https:// protocols are supported.
+*/
+class Url_http: public Url {
+ protected:
+ const LEX_STRING host, port, path;
+ bool ssl;
+
+ Url_http(LEX_STRING &url_arg, LEX_STRING &host_arg,
+ LEX_STRING &port_arg, LEX_STRING &path_arg, bool ssl_arg) :
+ Url(url_arg), host(host_arg), port(port_arg), path(path_arg), ssl(ssl_arg)
+ {}
+ ~Url_http()
+ {
+ my_free(host.str, MYF(0));
+ my_free(port.str, MYF(0));
+ my_free(path.str, MYF(0));
+ }
+
+ public:
+ int send(const char* data, size_t data_length);
+
+ friend Url* http_create(const char *url, size_t url_length);
+};
+
+/**
+ create a Url_http object out of the url, if possible.
+
+ @note
+ Arbitrary limitations here.
+
+ The url must be http[s]://hostname[:port]/path
+ No username:password@ or ?script=parameters are supported.
+
+ But it's ok. This is not a generic purpose www browser - it only needs to be
+ good enough to POST the data to mariadb.org.
+*/
+Url* http_create(const char *url, size_t url_length)
+{
+ const char *s;
+ LEX_STRING full_url= {const_cast<char*>(url), url_length};
+ LEX_STRING host, port, path;
+ bool ssl= false;
+
+ if (is_prefix(url, "http://"))
+ s= url + 7;
+#ifdef HAVE_OPENSSL
+ else if (is_prefix(url, "https://"))
+ {
+ ssl= true;
+ s= url + 8;
+ }
+#endif
+ else
+ return NULL;
+
+ for (url= s; *s && *s != ':' && *s != '/'; s++) /* no-op */;
+ host.str= const_cast<char*>(url);
+ host.length= s-url;
+
+ if (*s == ':')
+ {
+ for (url= ++s; *s && *s >= '0' && *s <= '9'; s++) /* no-op */;
+ port.str= const_cast<char*>(url);
+ port.length= s-url;
+ }
+ else
+ {
+ if (ssl)
+ {
+ port.str= const_cast<char*>("443");
+ port.length=3;
+ }
+ else
+ {
+ port.str= const_cast<char*>("80");
+ port.length=2;
+ }
+ }
+
+ if (*s == 0)
+ {
+ path.str= const_cast<char*>("/");
+ path.length= 1;
+ }
+ else
+ {
+ path.str= const_cast<char*>(s);
+ path.length= strlen(s);
+ }
+ if (!host.length || !port.length || path.str[0] != '/')
+ return NULL;
+
+ host.str= my_strndup(host.str, host.length, MYF(MY_WME));
+ port.str= my_strndup(port.str, port.length, MYF(MY_WME));
+ path.str= my_strndup(path.str, path.length, MYF(MY_WME));
+
+ if (!host.str || !port.str || !path.str)
+ {
+ my_free(host.str, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(port.str, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(path.str, MYF(MY_ALLOW_ZERO_PTR));
+ return NULL;
+ }
+
+ return new Url_http(full_url, host, port, path, ssl);
+}
+
+/* do the vio_write and check that all data were sent ok */
+#define write_check(VIO, DATA, LEN) \
+ (vio_write((VIO), (uchar*)(DATA), (LEN)) != (LEN))
+
+int Url_http::send(const char* data, size_t data_length)
+{
+ my_socket fd= INVALID_SOCKET;
+ char buf[1024];
+ uint len;
+
+ addrinfo *addrs, *addr, filter= {0, AF_UNSPEC, SOCK_STREAM, 6, 0, 0, 0, 0};
+ int res= getaddrinfo(host.str, port.str, &filter, &addrs);
+
+ if (res)
+ {
+ sql_print_error("feedback plugin: getaddrinfo() failed for url '%s': %s",
+ full_url.str, gai_strerror(res));
+ return 1;
+ }
+
+ for (addr= addrs; addr != NULL; addr= addr->ai_next)
+ {
+ fd= socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
+ if (fd == INVALID_SOCKET)
+ continue;
+
+ if (connect(fd, addr->ai_addr, addr->ai_addrlen) == 0)
+ break;
+
+ closesocket(fd);
+ }
+
+ freeaddrinfo(addrs);
+
+ if (fd == INVALID_SOCKET)
+ {
+ sql_print_error("feedback plugin: could not connect for url '%s'",
+ full_url.str);
+ return 1;
+ }
+
+ Vio *vio= vio_new(fd, VIO_TYPE_TCPIP, 0);
+ if (!vio)
+ {
+ sql_print_error("feedback plugin: vio_new failed for url '%s'",
+ full_url.str);
+ closesocket(fd);
+ return 1;
+ }
+
+#ifdef HAVE_OPENSSL
+ struct st_VioSSLFd *UNINIT_VAR(ssl_fd);
+ if (ssl)
+ {
+ buf[0]= 0;
+ if (!(ssl_fd= new_VioSSLConnectorFd(0, 0, 0, 0, 0)) ||
+ ssl_connect(ssl_fd, vio, send_timeout, buf))
+ {
+ sql_print_error("feedback plugin: ssl failed for url '%s' %s",
+ full_url.str, buf);
+ if (ssl_fd)
+ free_vio_ssl_acceptor_fd(ssl_fd);
+ closesocket(fd);
+ vio_delete(vio);
+ return 1;
+ }
+ }
+#endif
+
+ static const LEX_STRING boundary=
+ { C_STRING_WITH_LEN("----------------------------ba4f3696b39f") };
+ static const LEX_STRING header=
+ { C_STRING_WITH_LEN("\r\n"
+ "Content-Disposition: form-data; name=\"data\"; filename=\"-\"\r\n"
+ "Content-Type: application/octet-stream\r\n\r\n")
+ };
+
+ len= my_snprintf(buf, sizeof(buf),
+ "POST %s HTTP/1.0\r\n"
+ "User-Agent: MariaDB User Feedback Plugin\r\n"
+ "Host: %s:%s\r\n"
+ "Accept: */*\r\n"
+ "Content-Length: %u\r\n"
+ "Content-Type: multipart/form-data; boundary=%s\r\n"
+ "\r\n",
+ path.str, host.str, port.str,
+ (uint)(2*boundary.length + header.length + data_length + 4),
+ boundary.str + 2);
+
+ vio_timeout(vio, FOR_READING, send_timeout);
+ vio_timeout(vio, FOR_WRITING, send_timeout);
+ res = write_check(vio, buf, len)
+ || write_check(vio, boundary.str, boundary.length)
+ || write_check(vio, header.str, header.length)
+ || write_check(vio, data, data_length)
+ || write_check(vio, boundary.str, boundary.length)
+ || write_check(vio, "--\r\n", 4);
+
+ if (res)
+ sql_print_error("feedback plugin: failed to send report to '%s'",
+ full_url.str);
+ else
+ {
+ sql_print_information("feedback plugin: report to '%s' was sent",
+ full_url.str);
+
+ /*
+ if the data were send successfully, read the reply.
+ Extract the first string between <h1>...</h1> tags
+ and put it as a server reply into the error log.
+ */
+ len= vio_read(vio, (uchar*)buf, sizeof(buf)-1);
+ if (len && len < sizeof(buf))
+ {
+ char *from;
+
+ buf[len+1]= 0; // safety
+
+ if ((from= strstr(buf, "<h1>")))
+ {
+ from+= 4;
+ char *to= strstr(from, "</h1>");
+ if (to)
+ *to= 0;
+ else
+ from= NULL;
+ }
+ if (from)
+ sql_print_information("feedback plugin: server replied '%s'", from);
+ else
+ sql_print_warning("feedback plugin: failed to parse server reply");
+ }
+ else
+ {
+ res= 1;
+ sql_print_error("feedback plugin: failed to read server reply");
+ }
+ }
+
+ vio_delete(vio);
+
+#ifdef HAVE_OPENSSL
+ if (ssl)
+ {
+ SSL_CTX_free(ssl_fd->ssl_context);
+ my_free(ssl_fd, MYF(0));
+ }
+#endif
+
+ return res;
+}
+
+} // namespace feedback
+
diff --git a/plugin/feedback/utils.cc b/plugin/feedback/utils.cc
new file mode 100644
index 00000000000..f32b527c052
--- /dev/null
+++ b/plugin/feedback/utils.cc
@@ -0,0 +1,392 @@
+/* Copyright (C) 2010 Sergei Golubchik and 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
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#include "feedback.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <base64.h>
+#include <sha1.h>
+
+#if defined (_WIN32)
+#define HAVE_SYS_UTSNAME_H
+
+#ifndef VER_SUITE_WH_SERVER
+#define VER_SUITE_WH_SERVER 0x00008000
+#endif
+
+struct utsname {
+ char sysname[16]; // Name of this implementation of the operating system.
+ char nodename[16]; // Name of this node within the communications
+ // network to which this node is attached, if any.
+ char release[16]; // Current release level of this implementation.
+ char version[256]; // Current version level of this release.
+ char machine[16]; // Name of the hardware type on which the system is running.
+};
+
+/* Get commonly used name for Windows version */
+static const char *get_os_version_name(OSVERSIONINFOEX *ver)
+{
+ DWORD major = ver->dwMajorVersion;
+ DWORD minor = ver->dwMinorVersion;
+
+ if (major == 6 && minor == 1)
+ {
+ return (ver->wProductType == VER_NT_WORKSTATION)?
+ "Windows 7":"Windows Server 2008 R2";
+ }
+ if (major == 6 && minor == 0)
+ {
+ return (ver->wProductType == VER_NT_WORKSTATION)?
+ "Windows Vista":"Windows Server 2008";
+ }
+ if (major == 5 && minor == 2)
+ {
+ if (GetSystemMetrics(SM_SERVERR2) != 0)
+ return "Windows Server 2003 R2";
+ if (ver->wSuiteMask & VER_SUITE_WH_SERVER)
+ return "Windows Home Server";
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ if (ver->wProductType == VER_NT_WORKSTATION &&
+ sysinfo.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
+ return "Windows XP Professional x64 Edition";
+
+ return "Windows Server 2003";
+ }
+ if (major == 5 && minor == 1)
+ return "Windows XP";
+ if (major == 5 && minor == 0)
+ return "Windows 2000";
+
+ return "";
+}
+
+
+static int uname(struct utsname *buf)
+{
+ OSVERSIONINFOEX ver;
+ ver.dwOSVersionInfoSize = (DWORD)sizeof(ver);
+ if (!GetVersionEx((OSVERSIONINFO *)&ver))
+ return -1;
+
+ buf->nodename[0]= 0;
+ strcpy(buf->sysname, "Windows");
+ sprintf(buf->release, "%d.%d", ver.dwMajorVersion, ver.dwMinorVersion);
+
+ const char *version_str= get_os_version_name(&ver);
+ if(version_str && version_str[0])
+ sprintf(buf->version, "%s %s",version_str, ver.szCSDVersion);
+ else
+ sprintf(buf->version, "%s", ver.szCSDVersion);
+
+#ifdef _WIN64
+ strcpy(buf->machine, "x64");
+#else
+ BOOL isX64;
+ if (IsWow64Process(GetCurrentProcess(), &isX64) && isX64)
+ strcpy(buf->machine, "x64");
+ else
+ strcpy(buf->machine,"x86");
+#endif
+ return 0;
+}
+
+#elif defined(HAVE_SYS_UTSNAME_H)
+#include <sys/utsname.h>
+#endif
+
+#ifdef HAVE_SYS_UTSNAME_H
+static bool have_ubuf= false;
+static struct utsname ubuf;
+#endif
+
+#ifdef TARGET_OS_LINUX
+#include <glob.h>
+static bool have_distribution= false;
+static char distribution[256];
+
+static const char *masks[]= {
+ "/etc/*-version", "/etc/*-release",
+ "/etc/*_version", "/etc/*_release"
+};
+#endif
+
+bool schema_table_store_record(THD *thd, TABLE *table);
+
+namespace feedback {
+
+/*
+ convenience macros for inserting rows into I_S table.
+*/
+#define INSERT2(NAME,LEN,VALUE) \
+ do { \
+ table->field[0]->store(NAME, LEN, system_charset_info); \
+ table->field[1]->store VALUE; \
+ if (schema_table_store_record(thd, table)) \
+ return 1; \
+ } while (0)
+
+#define INSERT1(NAME,VALUE) \
+ do { \
+ table->field[0]->store(NAME, sizeof(NAME)-1, system_charset_info); \
+ table->field[1]->store VALUE; \
+ if (schema_table_store_record(thd, table)) \
+ return 1; \
+ } while (0)
+
+static const bool UNSIGNED= true; ///< used below when inserting integers
+
+/**
+ callback for fill_plugin_version() - insert a plugin name and its version
+*/
+static my_bool show_plugins(THD *thd, plugin_ref plugin, void *arg)
+{
+ TABLE *table= (TABLE*) arg;
+ char version[20];
+ size_t version_len;
+
+ version_len= my_snprintf(version, sizeof(version), "%d.%d",
+ (plugin_decl(plugin)->version) >> 8,
+ (plugin_decl(plugin)->version) & 0xff);
+
+ INSERT2(plugin_name(plugin)->str, plugin_name(plugin)->length,
+ (version, version_len, system_charset_info));
+
+ return 0;
+}
+
+/**
+ inserts all plugins and their versions into I_S.FEEDBACK
+*/
+int fill_plugin_version(THD *thd, TABLE_LIST *tables)
+{
+ return plugin_foreach_with_mask(thd, show_plugins, MYSQL_ANY_PLUGIN,
+ ~PLUGIN_IS_FREED, tables->table);
+}
+
+#if defined(_SC_PAGE_SIZE) && !defined(_SC_PAGESIZE)
+#define _SC_PAGESIZE _SC_PAGE_SIZE
+#endif
+
+/**
+ return the amount of physical memory
+*/
+static ulonglong my_getphysmem()
+{
+ ulonglong pages= 0;
+#ifdef _SC_PHYS_PAGES
+ pages= sysconf(_SC_PHYS_PAGES);
+#else
+ return 0;
+#endif
+
+#ifdef _SC_PAGESIZE
+ return pages * sysconf(_SC_PAGESIZE);
+#endif
+#ifdef _WIN32
+ MEMORYSTATUSEX memstatus;
+ memstatus.dwLength= sizeof(memstatus);
+ GlobalMemoryStatusEx(&memstatus);
+ return memstatus.ullTotalPhys;
+#else
+ return pages * my_getpagesize();
+#endif
+}
+
+/* get the number of (online) CPUs */
+int my_getncpus()
+{
+#ifdef _SC_NPROCESSORS_ONLN
+ return sysconf(_SC_NPROCESSORS_ONLN);
+#elif defined(__WIN__)
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ return sysinfo.dwNumberOfProcessors;
+#else
+ return 0;
+#endif
+}
+
+/**
+ Find the version of the kernel and the linux distribution
+*/
+int prepare_linux_info()
+{
+#ifdef HAVE_SYS_UTSNAME_H
+ have_ubuf= (uname(&ubuf) != -1);
+#endif
+
+#ifdef TARGET_OS_LINUX
+ /*
+ let's try to find what linux distribution it is
+ we read *[-_]{release,version} file in /etc.
+
+ Either it will be /etc/lsb-release, such as
+
+ ==> /etc/lsb-release <==
+ DISTRIB_ID=Ubuntu
+ DISTRIB_RELEASE=8.04
+ DISTRIB_CODENAME=hardy
+ DISTRIB_DESCRIPTION="Ubuntu 8.04.4 LTS"
+
+ Or a one-liner with the description (/etc/SuSE-release has more
+ than one line, but the description is the first, so it can be
+ treated as a one-liner).
+
+ We'll read lsb-release first, and if it's not found will search
+ for other files (*-version *-release *_version *_release)
+*/
+ int fd;
+ have_distribution= false;
+ if ((fd= my_open("/etc/lsb-release", O_RDONLY, MYF(0))) != -1)
+ {
+ /* Cool, LSB-compliant distribution! */
+ size_t len= my_read(fd, (uchar*)distribution, sizeof(distribution)-1, MYF(0));
+ my_close(fd, MYF(0));
+ if (len != (size_t)-1)
+ {
+ distribution[len]= 0; // safety
+ char *found= strstr(distribution, "DISTRIB_DESCRIPTION=");
+ if (found)
+ {
+ have_distribution= true;
+ char *end= strstr(found, "\n");
+ if (end == NULL)
+ end= distribution + len;
+ found+= 20;
+
+ if (*found == '"' && end[-1] == '"')
+ {
+ found++;
+ end--;
+ }
+ *end= 0;
+
+ char *to= strmov(distribution, "lsb: ");
+ memmove(to, found, end - found + 1);
+ }
+ }
+ }
+
+ /* if not an LSB-compliant distribution */
+ for (uint i= 0; !have_distribution && i < array_elements(masks); i++)
+ {
+ glob_t found;
+ if (glob(masks[i], GLOB_NOSORT, NULL, &found) == 0)
+ {
+ int fd;
+ if ((fd= my_open(found.gl_pathv[0], O_RDONLY, MYF(0))) != -1)
+ {
+ /*
+ +5 and -8 below cut the file name part out of the
+ full pathname that corresponds to the mask as above.
+ */
+ char *to= strmov(distribution, found.gl_pathv[0] + 5) - 8;
+ *to++= ':';
+ *to++= ' ';
+
+ size_t to_len= distribution + sizeof(distribution) - 1 - to;
+ size_t len= my_read(fd, (uchar*)to, to_len, MYF(0));
+ my_close(fd, MYF(0));
+ if (len != (size_t)-1)
+ {
+ to[len]= 0; // safety
+ char *end= strstr(to, "\n");
+ if (end)
+ *end= 0;
+ have_distribution= true;
+ }
+ }
+ }
+ globfree(&found);
+ }
+#endif
+ return 0;
+}
+
+/**
+ Add the linux distribution and the kernel version
+*/
+int fill_linux_info(THD *thd, TABLE_LIST *tables)
+{
+ TABLE *table= tables->table;
+ CHARSET_INFO *cs= system_charset_info;
+
+#ifdef HAVE_SYS_UTSNAME_H
+ if (have_ubuf)
+ {
+ INSERT1("Uname_sysname", (ubuf.sysname, strlen(ubuf.sysname), cs));
+ INSERT1("Uname_release", (ubuf.release, strlen(ubuf.release), cs));
+ INSERT1("Uname_version", (ubuf.version, strlen(ubuf.version), cs));
+ INSERT1("Uname_machine", (ubuf.machine, strlen(ubuf.machine), cs));
+ }
+#endif
+
+#ifdef TARGET_OS_LINUX
+ if (have_distribution)
+ INSERT1("Uname_distribution", (distribution, strlen(distribution), cs));
+#endif
+
+ return 0;
+}
+
+/**
+ Adds varios bits of information to the I_S.FEEDBACK
+*/
+int fill_misc_data(THD *thd, TABLE_LIST *tables)
+{
+ TABLE *table= tables->table;
+
+#ifdef MY_ATOMIC_OK
+ INSERT1("Cpu_count", (my_getncpus(), UNSIGNED));
+#endif
+ INSERT1("Mem_total", (my_getphysmem(), UNSIGNED));
+
+ return 0;
+}
+
+/**
+ calculates the server unique identifier
+
+ UID is a base64 encoded SHA1 hash of the MAC address of one of
+ the interfaces, and the tcp port that the server is listening on
+*/
+int calculate_server_uid(char *dest)
+{
+ uchar rawbuf[2 + 6];
+ uchar shabuf[SHA1_HASH_SIZE];
+ SHA1_CONTEXT ctx;
+
+ int2store(rawbuf, mysqld_port);
+ if (my_gethwaddr(rawbuf + 2))
+ {
+ sql_print_error("feedback plugin: failed to retrieve the MAC address");
+ return 1;
+ }
+
+ mysql_sha1_reset(&ctx);
+ mysql_sha1_input(&ctx, rawbuf, sizeof(rawbuf));
+ mysql_sha1_result(&ctx, shabuf);
+
+ assert(base64_needed_encoded_length(sizeof(shabuf)) <= SERVER_UID_SIZE);
+ base64_encode(shabuf, sizeof(shabuf), dest);
+
+ return 0;
+}
+
+} // namespace feedback
diff --git a/plugin/fulltext/CMakeLists.txt b/plugin/fulltext/CMakeLists.txt
new file mode 100644
index 00000000000..cf696c19e61
--- /dev/null
+++ b/plugin/fulltext/CMakeLists.txt
@@ -0,0 +1,3 @@
+INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
+SET(FTEXAMPLE_SOURCES plugin_example.c)
+MYSQL_PLUGIN(FTEXAMPLE)
diff --git a/plugin/handler_socket/handlersocket/Makefile.am b/plugin/handler_socket/handlersocket/Makefile.am
index 4d75d9739b1..7e47209bcf4 100644
--- a/plugin/handler_socket/handlersocket/Makefile.am
+++ b/plugin/handler_socket/handlersocket/Makefile.am
@@ -2,7 +2,7 @@ pkgplugindir = $(PLUGIN_DIR)
CXXFLAGS += -fimplicit-templates
noinst_HEADERS = database.hpp hstcpsvr.hpp hstcpsvr_worker.hpp mysql_incl.hpp
pkgplugin_LTLIBRARIES = handlersocket.la
-handlersocket_la_LDFLAGS = -module ../libhsclient/libhsclient.la
+handlersocket_la_LDFLAGS = -module ../libhsclient/libhsclient.la -L$(top_builddir)/libservices -lmysqlservices
handlersocket_la_CXXFLAGS = $(MYSQL_INC) $(MYSQL_CFLAGS) $(AM_CXXFLAGS) -I$(srcdir)/../libhsclient
handlersocket_la_SOURCES = database.cpp handlersocket.cpp \
hstcpsvr_worker.cpp hstcpsvr.cpp
diff --git a/plugin/handler_socket/handlersocket/database.cpp b/plugin/handler_socket/handlersocket/database.cpp
index f63f011d9b1..311eec55fa8 100644
--- a/plugin/handler_socket/handlersocket/database.cpp
+++ b/plugin/handler_socket/handlersocket/database.cpp
@@ -246,11 +246,11 @@ wait_server_to_start(THD *thd, volatile int& shutdown_flag)
&abstime);
pthread_mutex_unlock(&LOCK_server_started);
pthread_mutex_lock(&thd->mysys_var->mutex);
- THD::killed_state st = thd->killed;
+ killed_state st = thd->killed;
pthread_mutex_unlock(&thd->mysys_var->mutex);
DBG_SHUT(fprintf(stderr, "HNDSOCK wsts kst %d\n", (int)st));
pthread_mutex_lock(&LOCK_server_started);
- if (st != THD::NOT_KILLED) {
+ if (st != NOT_KILLED) {
DBG_SHUT(fprintf(stderr, "HNDSOCK wsts kst %d break\n", (int)st));
r = -1;
break;
@@ -357,11 +357,11 @@ bool
dbcontext::check_alive()
{
pthread_mutex_lock(&thd->mysys_var->mutex);
- THD::killed_state st = thd->killed;
+ killed_state st = thd->killed;
pthread_mutex_unlock(&thd->mysys_var->mutex);
DBG_SHUT(fprintf(stderr, "chk HNDSOCK kst %p %p %d %zu\n", thd, &thd->killed,
(int)st, sizeof(*thd)));
- if (st != THD::NOT_KILLED) {
+ if (st != NOT_KILLED) {
DBG_SHUT(fprintf(stderr, "chk HNDSOCK kst %d break\n", (int)st));
return false;
}
diff --git a/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp b/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp
index fa42f2b0914..85887d1d55c 100644
--- a/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp
+++ b/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp
@@ -63,7 +63,7 @@ struct hstcpsvr_conn : public dbcallback_i {
public:
auto_file fd;
sockaddr_storage addr;
- socklen_t addr_len;
+ size_socket addr_len;
dbconnstate cstate;
std::string err;
size_t readsize;
diff --git a/plugin/handler_socket/libhsclient/auto_addrinfo.hpp b/plugin/handler_socket/libhsclient/auto_addrinfo.hpp
index c3ab64e8127..f0c07060be1 100644
--- a/plugin/handler_socket/libhsclient/auto_addrinfo.hpp
+++ b/plugin/handler_socket/libhsclient/auto_addrinfo.hpp
@@ -9,12 +9,15 @@
#ifndef DENA_AUTO_ADDRINFO_HPP
#define DENA_AUTO_ADDRINFO_HPP
+#include <my_config.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include "util.hpp"
+typedef SOCKET_SIZE_TYPE size_socket;
+
namespace dena {
struct auto_addrinfo : private noncopyable {
diff --git a/plugin/handler_socket/libhsclient/socket.cpp b/plugin/handler_socket/libhsclient/socket.cpp
index 5d84a7c4adf..0c4816589fa 100644
--- a/plugin/handler_socket/libhsclient/socket.cpp
+++ b/plugin/handler_socket/libhsclient/socket.cpp
@@ -172,7 +172,7 @@ socket_bind(auto_file& fd, const socket_args& args, std::string& err_r)
int
socket_accept(int listen_fd, auto_file& fd, const socket_args& args,
- sockaddr_storage& addr_r, socklen_t& addrlen_r, std::string& err_r)
+ sockaddr_storage& addr_r, size_socket& addrlen_r, std::string& err_r)
{
fd.reset(accept(listen_fd, reinterpret_cast<sockaddr *>(&addr_r),
&addrlen_r));
diff --git a/plugin/handler_socket/libhsclient/socket.hpp b/plugin/handler_socket/libhsclient/socket.hpp
index 3da6020e843..c6e638c9c01 100644
--- a/plugin/handler_socket/libhsclient/socket.hpp
+++ b/plugin/handler_socket/libhsclient/socket.hpp
@@ -19,7 +19,7 @@ namespace dena {
struct socket_args {
sockaddr_storage addr;
- socklen_t addrlen;
+ size_socket addrlen;
int family;
int socktype;
int protocol;
@@ -43,7 +43,7 @@ void ignore_sigpipe();
int socket_bind(auto_file& fd, const socket_args& args, std::string& err_r);
int socket_connect(auto_file& fd, const socket_args& args, std::string& err_r);
int socket_accept(int listen_fd, auto_file& fd, const socket_args& args,
- sockaddr_storage& addr_r, socklen_t& addrlen_r, std::string& err_r);
+ sockaddr_storage& addr_r, size_socket& addrlen_r, std::string& err_r);
};
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.xs b/plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.xs
index 39f11e2780e..8e8d2520337 100644
--- a/plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.xs
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/HandlerSocket.xs
@@ -12,6 +12,11 @@
#include "ppport.h"
+/*
+ below we'll include (indirectly) my_global.h, which defines
+ VERSION too. Undefine our VERSION here.
+*/
+#undef VERSION
#include "hstcpcli.hpp"
#define DBG(x)
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL b/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.in
index 50c329db4b6..1a9b1444fb8 100644
--- a/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.in
@@ -11,8 +11,8 @@ WriteMakefile(
AUTHOR => 'higuchi dot akira at dena dot jp>') : ()),
CC => 'g++ -fPIC',
LD => 'g++ -fPIC',
- LIBS => ['-L../libhsclient -L../libhsclient/.libs -lhsclient'],
+ LIBS => ['-L@builddir@/../libhsclient -L@builddir@/../libhsclient/.libs -lhsclient'],
DEFINE => '',
- INC => '-I. -I../libhsclient',
+ INC => '-I. -I../libhsclient -I@builddir@/../libhsclient -I@top_builddir@/include',
OPTIMIZE => '-g -O3 -Wall -Wno-unused',
);
diff --git a/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.installed b/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.installed
index 1b7649498d2..0d01bceb819 100644
--- a/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.installed
+++ b/plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL.installed
@@ -13,7 +13,7 @@ WriteMakefile(
LD => 'g++ -fPIC',
LIBS => ['-lhsclient'], # e.g., '-lm'
DEFINE => '', # e.g., '-DHAVE_SOMETHING'
- INC => '-I. -I/usr/include/handlersocket',
+ INC => '-I. -I/usr/include/handlersocket -I/usr/include/mysql',
OPTIMIZE => '-g -O3 -Wall -Wno-unused',
# Un-comment this if you add C files to link with later:
# OBJECT => '$(O_FILES)', # link all the C files too
diff --git a/plugin/handler_socket/plug.in b/plugin/handler_socket/plug.in
index 0a6c36ba39f..fd351dec98d 100644
--- a/plugin/handler_socket/plug.in
+++ b/plugin/handler_socket/plug.in
@@ -16,4 +16,5 @@ MYSQL_PLUGIN_ACTIONS(handlersocket,
AC_SUBST(MYSQL_LIB)
AC_SUBST(PLUGIN_DIR)
AC_SUBST(HANDLERSOCKET_SUBDIRS)
+ AC_CONFIG_FILES(plugin/handler_socket/perl-Net-HandlerSocket/Makefile.PL)
])
diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
index a62569843db..d0cbafccc82 100755
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -80,7 +80,10 @@ CONFIGURE_FILE(mysqldumpslow.sh
CONFIGURE_FILE(mysqlhotcopy.sh
${CMAKE_BINARY_DIR}/scripts/mysqlhotcopy.pl ESCAPE_QUOTES @ONLY)
-FOREACH(f mysqldumpslow.pl mysqlhotcopy.pl mysql_config.pl
+CONFIGURE_FILE(mytop.sh
+ ${CMAKE_BINARY_DIR}/scripts/mytop.pl ESCAPE_QUOTES @ONLY)
+
+FOREACH(f mysqldumpslow.pl mysqlhotcopy.pl mytop.pl mysql_config.pl
mysql_convert_table_format.pl mysql_install_db.pl
mysql_secure_installation.pl mysqld_multi.pl)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${f}
@@ -90,4 +93,4 @@ ENDFOREACH()
INSTALL(FILES fill_help_tables.sql mysql_system_tables.sql
mysql_system_tables_data.sql mysql_system_tables_fix.sql mysql_test_data_timezone.sql
DESTINATION share COMPONENT Server)
-INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql_fix_privilege_tables.sql DESTINATION share COMPONENT Server) \ No newline at end of file
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mysql_fix_privilege_tables.sql DESTINATION share COMPONENT Server)
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 015b664c87d..e7504453fbc 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -33,6 +33,7 @@ bin_SCRIPTS = @server_scripts@ \
mysql_convert_table_format \
mysql_find_rows \
mysqlhotcopy \
+ mytop \
mysqldumpslow \
mysqld_multi
@@ -58,6 +59,7 @@ EXTRA_SCRIPTS = make_binary_distribution.sh \
mysql_convert_table_format.sh \
mysql_find_rows.sh \
mysqlhotcopy.sh \
+ mytop.sh \
mysqldumpslow.sh \
mysqld_multi.sh \
mysqld_safe.sh \
@@ -91,6 +93,7 @@ CLEANFILES = @server_scripts@ \
mysql_convert_table_format \
mysql_find_rows \
mysqlhotcopy \
+ mytop \
mysqldumpslow \
mysqld_multi \
convert-debug-for-diff \
@@ -114,7 +117,10 @@ mysqlbug: ${top_builddir}/config.status mysqlbug.sh
mysql_fix_privilege_tables.sql: mysql_system_tables.sql \
mysql_system_tables_fix.sql
@echo "Building $@";
- @cat mysql_system_tables.sql mysql_system_tables_fix.sql > $@
+ @echo "-- This file is automaticly generated from" > $@
+ @echo "-- mysql_system_tables.sql & mysql_system_tables_fix.sql" >> $@
+ @echo "" >> $@
+ @cat mysql_system_tables.sql mysql_system_tables_fix.sql >> $@
#
# Build mysql_fix_privilege_tables_sql.c from
diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh
index 828670d9408..789f3e3ce2e 100644
--- a/scripts/make_binary_distribution.sh
+++ b/scripts/make_binary_distribution.sh
@@ -169,6 +169,7 @@ esac
VERSION_NAME=@VERSION@
case $VERSION_NAME in
*-ndb-* ) VERSION_NAME=`echo $VERSION_NAME | sed -e 's/[.0-9]*-ndb-//'` ;;
+ *-MariaDB-* ) VERSION_NAME=`echo $VERSION_NAME | sed -e 's/-MariaDB//'` ;;
esac
if [ x"$SHORT_PRODUCT_TAG" != x"" ] ; then
NEW_NAME=mariadb-$SHORT_PRODUCT_TAG-$VERSION_NAME-$PLATFORM$SUFFIX
@@ -459,6 +460,7 @@ copyfileto $BASE/bin $BIN_FILES
$CP netware/*.pl $BASE/scripts
$CP scripts/mysqlhotcopy $BASE/scripts/mysqlhotcopy.pl
+$CP scripts/mytop $BASE/scripts/mytop.pl
copyfileto $BASE/lib \
libmysql/.libs/libmysqlclient.a \
diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist
index 37149440922..4d0e8acf7a8 100755
--- a/scripts/make_win_bin_dist
+++ b/scripts/make_win_bin_dist
@@ -373,6 +373,7 @@ mysql_secure_installation.pl \
mysqld_multi.pl \
mysqldumpslow.pl \
mysqlhotcopy.pl \
+mytop.pl \
"
mkdir -p $DESTDIR/scripts
diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql
index 468517d27cd..c21d9525bb2 100644
--- a/scripts/mysql_system_tables.sql
+++ b/scripts/mysql_system_tables.sql
@@ -13,7 +13,7 @@ set @had_db_table= @@warning_count != 0;
CREATE TABLE IF NOT EXISTS host ( Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Host privileges; Merged with database privileges';
-CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) unsigned DEFAULT 0 NOT NULL, plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL, auth_string TEXT NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges';
+CREATE TABLE IF NOT EXISTS user ( Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(41) character set latin1 collate latin1_bin DEFAULT '' NOT NULL, Select_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, File_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, References_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Show_view_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Alter_routine_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Create_user_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Event_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, Trigger_priv enum('N','Y') COLLATE utf8_general_ci DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') COLLATE utf8_general_ci DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, max_user_connections int(11) DEFAULT 0 NOT NULL, plugin char(60) CHARACTER SET latin1 DEFAULT '' NOT NULL, auth_string TEXT NOT NULL, PRIMARY KEY Host (Host,User) ) engine=MyISAM CHARACTER SET utf8 COLLATE utf8_bin comment='Users and global privileges';
-- Remember for later if user table already existed
set @had_user_table= @@warning_count != 0;
diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql
index 245bfe01c0a..7d791a5fc61 100644
--- a/scripts/mysql_system_tables_fix.sql
+++ b/scripts/mysql_system_tables_fix.sql
@@ -326,8 +326,11 @@ UPDATE host SET Create_routine_priv=Create_priv, Alter_routine_priv=Alter_priv,
#
# Add max_user_connections resource limit
+# this is signed in MariaDB so that if one sets it's to -1 then the user
+# can't connect anymore.
#
-ALTER TABLE user ADD max_user_connections int(11) unsigned DEFAULT '0' NOT NULL AFTER max_connections;
+ALTER TABLE user ADD max_user_connections int(11) DEFAULT '0' NOT NULL AFTER max_connections;
+ALTER TABLE user MODIFY max_user_connections int(11) DEFAULT '0' NOT NULL AFTER max_connections;
#
# user.Create_user_priv
diff --git a/scripts/mytop.sh b/scripts/mytop.sh
new file mode 100755
index 00000000000..5c88cf580a4
--- /dev/null
+++ b/scripts/mytop.sh
@@ -0,0 +1,2342 @@
+#!/usr/bin/perl -w
+#
+# $Id: mytop,v 1.90 2010/05/23 10:51:21 mark Exp $
+
+=pod
+
+=head1 NAME
+
+mytop - display MySQL server performance info like `top'
+
+=cut
+
+## most of the POD is at the bottom of the file
+
+use 5.005;
+use strict;
+use DBI;
+use Getopt::Long;
+use Socket;
+use List::Util qw(min max);
+
+$main::VERSION = "1.9a";
+
+$|=1;
+$0 = 'mytop';
+
+my $WIN = ($^O eq 'MSWin32') ? 1 : 0;
+
+## Test for color support.
+
+eval { require Term::ANSIColor; };
+
+my $HAS_COLOR = $@ ? 0 : 1;
+
+$HAS_COLOR = 0 if $WIN;
+
+## Test of Time::HiRes support
+
+eval { require Time::HiRes };
+
+my $HAS_TIME = $@ ? 0 : 1;
+
+my $debug = 0;
+
+## Try to lower our priority (which, who, pri)
+
+setpriority(0,0,10) unless $WIN;
+
+## Prototypes
+
+sub Clear();
+sub GetData();
+sub GetQPS();
+sub FullQueryInfo($);
+sub Explain($);
+sub PrintTable(@);
+sub PrintHelp();
+sub Sum(@);
+sub commify($);
+sub make_short($);
+sub Hashes($);
+sub Execute($);
+sub StringOrRegex($);
+sub GetInnoDBStatus();
+sub GetCmdSummary();
+sub GetShowVariables();
+sub GetShowStatus();
+sub cmd_s;
+sub cmd_S;
+sub cmd_q;
+sub FindProg($);
+
+## Default Config Values
+
+my %config = (
+ batchmode => 0,
+ color => 1,
+ db => 'test',
+ delay => 5,
+ filter_user => qr/.?/,
+ filter_db => qr/.?/,
+ filter_host => qr/.?/,
+ filter_state => qr/.?/,
+ header => 1,
+ help => 0,
+ host => 'localhost',
+ idle => 1,
+ long => 120,
+ long_nums => 0,
+ mode => 'top',
+ prompt => 0,
+ pass => '',
+ port => 3306,
+ resolve => 0,
+ slow => 10, # slow query time
+ socket => '',
+ sort => 0, # default or reverse sort ("s")
+ user => 'root'
+);
+
+my %qcache = (); ## The query cache--used for full query info support.
+my %ucache = (); ## The user cache--used for full killing by user
+my %dbcache = (); ## The db cache. This should be merged at some point.
+my %statcache = (); ## The show status cache for GetShowStatus()
+
+my (%STATUS, %OLD_STATUS); # header stuff.
+
+my $CLEAR = $WIN ? '': `clear`;
+
+## Term::ReadKey values
+
+my $RM_RESET = 0;
+my $RM_NOBLKRD = 3; ## using 4 traps Ctrl-C :-(
+
+## Read the user's config file, if it exists.
+
+my $config = "$ENV{HOME}/.mytop";
+
+if (-e $config)
+{
+ if (open CFG, "<$config")
+ {
+ while (<CFG>)
+ {
+ next if /^\s*$/; ## skip blanks
+ next if /^\s*#/; ## skip comments
+
+ chomp;
+
+ if (/(\S+)\s*=\s*(.*\S)/)
+ {
+ $config{lc $1} = $2 if exists $config{lc $1};
+ }
+ }
+ close CFG;
+ }
+}
+
+## Command-line args.
+
+use vars qw($opt_foo);
+
+Getopt::Long::Configure('no_ignore_case', 'bundling');
+
+GetOptions(
+ "color!" => \$config{color},
+ "user|u=s" => \$config{user},
+ "pass|password|p=s" => \$config{pass},
+ "database|db|d=s" => \$config{db},
+ "host|h=s" => \$config{host},
+ "port|P=i" => \$config{port},
+ "socket|S=s" => \$config{socket},
+ "delay|s=i" => \$config{delay},
+ "batch|batchmode|b" => \$config{batchmode},
+ "header!" => \$config{header},
+ "idle|i!" => \$config{idle},
+ "resolve|r!" => \$config{resolve},
+ "prompt!" => \$config{prompt},
+ "long=i" => \$config{long},
+ "long_nums!" => \$config{long_nums},
+ "mode|m=s" => \$config{mode},
+ "slow=i" => \$config{slow},
+ "sort=s" => \$config{sort}
+);
+
+## User may have put the port with the host.
+
+if ($config{host} =~ s/:(\d+)$//)
+{
+ $config{port} = $1;
+}
+
+## Don't use Term::ReadKey unless running interactively.
+
+if (not $config{batchmode})
+{
+ require Term::ReadKey;
+ Term::ReadKey->import();
+}
+
+## User may want to disable color.
+
+if ($HAS_COLOR and not $config{color})
+{
+ $HAS_COLOR = 0;
+}
+
+if ($HAS_COLOR)
+{
+ import Term::ANSIColor ':constants';
+}
+else
+{
+ *RESET = sub { };
+ *YELLOW = sub { };
+ *RED = sub { };
+ *MAGENTA = sub { };
+ *GREEN = sub { };
+ *BLUE = sub { };
+ *WHITE = sub { };
+ *BOLD = sub { };
+}
+
+my $RESET = RESET() || '';
+my $YELLOW = YELLOW() || '';
+my $RED = RED() || '';
+my $MAGENTA = MAGENTA() || '';
+my $GREEN = GREEN() || '';
+my $BLUE = BLUE() || '';
+my $WHITE = WHITE() || '';
+my $BOLD = BOLD() || '';
+
+## Connect
+
+my $dsn;
+
+## Socket takes precedence.
+
+$dsn ="DBI:mysql:database=$config{db};mysql_read_default_group=mytop;";
+
+if ($config{socket} and -S $config{socket})
+{
+ $dsn .= "mysql_socket=$config{socket}";
+}
+else
+{
+ $dsn .= "host=$config{host};port=$config{port}";
+}
+
+if ($config{prompt})
+{
+ print "Password: ";
+ ReadMode(2);
+ chomp($config{pass} = <STDIN>);
+ ReadMode(0);
+ print "\n";
+}
+
+my $dbh = DBI->connect($dsn, $config{user}, $config{pass},
+ { PrintError => 0 });
+
+if (not ref $dbh)
+{
+ my $Error = <<EODIE
+Cannot connect to MySQL server. Please check the:
+
+ * database you specified "$config{db}" (default is "test")
+ * username you specified "$config{user}" (default is "root")
+ * password you specified "$config{pass}" (default is "")
+ * hostname you specified "$config{host}" (default is "localhost")
+ * port you specified "$config{port}" (default is 3306)
+ * socket you specified "$config{socket}" (default is "")
+
+The options my be specified on the command-line or in a ~/.mytop
+config file. See the manual (perldoc mytop) for details.
+
+Here's the exact error from DBI. It might help you debug:
+
+$DBI::errstr
+
+EODIE
+;
+
+ die $Error;
+
+}
+
+ReadMode($RM_RESET) unless $config{batchmode};
+
+## Get static data
+
+my $db_version;
+my $db_release;
+my $server="MySQL";
+my $have_query_cache;
+
+my @variables = Hashes("show variables");
+
+foreach (@variables)
+{
+ if ($_->{Variable_name} eq "version")
+ {
+ $db_version = $_->{Value};
+ $db_version =~ /(\d+)/;
+ $db_release= $1;
+ $server="MariaDB" if ($db_version =~ /maria/i);
+ next;
+ }
+ if ($_->{Variable_name} eq "have_query_cache")
+ {
+# if ($_->{Value} eq 'YES')
+ if ($_->{Value} eq 'YES' or $_->{Value} eq 'DEMAND') # http://freshmeat.net/users/jerjones
+ {
+ $have_query_cache = 1;
+ }
+ else
+ {
+ $have_query_cache = 0;
+ }
+ next;
+ }
+}
+
+#########################################################################
+##
+## The main loop
+##
+#########################################################################
+
+ReadMode($RM_NOBLKRD) unless $config{batchmode};
+
+while (1)
+{
+ my $key;
+
+ if ($config{mode} eq 'qps')
+ {
+ GetQPS();
+ $key = ReadKey(1);
+
+ next unless $key;
+
+ if ($key =~ /t/i)
+ {
+ $config{mode} = 'top';
+ }
+ if ($key =~ /q/)
+ {
+ cmd_q();
+ }
+ next;
+ }
+ if ($config{mode} eq 'top')
+ {
+ GetData();
+ last if $config{batchmode};
+ $key = ReadKey($config{delay});
+ next unless $key;
+ }
+ elsif ($config{mode} eq 'cmd')
+ {
+ GetCmdSummary();
+ last if $config{batchmode};
+ $key = ReadKey($config{delay});
+ next unless $key;
+ }
+ elsif ($config{mode} eq 'innodb')
+ {
+ GetInnoDBStatus();
+ last if $config{batchmode};
+ $key = ReadKey($config{delay});
+ next unless $key;
+ }
+ elsif ($config{mode} eq 'status')
+ {
+ GetShowStatus();
+ last if $config{batchmode};
+ $key = ReadKey($config{delay});
+ next unless $key;
+ }
+
+ ##
+ ## keystroke command processing (if we get this far)
+ ##
+
+ # ! - Force past a replication error
+
+ if ($key eq 'r')
+ {
+ Execute("STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; START SLAVE;");
+ next;
+ }
+
+ # t - top
+
+ if ($key =~ /t/i)
+ {
+ $config{mode} = 'top';
+ }
+
+ ## q - quit
+
+ if ($key eq 'q')
+ {
+ cmd_q();
+ }
+
+ if ($key eq 'D')
+ {
+ require Data::Dumper;
+ print Data::Dumper::Dumper([\%config]);
+ ReadKey(0);
+ }
+
+ ## l - change long running hightling
+
+ if ($key eq 'l')
+ {
+ cmd_l();
+ next;
+ }
+
+ ## m - mode swtich to qps
+
+ if ($key eq 'm')
+ {
+ $config{mode} = 'qps';
+ Clear() unless $config{batchmode};
+ print "Queries Per Second [hit q to exit this mode]\n";
+ next;
+ }
+
+ ## M - mode swtich to qps
+
+ if ($key eq 'M')
+ {
+ $config{mode} = 'status';
+ Clear() unless $config{batchmode};
+ print "Queries Per Second [hit q to exit this mode]\n";
+ next;
+ }
+
+ ## c - mode swtich to command summary
+
+ if ($key eq 'c')
+ {
+ $config{mode} = 'cmd';
+ Clear() unless $config{batchmode};
+ print "Command Summary [hit q to exit this mode]\n";
+ next;
+ }
+
+ ## C - change Color on and off
+
+ if ($key eq 'C')
+ {
+ if ( $HAS_COLOR )
+ {
+ $HAS_COLOR = 0;
+ }
+ else
+ {
+ $HAS_COLOR = 1;
+ }
+ }
+
+ ## s - seconds of delay
+
+ if ($key eq 's')
+ {
+ cmd_s();
+ next;
+ }
+
+ # Change the SLOW query value
+
+ if ($key eq 'S')
+ {
+ cmd_S();
+ next;
+ }
+
+ ## R - resolve hostnames
+ if ($key eq 'R')
+ {
+ if ($config{resolve})
+ {
+ $config{resolve} = 0;
+ }
+ else
+ {
+ $config{resolve} = 1;
+ }
+ }
+
+ ## t - username based filter
+
+ if ($key eq 't')
+ {
+ ReadMode($RM_RESET);
+ print RED(), "Which state (blank for all, /.../ for regex): ", RESET();
+ $config{filter_state} = StringOrRegex(ReadLine(0));
+ ReadMode($RM_NOBLKRD);
+ next;
+ }
+
+ ## u - username based filter
+
+ if ($key eq 'u')
+ {
+ ReadMode($RM_RESET);
+ print RED(), "Which user (blank for all, /.../ for regex): ", RESET();
+ $config{filter_user} = StringOrRegex(ReadLine(0));
+ ReadMode($RM_NOBLKRD);
+ next;
+ }
+
+ ## d - database name based filter
+
+ if ($key eq 'd')
+ {
+ ReadMode($RM_RESET);
+ print RED(), "Which database (blank for all, /.../ for regex): ",
+ RESET();
+ $config{filter_db} = StringOrRegex(ReadLine(0));
+ ReadMode($RM_NOBLKRD);
+ next;
+ }
+
+ ## h - hostname based filter
+
+ if ($key eq 'h')
+ {
+ ReadMode($RM_RESET);
+ print RED(), "Which hostname (blank for all, /.../ for regex): ",
+ RESET();
+ $config{filter_host} = StringOrRegex(ReadLine(0));
+ ReadMode($RM_NOBLKRD);
+ next;
+ }
+
+ ## E - Show full Replication Error
+
+ if ($key eq 'E')
+ {
+ my($data) = Hashes('SHOW SLAVE STATUS');
+ Clear();
+ print "Error is: $data->{Last_Error}\n";
+ print RED(), "-- paused. press any key to resume --", RESET();
+ ReadKey(0);
+ next;
+ }
+ ## F - remove all filters
+
+ if ($key eq 'F')
+ {
+ $config{filter_host} = qr/.?/;
+ $config{filter_db} = qr/.?/;
+ $config{filter_user} = qr/.?/;
+ $config{filter_state} = qr/.?/;
+ print RED(), "-- display unfiltered --", RESET();
+ sleep 1;
+ next;
+ }
+
+ ## p - pause
+
+ if ($key eq 'p')
+ {
+ print RED(), "-- paused. press any key to resume --", RESET();
+ ReadKey(0);
+ next;
+ }
+
+ ## i - idle toggle
+
+ if ($key =~ /i/)
+ {
+ if ($config{idle})
+ {
+ $config{idle} = 0;
+ $config{sort} = 1;
+ print RED(), "-- idle (sleeping) processed filtered --", RESET();
+ sleep 1;
+ }
+ else
+ {
+ $config{idle} = 1;
+ $config{sort} = 0;
+ print RED(), "-- idle (sleeping) processed unfiltered --", RESET();
+ sleep 1;
+ }
+ }
+
+ ## I - InnoDB status
+
+ if ($key =~ 'I')
+ {
+ $config{mode} = 'innodb';
+ Clear() unless $config{batchmode};
+ print "InnoDB Status [hit q to exit this mode]\n";
+ next;
+ }
+
+ ## o - sort order
+
+ if ($key =~ /o/)
+ {
+ if ($config{sort})
+ {
+ $config{sort} = 0;
+ print RED(), "-- sort order reversed --", RESET();
+ sleep 1;
+ }
+ else
+ {
+ $config{sort} = 1;
+ print RED(), "-- sort order reversed --", RESET();
+ sleep 1;
+ }
+ }
+
+ ## ? - help
+
+ if ($key eq '?')
+ {
+ Clear();
+ PrintHelp();
+ ReadKey(0);
+ next;
+ }
+
+ ## k - kill
+
+ if ($key eq 'k')
+ {
+ ReadMode($RM_RESET);
+
+ print RED(), "Thread id to kill: ", RESET();
+ my $id = ReadLine(0);
+
+ $id =~ s/\s//g;
+
+ if ($id =~ /^\d+$/)
+ {
+ Execute("KILL $id");
+ }
+ else
+ {
+ print RED(), "-- invalid thread id --", RESET();
+ sleep 1;
+ }
+
+ ReadMode($RM_NOBLKRD);
+ next;
+ }
+
+ ## K - kill based on a username
+ if ($key =~ /K/)
+ {
+ ReadMode($RM_RESET);
+
+ print RED(), "User to kill: ", RESET();
+ my $user = ReadLine(0);
+
+ $user =~ s/\s//g;
+
+ if ($user =~ /^\S+$/)
+ {
+ for my $pid (keys %ucache)
+ {
+ next unless $ucache{$pid} eq $user;
+ Execute("KILL $pid");
+ select(undef, undef, undef, 0.2);
+ }
+ }
+ else
+ {
+ print RED(), "-- invalid thread id --", RESET();
+ sleep 1;
+ }
+
+ ReadMode($RM_NOBLKRD);
+ }
+
+ ## f - full info
+
+ if ($key =~ /f/)
+ {
+ ReadMode($RM_RESET);
+ print RED(), "Full query for which thread id: ", RESET();
+ my $id = ReadLine(0);
+ chomp $id;
+ FullQueryInfo($id);
+ ReadMode($RM_NOBLKRD);
+ print RED(), "-- paused. press any key to resume or (e) to explain --",
+ RESET();
+ my $key = ReadKey(0);
+
+ if ($key eq 'e')
+ {
+ Explain($id);
+ print RED(), "-- paused. press any key to resume --", RESET();
+ ReadKey(0);
+ }
+
+ next;
+ }
+
+ ## e - explain
+
+ if ($key =~ /e/)
+ {
+ ReadMode($RM_RESET);
+ print RED(), "Explain which query (id): ", RESET();
+ my $id = ReadLine(0);
+ chomp $id;
+ Explain($id);
+ ReadMode($RM_NOBLKRD);
+ print RED(), "-- paused. press any key to resume --", RESET();
+ ReadKey(0);
+ next;
+ }
+
+ ## r - reset status counters
+
+ if ($key =~ /r/)
+ {
+ Execute("FLUSH STATUS");
+ print RED(), "-- counters reset --", RESET();
+ sleep 1;
+ next;
+ }
+
+ ## H - header toggle
+
+ if ($key eq 'H')
+ {
+ if ($config{header})
+ {
+ $config{header} = 0;
+ }
+ else
+ {
+ $config{header}++;
+ }
+ }
+
+ ## # - magic debug key
+
+ if ($key eq '#')
+ {
+ $debug = 1;
+ }
+
+ if ($key eq 'V')
+ {
+ GetShowVariables();
+ print RED(), "-- paused. press any key to resume --", RESET();
+ ReadKey(0);
+ }
+
+ if ($key eq 'S')
+ {
+ $config{mode} = 'status';
+ }
+}
+
+ReadMode($RM_RESET) unless $config{batchmode};
+
+exit;
+
+#######################################################################
+
+sub Clear()
+{
+ if (not $WIN)
+ {
+ print "$CLEAR"
+ }
+ else
+ {
+ print "\n" x 90; ## dumb hack for now. Anyone know how to
+ ## clear the screen in dos window on a Win32
+ ## system??
+ }
+}
+
+my $last_time;
+
+sub GetData()
+{
+ ## Get terminal info
+ my $now_time;
+ %qcache = (); ## recycle memory
+ %dbcache = ();
+
+ my ($width, $height, $wpx, $hpx, $lines_left);
+
+ if (not $config{batchmode})
+ {
+ ($width, $height, $wpx, $hpx) = GetTerminalSize();
+ $lines_left = $height - 2;
+ }
+ else
+ {
+ $height = 999_999; ## I hope you don't have more than that!
+ $lines_left = 999_999;
+ $width = 80;
+ }
+
+ ##
+ ## Header stuff.
+ ##
+ if ($config{header})
+ {
+ my @recs = "";
+ if ( $db_release > 4 )
+ {
+ @recs = Hashes("show global status");
+ }
+ else
+ {
+ @recs = Hashes("show status");
+ }
+
+ ## if the server died or we lost connectivity
+ if (not @recs)
+ {
+ ReadMode($RM_RESET);
+ exit 1;
+ }
+
+ ## get high-res or low-res time
+ my ($t_delta);
+
+ if ($HAS_TIME)
+ {
+ $now_time = Time::HiRes::gettimeofday();
+ }
+ else
+ {
+ $now_time = time;
+ }
+
+ if ($last_time and $last_time != $now_time)
+ {
+ $t_delta = $now_time - $last_time;
+ }
+
+ %OLD_STATUS = %STATUS;
+
+ foreach my $ref (@recs)
+ {
+ my $key = $ref->{Variable_name};
+ my $val = $ref->{Value};
+
+ $STATUS{$key} = $val;
+ }
+
+ ## Compute Key Cache Hit Stats
+
+ $STATUS{Key_read_requests} ||= 1; ## can't divide by zero next
+
+ my $cache_hits_percent = (100-($STATUS{Key_reads}/$STATUS{Key_read_requests}) * 100);
+ $cache_hits_percent = sprintf("%2.2f",$cache_hits_percent);
+
+ ## Query Cache info for <= Ver. 4.1
+ ##
+ ## mysql> show status like 'qcache%';
+ ## +-------------------------+----------+
+ ## | Variable_name | Value |
+ ## +-------------------------+----------+
+ ## | Qcache_queries_in_cache | 81 |
+ ## | Qcache_inserts | 4961668 |
+ ## | Qcache_hits | 1374170 |
+ ## | Qcache_not_cached | 5656249 |
+ ## | Qcache_free_memory | 33164800 |
+ ## | Qcache_free_blocks | 2 |
+ ## | Qcache_total_blocks | 168 |
+ ## +-------------------------+----------+
+ ##
+ ## Query Cache info for => Ver. 5.0
+ ##
+ ## mysql> show status like 'qcache%';
+ ## +-------------------------+------------+
+ ## | Variable_name | Value |
+ ## +-------------------------+------------+
+ ## | Qcache_free_blocks | 37652 |
+ ## | Qcache_free_memory | 110289712 |
+ ## | Qcache_hits | 1460617356 |
+ ## | Qcache_inserts | 390563495 |
+ ## | Qcache_lowmem_prunes | 6414172 |
+ ## | Qcache_not_cached | 93002420 |
+ ## | Qcache_queries_in_cache | 66558 |
+ ## | Qcache_total_blocks | 192031 |
+ ## +-------------------------+------------+
+
+ my $query_cache_hits = 0;
+ my $query_cache_hits_per_sec = 0;
+ my $now_query_cache_hits_per_sec = 0;
+
+ if ($have_query_cache)
+ {
+ $query_cache_hits = $STATUS{Qcache_hits};
+ $query_cache_hits_per_sec = $STATUS{Qcache_hits} / $STATUS{Uptime};
+
+ if (defined $last_time and $last_time != $now_time)
+ {
+ my $q_delta = $STATUS{Qcache_hits} - $OLD_STATUS{Qcache_hits};
+ $now_query_cache_hits_per_sec = sprintf "%.2f", $q_delta / $t_delta;
+ }
+ }
+
+ $last_time = $now_time;
+
+ ## Server Uptime in meaningful terms...
+
+ my $time = $STATUS{Uptime};
+ my ($d,$h,$m,$s) = (0, 0, 0, 0);
+
+ $d += int($time / (60*60*24)); $time -= $d * (60*60*24);
+ $h += int($time / (60*60)); $time -= $h * (60*60);
+ $m += int($time / (60)); $time -= $m * (60);
+ $s += int($time);
+
+ my $uptime = sprintf("%d+%02d:%02d:%02d", $d, $h, $m, $s);
+
+ ## Queries per second...
+
+ my $avg_queries_per_sec = sprintf("%.2f", $STATUS{Questions} / $STATUS{Uptime});
+ my $num_queries = $STATUS{Questions};
+
+ my @t = localtime(time);
+
+ my $current_time = sprintf "[%02d:%02d:%02d]", $t[2], $t[1], $t[0];
+
+ my $host_width = 50;
+ my $up_width = $width - $host_width - 1;
+ Clear() unless $config{batchmode};
+ print RESET();
+
+ printf "%-.${host_width}s %${up_width}s\n",
+ "$server on $config{host} ($db_version)",
+ "up $uptime $current_time";
+ $lines_left--;
+
+
+ printf " Queries: %-6s qps: %4.0f Slow: %7s Se/In/Up/De(%%): %02.0f/%02.0f/%02.0f/%02.0f \n",
+ make_short( $STATUS{Questions} ), # q total
+ $STATUS{Questions} / $STATUS{Uptime}, # qps, average
+ make_short( $STATUS{Slow_queries} ), # slow
+
+ # hmm. a Qcache hit is really a select and should be counted.
+ 100 * ($STATUS{Com_select} + ($STATUS{Qcache_hits}||0) ) / $STATUS{Questions},
+ 100 * ($STATUS{Com_insert} + $STATUS{Com_replace} ) / $STATUS{Questions},
+ 100 * ($STATUS{Com_update} ) / $STATUS{Questions},
+ 100 * $STATUS{Com_delete} / $STATUS{Questions};
+
+ $lines_left--;
+
+ if ($t_delta)
+ {
+ my $q_diff = ( $STATUS{Questions} - $OLD_STATUS{Questions} );
+# print("q_diff: $STATUS{Questions} - $OLD_STATUS{Questions} / $t_delta = $q_diff\n");
+
+ printf(" Sorts: %5.0f qps now: %4.0f Slow qps: %3.1f Threads: %4.0f (%4.0f/%4.0f) %02.0f/%02.0f/%02.0f/%02.0f \n",
+ ( $STATUS{Sort_rows} - $OLD_STATUS{Sort_rows} ) / $t_delta,
+ ( $STATUS{Questions} - $OLD_STATUS{Questions} ) / $t_delta,
+ ( # slow now (qps)
+ ($STATUS{Slow_queries} ) ?
+ ( $STATUS{Slow_queries} - $OLD_STATUS{Slow_queries} ) / $t_delta :
+ 0
+ ),
+ $STATUS{Threads_connected},
+ $STATUS{Threads_running},
+ $STATUS{Threads_cached},
+
+ (100 * ($STATUS{Com_select} - $OLD_STATUS{Com_select} +
+ ($STATUS{Qcache_hits}||0) - ($OLD_STATUS{Qcache_hits}||0)
+ ) ) / ($q_diff ),
+ (100 * ($STATUS{Com_insert} - $OLD_STATUS{Com_insert} +
+ $STATUS{Com_replace} - $OLD_STATUS{Com_replace}
+ ) ) / ($q_diff ),
+ (100 * ($STATUS{Com_update} - $OLD_STATUS{Com_update}) ) / ($q_diff ),
+ (100 * ($STATUS{Com_delete} - $OLD_STATUS{Com_delete}) ) / ($q_diff ),
+ );
+ }
+ else
+ {
+ print "\n";
+ }
+ $lines_left--;
+
+ if ($have_query_cache and $STATUS{Com_select} and $query_cache_hits)
+ {
+ printf(" Cache Hits: %-5s Hits/s: %4.1f Hits now: %5.1f Ratio: ",
+ make_short($STATUS{Qcache_hits}), # cache hits
+ $STATUS{Qcache_hits} / $STATUS{Uptime}, # hits / sec
+ ($t_delta) ? ($STATUS{Qcache_hits} - $OLD_STATUS{Qcache_hits}) / $t_delta : 0, # Hits Now
+ );
+
+ my($Ratio) = 100 * ($STATUS{Qcache_hits}) / ($STATUS{Qcache_hits} + $STATUS{Com_select} );
+ if ($HAS_COLOR)
+ {
+ print YELLOW() if ($Ratio < 80.0);
+ print RED() if ($Ratio < 50.0);
+ print MAGENTA() if ($Ratio < 20.0);
+ }
+ printf("%4.1f%% ",$Ratio);
+ if ($HAS_COLOR)
+ {
+ print RESET();
+ }
+
+ print " Ratio now: ";
+ my($Ratio_now) = ($t_delta) ? # ratio now
+ 100 * ($STATUS{Qcache_hits} - $OLD_STATUS{Qcache_hits} ) /
+ ( ($STATUS{Com_select} + $STATUS{Qcache_hits} -
+ ($OLD_STATUS{Qcache_hits} + $OLD_STATUS{Com_select})
+ ) || 1) : 0;
+ if ($HAS_COLOR)
+ {
+ print GREEN() if ($Ratio_now >= 80.0);
+ print YELLOW() if ($Ratio_now < 80.0);
+ print RED() if ($Ratio_now < 50.0);
+ print MAGENTA() if ($Ratio_now < 20.0);
+ }
+ printf("%4.1f%% \n",$Ratio_now);
+ if ($HAS_COLOR)
+ {
+ print RESET();
+ }
+ }
+ $lines_left--;
+
+
+ printf(" MyISAM Key Efficiency: %2.1f%% Bps in/out: %5s/%5s ",
+ $cache_hits_percent,
+ make_short($STATUS{Bytes_received} / $STATUS{Uptime} ),
+ make_short($STATUS{Bytes_sent} / $STATUS{Uptime}));
+ printf("Now in/out: %5s/%5s",
+ make_short(($STATUS{Bytes_received} - $OLD_STATUS{Bytes_received}) / $t_delta ),
+ make_short(($STATUS{Bytes_sent} - $OLD_STATUS{Bytes_sent}) / $t_delta ))
+ if ($t_delta);
+ print "\n";
+
+ $lines_left--;
+
+ my($data) = Hashes('SHOW SLAVE STATUS');
+ if (defined($data->{Master_Host}))
+ {
+ print " Replication ";
+ if ($HAS_COLOR) {
+ print GREEN();
+ print RED() if ($data->{Slave_IO_Running} ne "Yes") ;
+ }
+ print "IO:$data->{Slave_IO_Running} ";
+ RESET() if ($HAS_COLOR);
+
+ if ($HAS_COLOR) {
+ print GREEN();
+ print RED() if ($data->{Slave_SQL_Running} ne "Yes") ;
+ }
+ print "SQL:$data->{Slave_SQL_Running} ";
+ print RESET() if ($HAS_COLOR);
+
+ my $SlaveDelay = $data->{Seconds_Behind_Master};
+ if ($SlaveDelay)
+ {
+ if ($HAS_COLOR) {
+ print GREEN();
+ print YELLOW() if ($SlaveDelay > 10);
+ print MAGENTA() if ($SlaveDelay > 120);
+ }
+ print "Delay: $SlaveDelay sec.";
+ } else {
+ my $free = $width - 35;
+ my $Err = substr $data->{Last_Error},0 ,$free;
+ printf(" ERR: %-${free}s", $Err) if ( $Err ne "" );
+ }
+ print WHITE() if ($HAS_COLOR);
+ print "\n";
+ $lines_left--;
+ }
+ print "\n";
+ }
+
+ if (not $config{batchmode} and not $config{header})
+ {
+ Clear();
+ print RESET();
+ }
+
+ ##
+ ## Threads
+ ##
+
+ my @sz = (9, 8, 15, 9, 6, 5, 6, 8);
+ my $used = scalar(@sz) + Sum(@sz);
+ my $state= $width <= 80 ? 6 : int(min(6+($width-80)/3, 15));
+ my $free = $width - $used - ($state - 6);
+ my $format= "%9s %8s %15s %9s %6s %5s %6s %${state}s %-.${free}s\n";
+ my $format2= "%9d %8.8s %15.15s %9.9s %6d %5.1f %6.6s %${state}.${state}s %-${free}.${free}s\n";
+ print BOLD() if ($HAS_COLOR);
+
+ printf $format,
+ 'Id','User','Host/IP','DB','Time', '%', 'Cmd', 'State', 'Query';
+
+ print RESET() if ($HAS_COLOR);
+
+ ## Id User Host DB
+ printf $format,
+ '--','----','-------','--','----', '-', '---', '-----', '----------';
+
+ $lines_left -= 2;
+
+ my $proc_cmd = "show full processlist";
+
+ my @data = Hashes($proc_cmd);
+
+ foreach my $thread (@data)
+ {
+ last if not $lines_left;
+
+ ## Drop Domain Name, unless it looks like an IP address. If
+ ## it's an IP, we'll strip the port number because it's rarely
+ ## interesting.
+
+ my $is_ip = 0;
+
+ if ($thread->{Host} =~ /^(\d{1,3}\.){3}(\d{1,3})(:\d+)?$/)
+ {
+ $thread->{Host} =~ s/:.*$//;
+ $is_ip = 1;
+ }
+ else
+ {
+ $thread->{Host} =~ s/^([^.]+).*/$1/;
+ }
+
+ ## Otherwise, look up the IP (if resolve is set) and strip the
+ ## name
+ if ($is_ip and $config{resolve})
+ {
+ $thread->{Host} =~ s/:\d+$//;
+ my $host = gethostbyaddr(inet_aton($thread->{Host}), AF_INET);
+# $host =~ s/^([^.]+).*/$1/;
+ $thread->{Host} = $host;
+ }
+
+ ## Fix possible undefs
+
+ $thread->{db} ||= '';
+ $thread->{Info} ||= '';
+ $thread->{Time} ||= 0 ;
+ $thread->{Id} ||= 0 ;
+ $thread->{User} ||= '';
+ $thread->{Command} ||= '';
+ $thread->{Host} ||= '';
+ $thread->{State} ||= "";
+ $thread->{Progress} ||= 0;
+
+ ## alter double hyphen comments so they don't break
+ ## the query when newlines are removed - http://freshmeat.net/users/jerjones
+ $thread->{Info} =~ s~\s--(.*)$~ /* $1 */ ~mg;
+
+ ## Normalize spaces -- mostly disabled for now. This can
+ ## break EXPLAIN if you try to explain a mangled query. It
+ ## may be re-enabled later as an option.
+
+ ## leading space removal
+ $thread->{Info} =~ s/^\s*//;
+
+ if (1)
+ {
+ ## remove newlines and carriage returns
+ $thread->{Info} =~ s/[\n\r]//g;
+
+ ## collpase whitespace
+ $thread->{Info} =~ s/\s+/ /g;
+ }
+
+ ## stow it in the cache
+
+ $qcache{$thread->{Id}} = $thread->{Info};
+ $dbcache{$thread->{Id}} = $thread->{db};
+ $ucache{$thread->{Id}} = $thread->{User};
+
+ }
+
+ ## Sort by idle time (closest thing to CPU usage I can think of).
+
+ my @sorted;
+
+ if (not $config{sort})
+ {
+ @sorted = sort { $a->{Time} <=> $b->{Time} } @data
+ }
+ else
+ {
+ @sorted = sort { $b->{Time} <=> $a->{Time} } @data
+ }
+
+ foreach my $thread (@sorted)
+ {
+ # Check to see if we can skip out. We skip out if we know the
+ # given line doesn't match.
+
+ next if (($thread->{Command} eq "Sleep")
+ and
+ (not $config{idle}));
+
+ next if (($thread->{Command} eq "Binlog Dump")
+ and
+ (not $config{idle}));
+
+ next if (($thread->{Command} eq "Daemon")
+ and
+ (not $config{idle}));
+
+ next if ($thread->{User} !~ $config{filter_user});
+ next if ($thread->{db} !~ $config{filter_db});
+ next if ($thread->{Host} !~ $config{filter_host});
+ next if ($thread->{State} !~ $config{filter_state});
+
+ # Otherwise, print.
+
+ my $smInfo;
+
+ if ($thread->{Info})
+ {
+ $smInfo = substr $thread->{Info}, 0, $free;
+ }
+# if ($thread->{State})
+# {
+# $smInfo = substr $thread->{State}, 0, $free;
+# }
+ else
+ {
+ $smInfo = "";
+ }
+
+ if ($HAS_COLOR)
+ {
+ print YELLOW() if $thread->{Command} eq 'Query';
+ print WHITE() if $thread->{Command} eq 'Sleep';
+ print GREEN() if $thread->{Command} eq 'Connect';
+ print BOLD() if $thread->{Time} > $config{slow};
+ print MAGENTA() if $thread->{Time} > $config{long};
+ }
+
+ printf $format2,
+ $thread->{Id}, $thread->{User}, $thread->{Host}, $thread->{db},
+ $thread->{Time}, $thread->{Progress}, $thread->{Command}, $thread->{State}, $smInfo;
+
+ print RESET() if $HAS_COLOR;
+
+ $lines_left--;
+
+ last if $lines_left == 0;
+
+ }
+
+}
+
+###########################################################################
+
+my $questions;
+
+sub GetQPS()
+{
+ my($data) = Hashes('SHOW STATUS LIKE "Questions"');
+ my $num = $data->{Value};
+
+ if (not defined $questions) ## first time?
+ {
+ $questions = $num;
+ return;
+ }
+
+ my $qps = $num - $questions;
+ $questions = $num;
+ print "$qps\n";
+}
+
+###########################################################################
+
+sub GetQcacheSummary()
+{
+}
+
+###########################################################################
+
+sub GetInnoDBStatus()
+{
+ if (not $config{pager})
+ {
+ if (not $config{pager} = FindProg('less'))
+ {
+ $config{pager} = FindProg('more');
+ }
+ }
+
+ my @data = Hashes("SHOW INNODB STATUS");
+
+ open P, "|$config{pager}" or die "$!";
+ print keys %{$data[0]};
+ print $data[0]->{Status},"\n";
+ close P;
+}
+
+###########################################################################
+
+my %prev_data;
+
+sub GetCmdSummary()
+{
+ my ($width, $height, $wpx, $hpx, $lines_left);
+
+ if (not $config{batchmode})
+ {
+ ($width, $height, $wpx, $hpx) = GetTerminalSize();
+
+ $lines_left = $height - 2;
+ }
+ else
+ {
+ $height = 999_999; ## I hope you don't have more than that!
+ $lines_left = 999_999;
+ $width = 80;
+ }
+
+ # Variable_name and Value pairs come back...
+ my @data = Hashes("SHOW STATUS LIKE 'Com_%'");
+ my %cmd_data;
+ my %cmd_delta;
+ my %cmd_pct;
+ my %cmd_delta_pct;
+ my $total;
+ my $delta_total;
+
+ for my $item (@data)
+ {
+ next unless $item->{Value};
+ $item->{Variable_name} =~ s/^Com_//;
+ $item->{Variable_name} =~ s/_/ /g;
+ $cmd_data{$item->{Variable_name}} = $item->{Value};
+ $total += $item->{Value};
+ }
+
+ ## Populate other stats
+
+ for my $item (keys %cmd_data)
+ {
+ $cmd_delta{$item} = $cmd_data{$item} -
+ ($prev_data{$item} || $cmd_data{$item} - 1);
+
+ $delta_total += $cmd_delta{$item};
+
+ $cmd_pct{$item} = int(($cmd_data{$item} / $total) * 100);
+ }
+
+ for my $item (keys %cmd_data)
+ {
+ $cmd_delta_pct{$item} = int(($cmd_delta{$item} / $delta_total) * 100);
+ }
+
+
+ ## Display
+
+ Clear() unless $config{batchmode};
+ print RESET();
+ printf "%18s %10s %4s | %5s %4s\n", 'Command', 'Total', 'Pct', 'Last', 'Pct';
+ printf "%18s %10s %4s | %5s %4s\n", '-------', '-----', '---', '----', '---';
+ $lines_left -= 2;
+
+ for my $item (sort { $cmd_data{$b} <=> $cmd_data{$a} } keys %cmd_data)
+ {
+ printf "%18s %10d %4s | %5d %4s\n",
+ $item,
+ $cmd_data{$item},
+ $cmd_pct{$item} . "%",
+ $cmd_delta{$item},
+ $cmd_delta_pct{$item} . "%";
+
+ last if not $lines_left;
+ $lines_left -= 1;
+ }
+
+ %prev_data = %cmd_data;
+}
+
+###########################################################################
+
+sub GetShowVariables()
+{
+ if (not $config{pager})
+ {
+ if (not $config{pager} = FindProg('less'))
+ {
+ $config{pager} = FindProg('more');
+ }
+ }
+
+ my @rows = Hashes("SHOW VARIABLES");
+
+ open P, "|$config{pager}" or die "$!";
+
+ for my $row (@rows)
+ {
+ my $name = $row->{Variable_name};
+ my $value = $row->{Value};
+ printf P "%32s: %s\n", $name, $value;
+ }
+
+ close P;
+}
+
+###########################################################################
+
+sub GetShowStatus()
+{
+ Clear() unless $config{batchmode};
+ my @rows = Hashes("SHOW STATUS");
+
+ printf "%32s %10s %10s\n", 'Counter', 'Total', 'Change';
+ printf "%32s %10s %10s\n", '-------', '-----', '------';
+
+ for my $row (@rows)
+ {
+ my $name = $row->{Variable_name};
+ my $value = $row->{Value};
+ my $old = $statcache{$name};
+ my $delta = 0;
+
+ next if $name =~ m/^Com_/; ## skip Com_ stats
+ next if $value =~ m/^[^0-9]*$/; ## skip non-numeric
+
+ ## TODO: if Qcache is off, we should skip Qcache_ values
+
+ if ($HAS_COLOR and defined $old and $old =~ /^\d/)
+ {
+ if ($value > $old)
+ {
+ print YELLOW();
+ $delta = $value - $old;
+ }
+ elsif ($value < $old)
+ {
+ print RED();
+ $delta = $value - $old;
+ }
+
+ if (not $config{idle} and $value == $old)
+ {
+ # filter unchanging stats, maybe
+ print RESET();
+ next;
+ }
+ }
+
+ if ($delta != 0) {
+ printf "%32s: %10s %10s\n", $name, $value, $delta;
+ }
+ print RESET() if $HAS_COLOR;
+
+ $statcache{$name} = $value;
+ }
+
+}
+
+###########################################################################
+
+sub FullQueryInfo($)
+{
+ my $id = shift;
+
+ if (not exists $qcache{$id} or not defined $qcache{$id})
+ {
+ print "*** Invalid id. ***\n";
+ return;
+ }
+
+ my $sql = $qcache{$id};
+ print $CLEAR;
+ print "Thread $id was executing following query:\n\n";
+ print YELLOW(), $sql,"\n\n", RESET();
+}
+
+###########################################################################
+
+sub Explain($)
+{
+ my $id = shift;
+
+ if (not exists $qcache{$id} or not defined $qcache{$id})
+ {
+ print "*** Invalid id. ***\n";
+ return;
+ }
+
+ my $sql = $qcache{$id};
+ my $db = $dbcache{$id};
+
+ Execute("USE $db");
+ my @info = Hashes("EXPLAIN $sql");
+ print $CLEAR;
+ print "EXPLAIN $sql:\n\n";
+ PrintTable(@info);
+}
+
+###########################################################################
+
+sub PrintTable(@)
+{
+ my $cnt = 1;
+ my @cols = qw(table type possible_keys key key_len ref rows Extra);
+
+ for my $row (@_)
+ {
+ print "*** row $cnt ***\n";
+ for my $key (@cols)
+ {
+ my $val = $row->{$key} || 'NULL';
+ printf "%15s: %s\n", $key, $val;
+ }
+ $cnt++;
+ }
+}
+
+###########################################################################
+
+sub StringOrRegex($)
+{
+ my $input = shift;
+ chomp $input;
+ if (defined $input)
+ {
+ # regex, strip /.../ and use via qr//
+ if ($input =~ m{^/} and $input =~ m{/$})
+ {
+ $input =~ s{^/}{} if $config{filter_user};
+ $input =~ s{/$}{} if $config{filter_user};
+ $input = qr/$input/;
+ }
+
+
+ # reset to match anything
+ elsif ($input eq '')
+ {
+ $input = qr/.*/;
+ }
+
+ # string, build a simple regex
+ else
+ {
+ $input = '^' . $input . '$';
+ $input = qr/$input/;
+ }
+ }
+
+ # reset to match anything
+ else
+ {
+ $input = qr/.*/;
+ }
+ return $input;
+}
+
+###########################################################################
+
+sub cmd_l
+{
+ ReadMode($RM_RESET);
+
+ print RED(), "Seconds for long queries: ", RESET();
+ my $secs = ReadLine(0);
+
+ if ($secs =~ /^\s*(\d+)/)
+ {
+ $config{long} = $1;
+ if ($config{long} < 1)
+ {
+ $config{long} = 1;
+ }
+ }
+ ReadMode($RM_NOBLKRD);
+}
+
+sub cmd_s
+{
+ ReadMode($RM_RESET);
+
+ print RED(), "Seconds of Delay: ", RESET();
+ my $secs = ReadLine(0);
+
+ if ($secs =~ /^\s*(\d+)/)
+ {
+ $config{delay} = $1;
+ if ($config{delay} < 1)
+ {
+ $config{delay} = 1;
+ }
+ }
+ ReadMode($RM_NOBLKRD);
+}
+
+sub cmd_S
+{
+ ReadMode($RM_RESET);
+
+ print RED(), "Seconds for Slow queries: ", RESET();
+ my $secs = ReadLine(0);
+
+ if ($secs =~ /^\s*(\d+)/)
+ {
+ $config{slow} = $1;
+ if ($config{slow} < 1)
+ {
+ $config{slow} = 1;
+ }
+ }
+ ReadMode($RM_NOBLKRD);
+}
+
+sub cmd_q
+{
+ ReadMode($RM_RESET);
+ print "\n";
+ exit;
+}
+
+sub trim($)
+{
+ my $string = shift;
+ $string =~ s/^\s+//;
+ $string =~ s/\s+$//;
+ return $string;
+}
+
+###########################################################################
+
+sub PrintHelp()
+{
+ my $help = qq[
+Help for mytop version $main::VERSION by Mark Grennan <${YELLOW}Mark\@Grennan.com${RESET}>
+Origional work by Jeremy D. Zawodny <${YELLOW}Jeremy\@Zawodny.com${RESET}>
+
+ ? - display this screen
+ # - toggle short/long numbers (not yet implemented)
+ ! - force past replication error
+ c - command summary view (based on Com_* counters)
+ C - turn color on and off
+ d - show only a specific database
+ e - explain the query that a thread is running
+ E - display current replication error
+ f - show full query info for a given thread
+ F - unFilter the dispaly
+ h - show only a specifc host's connections
+ H - toggle the mytop header
+ i - toggle the display of idle (sleeping) threads
+ I - show innodb status
+ k - kill a thread
+ p - pause the display
+ l - change long running queries hightlighing
+ m - switch [mode] to qps (queries/sec) scrolling view
+ M - switch [mode] to status
+ o - reverse the sort order (toggle)
+ q - quit
+ r - reset the status counters (via FLUSH STATUS on your server)
+ R - change reverse IP lookup
+ s - change the delay between screen updates
+ S - change slow quiery hightlighting
+ t - switch to thread view (default)
+ u - show only a specific user
+ V - show variablesi
+ : - enter a command (not yet implemented)
+
+Base version from ${GREEN}http://www.mysqlfanboy.com/mytop${RESET}
+This version comes as part of the ${GREEN}MariaDB${RESET} distribution.
+];
+
+ print $help;
+}
+
+sub Sum(@)
+{
+ my $sum;
+ while (my $val = shift @_) { $sum += $val; }
+ return $sum;
+}
+
+## A useful routine from perlfaq
+
+sub commify($)
+{
+ local $_ = shift;
+ return 0 unless defined $_;
+ 1 while s/^([-+]?\d+)(\d{3})/$1,$2/;
+ return $_;
+}
+
+## Compact numeric representation (10,000 -> 10.0k)
+
+sub make_short($)
+{
+ my $number = shift;
+ return commify($number) if $config{long_nums};
+ my $n = 0;
+ while ($number > 1_025) { $number /= 1024; $n++; };
+ return sprintf "%.1f%s", $number, ('','k','M','G', 'T')[$n];
+}
+
+
+
+## Run a query and return the records has an array of hashes.
+
+sub Hashes($)
+{
+ my $sql = shift;
+ my @records;
+
+ if (my $sth = Execute($sql))
+ {
+ while (my $ref = $sth->fetchrow_hashref)
+ {
+ print "record\n" if $debug;
+ push @records, $ref;
+ }
+ }
+ return @records;
+}
+
+## Execute an SQL query and return the statement handle.
+
+sub Execute($)
+{
+ my $sql = shift;
+ my $sth = $dbh->prepare($sql);
+
+ if (not $sth) { ReadMode($RM_RESET); die $DBI::errstr; }
+
+ my $ReturnCode = $sth->execute;
+
+ if (not $ReturnCode)
+ {
+ if ($debug)
+ {
+ print "query failed\n";
+ sleep 10;
+ }
+ return undef;
+ }
+
+ return $sth;
+}
+
+sub FindProg($)
+{
+ my $prog = shift;
+ my $found = undef;
+ my @search_dirs = ("/bin", "/usr/bin", "/usr/sbin",
+ "/usr/local/bin", "/usr/local/sbin");
+
+ for (@search_dirs)
+ {
+ my $loc = "$_/$prog";
+ if (-e $loc)
+ {
+ $found = $loc;
+ last;
+ }
+ }
+ return $found;
+}
+
+=pod
+
+=head1 SYNOPSIS
+
+B<mytop> [options]
+
+=head1 AVAILABILITY
+
+Base version from B<http://www.mysqlfanboy.com/mytop>.
+
+This version comes as part of the B<MariaDB> distribution. See B<http://mariadb.org/>.
+
+And older (the original) version B<mytop> is available from
+http://jeremy.zawodny.com/mysql/mytop/ it B<might> also be on CPAN as
+well.
+
+=head1 REQUIREMENTS
+
+In order for B<mytop> to function properly, you must have the
+following:
+
+ * Perl 5.005 or newer
+ * Getopt::Long
+ * DBI and DBD::mysql
+ * Term::ReadKey from CPAN
+
+Most systems are likely to have all of those installed--except for
+Term::ReadKey. You will need to pick that up from the CPAN. You can
+pick up Term::ReadKey here:
+
+ http://search.cpan.org/search?dist=TermReadKey
+
+And you obviously need access to a MySQL server (version 3.22.x or
+3.23.x) with the necessary security to run the I<SHOW PROCESSLIST> and
+I<SHOW STATUS> commands.
+
+If you are a Windows user, using ActiveState's Perl, you can use PPM
+(the Perl Package Manager) to install the MySQL and Term::ReadKey
+modules.
+
+=head2 Optional Color Support
+
+In additon, if you want a color B<mytop> (recommended), install
+Term::ANSIColor from the CPAN:
+
+ http://search.cpan.org/search?dist=ANSIColor
+
+Once you do, B<mytop> will automatically use it. However, color is not
+yet working on Windows. Patches welcome. :-)
+
+=head2 Optional Hi-Res Timing
+
+If you want B<mytop> to provide more accurate real-time
+queries-per-second statistics, install the Time::HiRes module from
+CPAN. B<mytop> will automatically notice that you have it and use it
+rather than the standard timing mechanism.
+
+=head2 Platforms
+
+B<mytop> is known to work on:
+
+ * Linux (2.2.x, 2.4.x)
+ * FreeBSD (2.2, 3.x, 4.x)
+ * Mac OS X
+ * BSDI 4.x
+ * Solaris 2.x
+ * Windows NT 4.x (ActivePerl)
+
+If you find that it works on another platform, please let me
+know. Given that it is all Perl code, I expect it to be rather
+portable to Unix and Unix-like systems. Heck, it I<might> even work on
+Win32 systems.
+
+=head1 DESCRIPTION
+
+Help is always welcome in improving this software. Feel free to
+contact the author (see L<"AUTHOR"> below) with bug reports, fixes,
+suggestions, and comments. Additionally L<"BUGS"> will provide a list
+of things this software is not able to do yet.
+
+Having said that, here are the details on how it works and what you can
+do with it.
+
+=head2 The Basics
+
+B<mytop> was inspired by the system monitoring tool B<top>. I
+routinely use B<top> on Linux, FreeBSD, and Solaris. You are likely to
+notice features from each of them here.
+
+B<mytop> will connect to a MySQL server and periodically run the
+I<SHOW PROCESSLIST> and I<SHOW STATUS> commands and attempt to
+summarize the information from them in a useful format.
+
+=head2 The Display
+
+The B<mytop> display screen is really broken into two parts. The top 4
+lines (header) contain summary information about your MySQL
+server. For example, you might see something like:
+
+MySQL on localhost (4.0.13-log) up 1+11:13:00 [23:29:11]
+ Queries: 19.3M qps: 160 Slow: 1.0 Se/In/Up/De(%): 00/80/03/17
+ qps now: 219 Slow qps: 0.0 Threads: 1 ( 1/ 16) 00/74/00/25
+ Key Efficiency: 99.3% Bps in/out: 30.5k/162.8 Now in/out: 32.7k/ 3.3k
+
+The first line identifies the hostname of the server (localhost) and
+the version of MySQL it is running. The right had side shows the
+uptime of the MySQL server process in days+hours:minutes:seconds
+format (much like FreeBSD's top) as well as the current time.
+
+The second line displays the total number of queries the server has
+processed, the average number of queries per second, the number of
+slow queries, and the percentage of Select, Insert, Update, and Delete
+queries.
+
+The third real-time values. First is the number of queries per second,
+then the number of slow queries, followed by query precentages (like
+on the previous line).
+
+And the fourth line displays key buffer efficiency (how often keys are
+read from the buffer rather than disk) and the number of bytes that
+MySQL has sent and received, both over all and in the last cycle.
+
+You can toggle the header by hitting B<h> when running B<mytop>.
+
+The second part of the display lists as many threads as can fit on
+screen. By default they are sorted according to their idle time (least
+idle first). The display looks like:
+
+ Id User Host Dbase Time Cmd Query or State
+ -- ---- ---- ----- ---- --- --------------
+ 61 jzawodn localhost music 0 Query show processlist
+
+As you can see, the thread id, username, host from which the user is
+connecting, database to which the user is connected, number of seconds
+of idle time, the command the thread is executing, and the query info
+are all displayed.
+
+Often times the query info is what you are really interested in, so it
+is good to run B<mytop> in an xterm that is wider than the normal 80
+columns if possible.
+
+The thread display color-codes the threads if you have installed color
+support. The current color scheme only works well in a window with a
+dark (like black) background. The colors are selected according to the
+C<Command> column of the display:
+
+ Query - Yellow
+ Sleep - White
+ Connect - Green
+ Slow - Bright
+ Long - Magenta
+
+Those are purely arbitrary and will be customizable in a future
+release. If they annoy you just start B<mytop> with the B<--nocolor>
+flag or adjust your config file appropriately.
+
+=head2 Arguments
+
+B<mytop> handles long and short command-line arguments. Not all
+options have both long and short formats, however. The long arguments
+have two dashes `--'. Short arguments only have one '-'.
+
+=over
+
+=item B<-u> or B<-user> username
+
+Username to use when logging in to the MySQL server. Default: ``root''.
+
+=item B<-p> or B<-pass> or B<-password> password
+
+Password to use when logging in to the MySQL server. Default: none.
+
+=item B<-h> or B<--host> hostname[:port]
+
+Hostname of the MySQL server. The hostname may be followed by an
+option port number. Note that the port is specified separate from the
+host when using a config file. Default: ``localhost''.
+
+=item B<--port> or B<-P> port
+
+If you're running MySQL on a non-standard port, use this to specify
+the port number. Default: 3306.
+
+=item B<-s> or B<--delay> seconds
+
+How long between display refreshes. Default: 5
+
+=item B<-d> or B<--db> or B<--database> database
+
+Use if you'd like B<mytop> to connect to a specific database by
+default. Default: ``test''.
+
+=item B<-b> or B<--batch> or B<--batchmode>
+
+In batch mode, mytop runs only once, does not clear the screen, and
+places no limit on the number of lines it will print. This is suitable
+for running periodically (perhaps from cron) to capture the
+information into a file for later viewing. You might use batch mode in
+a CGI script to occasionally display your MySQL server status on the
+web.
+
+Default: unset.
+
+=item B<-S> or B<--socket> /path/to/socket
+
+If you're running B<mytop> on the same host as MySQL, you may wish to
+have it use the MySQL socket directly rather than a standard TCP/IP
+connection. If you do,just specify one.
+
+Note that specifying a socket will make B<mytop> ignore any host
+and/or port that you might have specified. If the socket does not
+exist (or the file specified is not a socket), this option will be
+ignored and B<mytop> will use the hostname and port number instead.
+
+Default: none.
+
+=item B<--header> or B<--noheader>
+
+Sepcify if you want the header to display or not. You can toggle this
+with the B<h> key while B<mytop> is running.
+
+Default: header.
+
+=item B<--color> or B<--nocolor>
+
+Specify if you want a color display. This has no effect if you don't
+have color support available.
+
+Default: If you have color support, B<mytop> will try color unless you
+tell it not to.
+
+=item B<-i> or B<--idle> or B<--noi> or B<--noidle>
+
+Specify if you want idle (sleeping) threads to appear in the list. If
+sleeping threads are omitted, the default sorting order is reversed so
+that the longest running queries appear at the top of the list.
+
+Default: idle.
+
+=item B<--prompt> or B<--noprompt>
+
+Specify if you want to be prompted to type in your database password.
+This provides a little bit more security since it not only prevents
+the password from viewable in a process list, but also doesn't require
+the password to be stored in plain text in your ~/.mytop config file.
+You will B<only> be prompted if a password has not been specified in
+your config file or through another command line option.
+
+Default: noprompt.
+
+=item B<--resolve>
+
+If you have skip-resolve set on MySQL (to keep it from doing a reverse
+DNS lookup on each inbound connection), mytop can replace IP addresses
+with hostnames but toggling this option.
+
+Default: noresolve
+
+=back
+
+Command-line arguments will always take precedence over config file
+options. That happens because the config file is read I<BEFORE> the
+command-line arguments are applied.
+
+=head2 Config File
+
+Instead of always using bulky command-line parameters, you can also
+use a config file in your home directory (C<~/.mytop>). If present,
+B<mytop> will read it automatically. It is read I<before> any of your
+command-line arguments are processed, so your command-line arguments
+will override directives in the config file.
+
+Here is a sample config file C<~/.mytop> which implements the defaults
+described above.
+
+ user=root
+ pass=
+ host=localhost
+ db=test
+ delay=5
+ port=3306
+ slow=10
+ socket=
+ batchmode=0
+ header=1
+ color=1
+ idle=1
+ long=120
+
+Using a config file will help to ensure that your database password
+isn't visible to users on the command-line. Just make sure that the
+permissions on C<~/.mytop> are such that others cannot read it (unless
+you want them to, of course).
+
+You may have white space on either side of the C<=> in lines of the
+config file.
+
+=head2 Shortcut Keys
+
+The following keys perform various actions while B<mytop> is
+running. Those which have not been implemented are listed as
+such. They are included to give the user idea of what is coming.
+
+=over
+
+=item B<?>
+
+Display help.
+
+=item B<c>
+
+Show "command counters" based on the Com_* values in SHOW STATUS.
+This is a new feature. Feedback welcome.
+
+=item B<C>
+
+Turn display color on and off. Default is on.
+
+=item B<d>
+
+Show only threads connected to a particular database.
+
+=item B<f>
+
+Given a thread id, display the entire query that thread was (and still
+may be) running.
+
+=item B<F>
+
+Disable all filtering (host, user, and db).
+
+=item B<h>
+
+Only show queries from a particular host.
+
+=item B<H>
+
+Toggle the header display. You can also specify either C<header=0> or
+C<header=1> in your config file to set the default behavior.
+
+=item B<i>
+
+Toggle the display of idle (sleeping) threads. If sleeping threads are
+filtered, the default sorting order is reversed so that the longest
+running queries appear at the top of the list.
+
+=item B<I>
+
+Switch to InnoDB Status mode. The output of "SHOW INNODB STATUS" will
+be displayed every cycle. In a future version, this may actually
+summarize that data rather than producing raw output.
+
+=item B<k>
+
+Kill a thread.
+
+=item B<m>
+
+Toggle modes. Currently this switches from `top' mode to `qps'
+(Queries Per Second Mode). In this mode, mytop will write out one
+integer per second. The number written reflects the number of queries
+executed by the server in the previous one second interval.
+
+More modes may be added in the future.
+
+=item B<o>
+
+Reverse the default sort order.
+
+=item B<p>
+
+Pause display.
+
+=item B<q>
+
+Quit B<mytop>
+
+=item B<r>
+
+Reset the server's status counters via a I<FLUSH STATUS> command.
+
+=item B<R>
+
+Togle IP reverse lookup. Default is on.
+
+=item B<s>
+
+Change the sleep time (number of seconds between display refreshes).
+
+=item B<S>
+
+Set the number of seconds a query will need to run before it is
+considered old and will be highlighted.
+
+=item B<u>
+
+Show only threads owned by a giver user.
+
+=back
+
+The B<s> key has a command-line counterpart: B<-s>.
+
+The B<h> key has two command-line counterparts: B<-header> and
+B<-noheader>.
+
+=head1 BUGS
+
+This is more of a BUGS + WishList.
+
+Some performance information is not available when talking to a
+version 3.22.x MySQL server. Additional information (about threads
+mostly) was added to the output of I<SHOW STATUS> in MySQL 3.23.x and
+B<mytop> makes use of it. If the information is not available, you
+will simply see zeros where the real numbers should be.
+
+Simply running this program will increase your overall counters (such
+as the number of queries run). But you may or may not view that as a
+bug.
+
+B<mytop> consumes too much CPU time when running (verified on older
+versions of Linux and FreeBSD). It's likely a problem related to
+Term::ReadKey. I haven't had time to investigate yet, so B<mytop> now
+automatically lowers its priority when you run it. You may also think
+about running B<mytop> on another workstation instead of your database
+server. However, C<mytop> on Solaris does B<not> have this problem.
+Newer versions of Linux and FreeBSD seem to have fixed this.
+
+You can't specify the maximum number of threads to list. If you have
+many threads and a tall xterm, B<mytop> will always try to display as
+many as it can fit.
+
+The size of most of the columns in the display has a small maximum
+width. If you have fairly long database/user/host names the display
+may appear odd. I have no good idea as to how best to deal with that
+yet. Suggestions are welcome.
+
+It'd be nice if you could just add B<mytop> configuration directives
+in your C<my.cnf> file instead of having a separate config file.
+
+You should be able to specify the columns you'd like to see in the
+display and the order in which they appear. If you only have one
+username that connects to your database, it's probably not worth
+having the User column appear, for example.
+
+=head1 AUTHOR
+
+mytop was developed and is maintained by Jeremy D. Zawodny
+(Jeremy@Zawodny.com).
+
+(Mark Grennan) After weeks and months of trying to get Jeremy's
+attention I desided to release my own update to mytop. I use it
+every day as a part of my job. Thanks Jeremy for creating mytop.
+I hope you find my updates as helpful as I have. I can be
+reached at (Mark@Grennan.com).
+
+=head1 DISCLAIMER
+
+While I use this software in my job at Yahoo!, I am solely responsible
+for it. Yahoo! does not necessarily support this software in any
+way. It is merely a personal idea which happened to be very useful in
+my job.
+
+=head1 RECRUITING
+
+If you hack Perl and grok MySQL, come work at Yahoo! Contact me for
+details. Or just send me your resume. Er, unless we just had layoffs,
+in which case we're not hiring. :-(
+
+=head1 SEE ALSO
+
+Please check the MySQL manual if you're not sure where some of the
+output of B<mytop> is coming from.
+
+=head1 COPYRIGHT
+
+Copyright (C) 2000-2010, Jeremy D. Zawodny.
+Copyright (C) 2010, Mark T. Grennan.
+
+=head1 CREDITS
+
+Fix a bug. Add a feature. See your name here!
+
+Many thanks go to these fine folks:
+
+=over
+
+=item Sami Ahlroos (sami@avis-net.de)
+
+Suggested the idle/noidle stuff.
+
+=item Jan Willamowius (jan@janhh.shnet.org)
+
+Mirnor bug report. Documentation fixes.
+
+=item Alex Osipov (alex@acky.net)
+
+Long command-line options, Unix socket support.
+
+=item Stephane Enten (tuf@grolier.fr)
+
+Suggested batch mode.
+
+=item Richard Ellerbrock (richarde@eskom.co.za)
+
+Bug reports and usability suggestions.
+
+=item William R. Mattil (wrm@newton.irngtx.tel.gte.com)
+
+Bug report about empty passwords not working.
+
+=item Benjamin Pflugmann (philemon@spin.de)
+
+Suggested -P command-line flag as well as other changes.
+
+=item Justin Mecham <justin@aspect.net>
+
+Suggested setting $0 to `mytop'.
+
+=item Thorsten Kunz <thorsten.kunz@de.tiscali.com>
+
+Provided a fix for cases when we try remove the domain name from the
+display even if it is actually an IP address.
+
+=item Sasha Pachev <sasha@mysql.com>
+
+Provided the idea of real-time queries per second in the main display.
+
+=item Paul DuBois <paul@snake.net>
+
+Pointed out some option-handling bugs.
+
+=item Mike Wexler <mwexler@tias.com>
+
+Suggested that we don't mangle (normalize) whitespace in query info by
+default.
+
+=item Mark Zweifel <markez@yahoo-inc.com>
+
+Make the --idle command-line argument negatable.
+
+=item Axel Schwenke <schwenke@jobpilot.de>
+
+Noticed the inccorect formula for query cache hit percentages in
+version 1.2.
+
+=item Steven Roussey <sroussey@network54.com>
+
+Supplied a patch to help filter binary junk in queries so that
+terminals don't freak out.
+
+=item jon r. luini <falcon@chime.com>
+
+Supplied a patch that formed the basis for C<-prompt> support. Sean
+Leach <sleach@wiggum.com> submitted a similar patch.
+
+=item Yogish Baliga <baliga@yahoo-inc.com>
+
+Supplied a patch that formed the basis for C<-resolve> support.
+
+=item Per Andreas Buer <perbu@linpro.no>
+
+Supplied an excellent patch to tidy up the top display. This includes
+showing most values in short form, such as 10k rather than 10000.
+
+=item Michael "Monty" Widenius <monty@askmonty.org>
+
+Fixed a couple of minor bugs that gave warnings on startup.
+Added support for MariaDB (show MariaDB at top and % done).
+Cut long server version names to display width.
+Made 'State' length dynamic.
+
+=back
+
+See the Changes file on the B<mytop> distribution page for more
+details on what has changed.
+
+=head1 LICENSE
+
+B<mytop> is licensed under the GNU General Public License version
+2. For the full license information, please visit
+http://www.gnu.org/copyleft/gpl.html
+
+=cut
+
+__END__
diff --git a/sql-bench/crash-me.sh b/sql-bench/crash-me.sh
index cc8659513c2..b6aabfbed87 100644
--- a/sql-bench/crash-me.sh
+++ b/sql-bench/crash-me.sh
@@ -39,7 +39,7 @@
# as such, and clarify ones such as "mediumint" with comments such as
# "3-byte int" or "same as xxx".
-$version="1.61";
+$version="1.62";
use Cwd;
use DBI;
@@ -619,6 +619,8 @@ check_reserved_words($dbh);
"numeric(9,2)","decimal(6,2)","dec(6,2)",
"bit", "bit(2)","bit varying(2)","float","float(8)","real",
"double precision", "date","time","timestamp",
+ "time(6)", "timestamp(6)",
+ "datetime", "datetime(6)",
"interval year", "interval year to month",
"interval month",
"interval day", "interval day to hour", "interval day to minute",
@@ -632,8 +634,7 @@ check_reserved_words($dbh);
"national char varying(20)","nchar varying(20)",
"national character varying(20)",
"timestamp with time zone");
-@odbc_types=("binary(1)","varbinary(1)","tinyint","bigint",
- "datetime");
+@odbc_types=("binary(1)","varbinary(1)","tinyint","bigint");
@extra_types=("blob","byte","long varbinary","image","text","text(10)",
"mediumtext",
"long varchar(1)", "varchar2(257)",
@@ -663,7 +664,7 @@ check_reserved_words($dbh);
foreach $types (@types)
{
print "\nSupported $types->[0] types\n";
- $tmp=@$types->[1];
+ $tmp= $types->[1];
foreach $use_type (@$tmp)
{
$type=$use_type;
@@ -746,10 +747,14 @@ if (($limits{'type_extra_float(2_arg)'} eq "yes" ||
$result="exact";
}
$prompt="Storage of float values";
- print "$prompt: $result\n";
save_config_data("storage_of_float", $result, $prompt);
}
+if (defined($limits{'storage_of_float'}))
+{
+ print "Storage of float values: $limits{'storage_of_float'}\n";
+}
+
try_and_report("Type for row id", "rowid",
["rowid",
"create table crash_q (a rowid)",
@@ -1061,7 +1066,7 @@ try_and_report("Automatic row id", "automatic_rowid",
foreach $types (@types)
{
print "\nSupported $types->[0] functions\n";
- $tmp=@$types->[1];
+ $tmp= $types->[1];
foreach $type (@$tmp)
{
if (defined($limits{"func_$types->[0]_$type->[1]"}))
@@ -1136,7 +1141,7 @@ if ($limits{'functions'} eq 'yes')
foreach $types (@group_types)
{
print "\nSupported $types->[0] group functions\n";
- $tmp=@$types->[1];
+ $tmp= $types->[1];
foreach $type (@$tmp)
{
check_and_report("Group function $type->[0]",
@@ -3132,8 +3137,11 @@ $0 takes the following options:
Wait this long before restarting server.
--verbose
---noverbose
Log into the result file queries performed for determination parameter value
+ This causes rows starting with ' ###' to be logged into the .cnf file
+
+--noverbose
+ Don't log '###' quries to the .cnf file.
EOF
exit(0);
@@ -4349,7 +4357,7 @@ sub save_config_data
my $last_line_was_empty=0;
foreach $line (split /\n/, $log{$key})
{
- print CONFIG_FILE " ###$line\n"
+ print CONFIG_FILE "$log_prefix$line\n"
unless ( ($last_line_was_empty eq 1)
&& ($line =~ /^\s+$/) );
$last_line_was_empty= ($line =~ /^\s+$/)?1:0;
@@ -4369,7 +4377,7 @@ sub add_log
{
my $key = shift;
my $line = shift;
- $log{$key} .= $line . "\n" if ($opt_verbose);;
+ $log{$key} .= $line . "\n" if ($opt_verbose);
}
sub save_all_config_data
@@ -4391,14 +4399,17 @@ sub save_all_config_data
$tmp="$key=$limits{$key}";
print CONFIG_FILE $tmp . ("\t" x (int((32-min(length($tmp),32)+7)/8)+1)) .
"# $prompts{$key}\n";
- my $line;
- my $last_line_was_empty=0;
- foreach $line (split /\n/, $log{$key})
- {
- print CONFIG_FILE " ###$line\n" unless
- ( ($last_line_was_empty eq 1) && ($line =~ /^\s*$/));
+ if ($opt_verbose)
+ {
+ my $line;
+ my $last_line_was_empty=0;
+ foreach $line (split /\n/, $log{$key})
+ {
+ print CONFIG_FILE "$log_prefix$line\n" unless
+ ( ($last_line_was_empty eq 1) && ($line =~ /^\s*$/));
$last_line_was_empty= ($line =~ /^\s*$/)?1:0;
- };
+ }
+ }
}
close CONFIG_FILE;
}
diff --git a/sql-bench/limits/mysql.cfg b/sql-bench/limits/mysql.cfg
index 76565cb16ff..1194898481d 100644
--- a/sql-bench/limits/mysql.cfg
+++ b/sql-bench/limits/mysql.cfg
@@ -1,4 +1,4 @@
-#This file is automaticly generated by crash-me 1.61
+#This file is automaticly generated by crash-me 1.62
NEG=yes # update of column= -column
Need_cast_for_null=no # Need to cast NULL for arithmetic
@@ -31,7 +31,7 @@ comment_--=yes # -- as comment (ANSI)
comment_/**/=yes # /* */ as comment
comment_//=no # // as comment
compute=no # Compute
-connections=101 # Simultaneous connections (installation default)
+connections=152 # Simultaneous connections (installation default)
constraint_check=syntax only # Column constraints
constraint_check_named=syntax only # Named constraints
constraint_check_table=syntax only # Table constraints
@@ -387,17 +387,17 @@ max_char_size=255 # max char() size
max_column_name=64 # column name length
max_columns=2599 # Columns in table
max_conditions=85660 # OR and AND in WHERE
-max_expressions=580 # simple expressions
+max_expressions=571 # simple expressions
max_index=+64 # max index
max_index_length=1000 # index length
max_index_name=64 # index name length
max_index_part_length=255 # max index part length
-max_index_parts=16 # index parts
+max_index_parts=32 # index parts
max_index_varchar_part_length=1000 # index varchar part length
max_row_length=65534 # max table row length (without blobs)
max_row_length_with_null=65502 # table row length with nulls (without blobs)
max_select_alias_name=+512 # select alias name length
-max_stack_expression=580 # stacked expressions
+max_stack_expression=571 # stacked expressions
max_table_alias_name=+512 # table alias name length
max_table_name=64 # table name length
max_text_size=1048543 # max text or blob size
@@ -422,7 +422,7 @@ null_in_unique=yes # null in unique index
null_num_expr=yes # Is 1+NULL = NULL
nulls_in_unique=yes # null combination in unique index
odbc_left_outer_join=yes # left outer join odbc style
-operating_system=Linux 2.6.8-my i686 # crash-me tested on
+operating_system=Linux 2.6.37.6-0.7-desktop x86_64 # crash-me tested on
order_by=yes # Order by
order_by_alias=yes # Order by alias
order_by_function=yes # Order by function
@@ -433,7 +433,7 @@ position_of_null_desc=last # Where is null values in sorted recordset (DESC)
primary_key_in_create=yes # primary key in create table
psm_functions=no # PSM functions (ANSI SQL)
psm_modules=no # PSM modules (ANSI SQL)
-psm_procedures=no # PSM procedures (ANSI SQL)
+psm_procedures=yes # PSM procedures (ANSI SQL)
psm_trigger=no # Triggers (ANSI SQL)
query_size=1048574 # query size
quote_ident_with_"=error # " as identifier quote (ANSI SQL)
@@ -485,7 +485,7 @@ reserved_word_ansi-92/99_column=yes # Keyword COLUMN
reserved_word_ansi-92/99_commit=no # Keyword COMMIT
reserved_word_ansi-92/99_completion=no # Keyword COMPLETION
reserved_word_ansi-92/99_connect=no # Keyword CONNECT
-reserved_word_ansi-92/99_connection=yes # Keyword CONNECTION
+reserved_word_ansi-92/99_connection=no # Keyword CONNECTION
reserved_word_ansi-92/99_constraint=yes # Keyword CONSTRAINT
reserved_word_ansi-92/99_constraints=no # Keyword CONSTRAINTS
reserved_word_ansi-92/99_continue=yes # Keyword CONTINUE
@@ -546,7 +546,7 @@ reserved_word_ansi-92/99_general=no # Keyword GENERAL
reserved_word_ansi-92/99_get=no # Keyword GET
reserved_word_ansi-92/99_global=no # Keyword GLOBAL
reserved_word_ansi-92/99_go=no # Keyword GO
-reserved_word_ansi-92/99_goto=yes # Keyword GOTO
+reserved_word_ansi-92/99_goto=no # Keyword GOTO
reserved_word_ansi-92/99_grant=yes # Keyword GRANT
reserved_word_ansi-92/99_group=yes # Keyword GROUP
reserved_word_ansi-92/99_having=yes # Keyword HAVING
@@ -933,7 +933,7 @@ reserved_word_extra_setuser=no # Keyword SETUSER
reserved_word_extra_share=no # Keyword SHARE
reserved_word_extra_show=yes # Keyword SHOW
reserved_word_extra_shutdown=no # Keyword SHUTDOWN
-reserved_word_extra_soname=yes # Keyword SONAME
+reserved_word_extra_soname=no # Keyword SONAME
reserved_word_extra_spatial=yes # Keyword SPATIAL
reserved_word_extra_sql_big_result=yes # Keyword SQL_BIG_RESULT
reserved_word_extra_sql_calc_found_rows=yes # Keyword SQL_CALC_FOUND_ROWS
@@ -983,7 +983,7 @@ select_limit3=yes # SELECT with LIMIT # OFFSET #
select_string_size=1048565 # constant string size in SELECT
select_table_update=yes # Update with sub select
select_without_from=yes # SELECT without FROM
-server_version=MySQL 5.0.7 beta valgrind max debug/ # server version
+server_version=MySQL 5.3.1 MariaDB beta valgrind max debug # server version
simple_joins=yes # ANSI SQL simple joins
sorted_group_by=yes # Group by always sorted
storage_of_float=round # Storage of float values
@@ -1063,7 +1063,6 @@ type_extra_varchar2(1_arg)=no # Type varchar2(1 arg)
type_extra_year=yes # Type year
type_odbc_bigint=yes # Type bigint
type_odbc_binary(1_arg)=yes # Type binary(1 arg)
-type_odbc_datetime=yes # Type datetime
type_odbc_tinyint=yes # Type tinyint
type_odbc_varbinary(1_arg)=yes # Type varbinary(1 arg)
type_sql_bit=yes # Type bit
@@ -1075,6 +1074,8 @@ type_sql_char_varying(1_arg)=yes # Type char varying(1 arg)
type_sql_character(1_arg)=yes # Type character(1 arg)
type_sql_character_varying(1_arg)=yes # Type character varying(1 arg)
type_sql_date=yes # Type date
+type_sql_datetime=yes # Type datetime
+type_sql_datetime(1_arg)=yes # Type datetime(1 arg)
type_sql_dec(2_arg)=yes # Type dec(2 arg)
type_sql_decimal(2_arg)=yes # Type decimal(2 arg)
type_sql_double_precision=yes # Type double precision
@@ -1104,7 +1105,9 @@ type_sql_numeric(2_arg)=yes # Type numeric(2 arg)
type_sql_real=yes # Type real
type_sql_smallint=yes # Type smallint
type_sql_time=yes # Type time
+type_sql_time(1_arg)=yes # Type time(1 arg)
type_sql_timestamp=yes # Type timestamp
+type_sql_timestamp(1_arg)=yes # Type timestamp(1 arg)
type_sql_timestamp_with_time_zone=no # Type timestamp with time zone
type_sql_varchar(1_arg)=yes # Type varchar(1 arg)
union=yes # union
diff --git a/sql-common/client.c b/sql-common/client.c
index 28b3cf274bc..902bd658ee7 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -125,6 +125,7 @@ const char *def_shared_memory_base_name= default_shared_memory_base_name;
static void mysql_close_free_options(MYSQL *mysql);
static void mysql_close_free(MYSQL *mysql);
static void mysql_prune_stmt_list(MYSQL *mysql);
+static int cli_report_progress(MYSQL *mysql, uchar *packet, uint length);
#if !(defined(__WIN__) || defined(__NETWARE__))
static int wait_for_data(my_socket fd, uint timeout);
@@ -689,6 +690,7 @@ cli_safe_read(MYSQL *mysql)
ulong len=0;
init_sigpipe_variables
+restart:
/* Don't give sigpipe errors if the client doesn't want them */
set_sigpipe(mysql);
if (net->vio != 0)
@@ -712,13 +714,27 @@ cli_safe_read(MYSQL *mysql)
{
if (len > 3)
{
- char *pos=(char*) net->read_pos+1;
- net->last_errno=uint2korr(pos);
+ uchar *pos= net->read_pos+1;
+ uint last_errno=uint2korr(pos);
+
+ if (last_errno == 65535 &&
+ (mysql->server_capabilities & CLIENT_PROGRESS))
+ {
+ if (cli_report_progress(mysql, pos+2, (uint) (len-3)))
+ {
+ /* Wrong packet */
+ set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate);
+ return (packet_error);
+ }
+ goto restart;
+ }
+ net->last_errno= last_errno;
+
pos+=2;
len-=2;
- if (protocol_41(mysql) && pos[0] == '#')
+ if (protocol_41(mysql) && (char) pos[0] == '#')
{
- strmake(net->sqlstate, pos+1, SQLSTATE_LENGTH);
+ strmake(net->sqlstate, (char*) pos+1, SQLSTATE_LENGTH);
pos+= SQLSTATE_LENGTH+1;
}
else
@@ -875,6 +891,40 @@ static void cli_flush_use_result(MYSQL *mysql)
}
+/*
+ Report progress to the client
+
+ RETURN VALUES
+ 0 ok
+ 1 error
+*/
+
+static int cli_report_progress(MYSQL *mysql, uchar *packet, uint length)
+{
+ uint stage, max_stage, proc_length;
+ double progress;
+ uchar *start= packet;
+
+ if (length < 5)
+ return 1; /* Wrong packet */
+
+ if (!(mysql->options.extension && mysql->options.extension->report_progress))
+ return 0; /* No callback, ignore packet */
+
+ packet++; /* Ignore number of strings */
+ stage= (uint) *packet++;
+ max_stage= (uint) *packet++;
+ progress= uint3korr(packet)/1000.0;
+ packet+= 3;
+ proc_length= net_field_length(&packet);
+ if (packet + proc_length > start + length)
+ return 1; /* Wrong packet */
+ (*mysql->options.extension->report_progress)(mysql, stage, max_stage,
+ progress, (char*) packet,
+ proc_length);
+ return 0;
+}
+
#ifdef __WIN__
static my_bool is_NT(void)
{
@@ -883,57 +933,6 @@ static my_bool is_NT(void)
}
#endif
-
-#ifdef CHECK_LICENSE
-/**
- Check server side variable 'license'.
-
- If the variable does not exist or does not contain 'Commercial',
- we're talking to non-commercial server from commercial client.
-
- @retval 0 success
- @retval !0 network error or the server is not commercial.
- Error code is saved in mysql->net.last_errno.
-*/
-
-static int check_license(MYSQL *mysql)
-{
- MYSQL_ROW row;
- MYSQL_RES *res;
- NET *net= &mysql->net;
- static const char query[]= "SELECT @@license";
- static const char required_license[]= STRINGIFY_ARG(LICENSE);
-
- if (mysql_real_query(mysql, query, sizeof(query)-1))
- {
- if (net->last_errno == ER_UNKNOWN_SYSTEM_VARIABLE)
- {
- set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
- ER(CR_WRONG_LICENSE), required_license);
- }
- return 1;
- }
- if (!(res= mysql_use_result(mysql)))
- return 1;
- row= mysql_fetch_row(res);
- /*
- If no rows in result set, or column value is NULL (none of these
- two is ever true for server variables now), or column value
- mismatch, set wrong license error.
- */
- if (!net->last_errno &&
- (!row || !row[0] ||
- strncmp(row[0], required_license, sizeof(required_license))))
- {
- set_mysql_extended_error(mysql, CR_WRONG_LICENSE, unknown_sqlstate,
- ER(CR_WRONG_LICENSE), required_license);
- }
- mysql_free_result(res);
- return net->last_errno;
-}
-#endif /* CHECK_LICENSE */
-
-
/**************************************************************************
Shut down connection
**************************************************************************/
@@ -1050,14 +1049,17 @@ static int add_init_command(struct st_mysql_options *options, const char *cmd)
return 0;
}
-#define extension_set_string(OPTS, X, STR) \
- if ((OPTS)->extension) \
- my_free((OPTS)->extension->X, MYF(MY_ALLOW_ZERO_PTR)); \
- else \
+#define extension_set(OPTS, X, VAL) \
+ if (!(OPTS)->extension) \
(OPTS)->extension= (struct st_mysql_options_extention *) \
my_malloc(sizeof(struct st_mysql_options_extention), \
MYF(MY_WME | MY_ZEROFILL)); \
- (OPTS)->extension->X= my_strdup((STR), MYF(MY_WME));
+ (OPTS)->extension->X= VAL;
+
+#define extension_set_string(OPTS, X, STR) \
+ if ((OPTS)->extension) \
+ my_free((OPTS)->extension->X, MYF(MY_ALLOW_ZERO_PTR)); \
+ extension_set(OPTS, X, my_strdup((STR), MYF(MY_WME)));
void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group)
@@ -2977,11 +2979,6 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
if (mysql->client_flag & CLIENT_COMPRESS) /* We will use compression */
net->compress=1;
-#ifdef CHECK_LICENSE
- if (check_license(mysql))
- goto error;
-#endif
-
if (db && !mysql->db && mysql_select_db(mysql, db))
{
if (mysql->net.last_errno == CR_SERVER_LOST)
@@ -3737,6 +3734,15 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
case MYSQL_DEFAULT_AUTH:
extension_set_string(&mysql->options, default_auth, arg);
break;
+ case MYSQL_PROGRESS_CALLBACK:
+ if (!mysql->options.extension)
+ mysql->options.extension= (struct st_mysql_options_extention *)
+ my_malloc(sizeof(struct st_mysql_options_extention),
+ MYF(MY_WME | MY_ZEROFILL));
+ if (mysql->options.extension)
+ mysql->options.extension->report_progress=
+ (void (*)(const MYSQL *, uint, uint, double, const char *, uint)) arg;
+ break;
default:
DBUG_RETURN(1);
}
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 96c3643ccbc..599914a8f8f 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -37,7 +37,9 @@ SET_SOURCE_FILES_PROPERTIES(${CMAKE_BINARY_DIR}/sql/sql_yacc.h
PROPERTIES GENERATED 1)
ADD_DEFINITIONS(-DMYSQL_SERVER -D_CONSOLE -DHAVE_DLOPEN -DHAVE_EVENT_SCHEDULER)
-
+IF(WITH_FEEDBACK_STORAGE_ENGINE)
+ ADD_DEFINITIONS(-DWITH_FEEDBACK_PLUGIN)
+ENDIF()
SET (SQL_SOURCE
../sql-common/client.c derror.cc des_key_file.cc
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index 322db38adf2..5e5e5a72850 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -1078,7 +1078,7 @@ static bool debug_sync_set_action(THD *thd, st_debug_sync_action *action)
point decremented it to 0. In this case the following happened:
- an error message was reported with my_error() and
- - the statement was killed with thd->killed= THD::KILL_QUERY.
+ - the statement was killed with thd->killed= KILL_QUERY.
If a statement reports an error, it must not call send_ok().
The calling functions will not call send_ok(), if we return TRUE
@@ -1852,7 +1852,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action)
{
if (!--action->hit_limit)
{
- thd->killed= THD::KILL_QUERY;
+ thd->killed= KILL_QUERY;
my_error(ER_DEBUG_SYNC_HIT_LIMIT, MYF(0));
}
DBUG_PRINT("debug_sync_exec", ("hit_limit: %lu at: '%s'",
diff --git a/sql/discover.cc b/sql/discover.cc
index 56dc00cc5c4..92af5d56016 100644
--- a/sql/discover.cc
+++ b/sql/discover.cc
@@ -67,7 +67,7 @@ int readfrm(const char *name, uchar **frmdata, size_t *len)
error= 2;
if (my_fstat(file, &state, MYF(0)))
goto err;
- read_len= state.st_size;
+ read_len= (size_t)state.st_size;
// Read whole frm file
error= 3;
diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc
index ecddcb7ca46..240d2df8e65 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -642,7 +642,7 @@ Event_scheduler::stop()
sql_print_information("Event Scheduler: Killing the scheduler thread, "
"thread id %lu",
scheduler_thd->thread_id);
- scheduler_thd->awake(THD::KILL_CONNECTION);
+ scheduler_thd->awake(KILL_CONNECTION);
pthread_mutex_unlock(&scheduler_thd->LOCK_thd_data);
/* thd could be 0x0, when shutting down */
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index afc4d8252ff..588a99f560f 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -204,6 +204,14 @@ static void do_skip(Copy_field *copy __attribute__((unused)))
}
+/*
+ Copy: (NULLable field) -> (NULLable field)
+
+ note: if the record we're copying from is NULL-complemetned (i.e.
+ from_field->table->null_row==1), it will also have all NULLable columns to be
+ set to NULLs, so we dont need to check table->null_row here.
+*/
+
static void do_copy_null(Copy_field *copy)
{
if (*copy->from_null_ptr & copy->from_bit)
@@ -218,6 +226,10 @@ static void do_copy_null(Copy_field *copy)
}
}
+/*
+ Copy: (not-NULL field in table that can be NULL-complemented) -> (NULLable
+ field)
+*/
static void do_outer_field_null(Copy_field *copy)
{
@@ -235,6 +247,7 @@ static void do_outer_field_null(Copy_field *copy)
}
+/* Copy: (NULL-able field) -> (not NULL-able field) */
static void do_copy_not_null(Copy_field *copy)
{
if (*copy->from_null_ptr & copy->from_bit)
@@ -248,6 +261,7 @@ static void do_copy_not_null(Copy_field *copy)
}
+/* Copy: (non-NULLable field) -> (NULLable field) */
static void do_copy_maybe_null(Copy_field *copy)
{
*copy->to_null_ptr&= ~copy->to_bit;
diff --git a/sql/filesort.cc b/sql/filesort.cc
index 559f4f1dcf6..15020b56e52 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -506,7 +506,7 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
my_off_t record;
TABLE *sort_form;
THD *thd= current_thd;
- volatile THD::killed_state *killed= &thd->killed;
+ volatile killed_state *killed= &thd->killed;
handler *file;
MY_BITMAP *save_read_set, *save_write_set, *save_vcol_set;
DBUG_ENTER("find_all_keys");
@@ -546,12 +546,11 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
/* Temporary set for register_used_fields and register_field_in_read_map */
sort_form->read_set= &sort_form->tmp_set;
register_used_fields(param);
- if (select && select->cond)
- select->cond->walk(&Item::register_field_in_read_map, 1,
- (uchar*) sort_form);
- if (select && select->pre_idx_push_select_cond)
- select->pre_idx_push_select_cond->walk(&Item::register_field_in_read_map,
- 1, (uchar*) sort_form);
+ Item *sort_cond= !select ?
+ 0 : !select->pre_idx_push_select_cond ?
+ select->cond : select->pre_idx_push_select_cond;
+ if (sort_cond)
+ sort_cond->walk(&Item::register_field_in_read_map, 1, (uchar*) sort_form);
sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set,
&sort_form->tmp_set);
@@ -624,15 +623,21 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
SQL_SELECT::skip_record evaluates this condition. it may include a
correlated subquery predicate, such that some field in the subquery
refers to 'sort_form'.
+
+ PSergey-todo: discuss the above with Timour.
*/
+ MY_BITMAP *tmp_read_set= sort_form->read_set;
+ MY_BITMAP *tmp_write_set= sort_form->write_set;
+ MY_BITMAP *tmp_vcol_set= sort_form->vcol_set;
+
if (select->cond->with_subselect)
sort_form->column_bitmaps_set(save_read_set, save_write_set,
save_vcol_set);
write_record= (select->skip_record(thd) > 0);
if (select->cond->with_subselect)
- sort_form->column_bitmaps_set(&sort_form->tmp_set,
- &sort_form->tmp_set,
- &sort_form->tmp_set);
+ sort_form->column_bitmaps_set(tmp_read_set,
+ tmp_write_set,
+ tmp_vcol_set);
}
else
write_record= true;
@@ -1233,9 +1238,9 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
void *first_cmp_arg;
element_count dupl_count= 0;
uchar *src;
- THD::killed_state not_killable;
+ killed_state not_killable;
uchar *unique_buff= param->unique_buff;
- volatile THD::killed_state *killed= &current_thd->killed;
+ volatile killed_state *killed= &current_thd->killed;
DBUG_ENTER("merge_buffers");
status_var_increment(current_thd->status_var.filesort_merge_passes);
@@ -1243,7 +1248,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
if (param->not_killable)
{
killed= &not_killable;
- not_killable= THD::NOT_KILLED;
+ not_killable= NOT_KILLED;
}
error=0;
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 77851119e34..5a3365b29d2 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -1855,7 +1855,7 @@ static void ndb_binlog_query(THD *thd, Cluster_schema *schema)
else
thd->server_id= schema->any_value;
thd->db= schema->db;
- int errcode = query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode = query_error_code(thd, thd->killed == NOT_KILLED);
thd->binlog_query(THD::STMT_QUERY_TYPE, schema->query,
schema->query_length, FALSE,
schema->name[0] == 0 || thd->db[0] == 0,
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 6a72623ce5d..eabb10a0d5a 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1301,7 +1301,7 @@ int ha_partition::prepare_new_partition(TABLE *tbl,
DBUG_RETURN(0);
error_external_lock:
- VOID(file->close());
+ VOID(file->ha_close());
error_open:
VOID(file->ha_delete_table(part_name));
error_create:
@@ -1347,7 +1347,7 @@ void ha_partition::cleanup_new_partition(uint part_count)
while ((part_count > 0) && (*file))
{
(*file)->ha_external_lock(thd, F_UNLCK);
- (*file)->close();
+ (*file)->ha_close();
/* Leave the (*file)->ha_delete_table(part_name) to the ddl-log */
@@ -2448,7 +2448,7 @@ bool ha_partition::read_par_file(const char *name)
fn_format(buff, name, "", ha_par_ext, MY_APPEND_EXT);
/* Following could be done with my_stat to read in whole file */
- if ((file= my_open(buff, O_RDONLY | O_SHARE, MYF(0))) < 0)
+ if ((file= my_open(buff, O_RDONLY | O_SHARE, MYF(MY_WME))) < 0)
DBUG_RETURN(true);
if (my_read(file, (uchar *) & buff[0], PAR_WORD_SIZE, MYF(MY_NABP)))
goto err1;
@@ -2842,7 +2842,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
err_handler:
DEBUG_SYNC(ha_thd(), "partition_open_error");
while (file-- != m_file)
- (*file)->close();
+ (*file)->ha_close();
err_alloc:
bitmap_free(&m_bulk_insert_started);
if (!m_is_clone_of)
@@ -2928,7 +2928,7 @@ int ha_partition::close(void)
repeat:
do
{
- (*file)->close();
+ (*file)->ha_close();
} while (*(++file));
if (first && m_added_file && m_added_file[0])
diff --git a/sql/handler.cc b/sql/handler.cc
index 318e2e116e2..6c5d3a580ec 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1403,9 +1403,13 @@ int ha_rollback_trans(THD *thd, bool all)
slave SQL thread, it would not stop the thread but just be printed in
the error log; but we don't want users to wonder why they have this
message in the error log, so we don't send it.
+
+ We don't have to test for thd->killed == KILL_SYSTEM_THREAD as
+ it doesn't matter if a warning is pushed to a system thread or not:
+ No one will see it...
*/
if (is_real_trans && thd->transaction.all.modified_non_trans_table &&
- !thd->slave_thread && thd->killed != THD::KILL_CONNECTION)
+ !thd->slave_thread && thd->killed < KILL_CONNECTION)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
@@ -2168,7 +2172,7 @@ THD *handler::ha_thd(void) const
Don't wait for locks if not HA_OPEN_WAIT_IF_LOCKED is set
*/
int handler::ha_open(TABLE *table_arg, const char *name, int mode,
- int test_if_locked)
+ uint test_if_locked)
{
int error;
DBUG_ENTER("handler::ha_open");
@@ -2212,11 +2216,22 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
dup_ref=ref+ALIGN_SIZE(ref_length);
cached_table_flags= table_flags();
}
- rows_read= rows_changed= 0;
- memset(index_rows_read, 0, sizeof(index_rows_read));
+ reset_statistics();
+ internal_tmp_table= test(test_if_locked & HA_OPEN_INTERNAL_TABLE);
DBUG_RETURN(error);
}
+int handler::ha_close()
+{
+ DBUG_ENTER("ha_close");
+ /*
+ Increment global statistics for temporary tables.
+ In_use is 0 for tables that was closed from the table cache.
+ */
+ if (table->in_use)
+ status_var_add(table->in_use->status_var.rows_tmp_read, rows_tmp_read);
+ DBUG_RETURN(close());
+}
/* Initialize handler for random reading, with error handling */
@@ -2548,7 +2563,7 @@ int handler::update_auto_increment()
/*
first test if the query was aborted due to strict mode constraints
*/
- if (thd->killed == THD::KILL_BAD_DATA)
+ if (killed_mask_hard(thd->killed) == KILL_BAD_DATA)
DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
/*
@@ -3238,7 +3253,7 @@ int handler::rename_table(const char * from, const char * to)
void handler::drop_table(const char *name)
{
- close();
+ ha_close();
delete_table(name);
}
@@ -3757,6 +3772,7 @@ void handler::update_global_table_stats()
TABLE_STATS * table_stats;
status_var_add(table->in_use->status_var.rows_read, rows_read);
+ DBUG_ASSERT(rows_tmp_read == 0);
if (!table->in_use->userstat_running)
{
@@ -4704,7 +4720,7 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table)
/** @brief
Write table maps for all (manually or automatically) locked tables
- to the binary log. Also, if binlog_annotate_rows_events is ON,
+ to the binary log. Also, if binlog_annotate_row_events is ON,
write Annotate_rows event before the first table map.
SYNOPSIS
@@ -4742,7 +4758,7 @@ static int write_locked_table_maps(THD *thd)
locks[0]= thd->extra_lock;
locks[1]= thd->lock;
locks[2]= thd->locked_tables;
- my_bool with_annotate= thd->variables.binlog_annotate_rows_events &&
+ my_bool with_annotate= thd->variables.binlog_annotate_row_events &&
thd->query() && thd->query_length();
for (uint i= 0 ; i < sizeof(locks)/sizeof(*locks) ; ++i )
@@ -4862,6 +4878,9 @@ int handler::ha_reset()
/* reset the bitmaps to point to defaults */
table->default_column_bitmaps();
pushed_cond= NULL;
+ /* Reset information about pushed engine conditions */
+ cancel_pushed_idx_cond();
+ /* Reset information about pushed index conditions */
DBUG_RETURN(reset());
}
diff --git a/sql/handler.h b/sql/handler.h
index 4707aabbd52..66320c7e98f 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1,4 +1,5 @@
/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+ Copyright 2009-2011 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
@@ -1389,10 +1390,14 @@ public:
}
void add_io(double add_io_cnt, double add_avg_cost)
{
- double io_count_sum= io_count + add_io_cnt;
- avg_io_cost= (io_count * avg_io_cost +
- add_io_cnt * add_avg_cost) / io_count_sum;
- io_count= io_count_sum;
+ /* In edge cases add_io_cnt may be zero */
+ if (add_io_cnt > 0)
+ {
+ double io_count_sum= io_count + add_io_cnt;
+ avg_io_cost= (io_count * avg_io_cost +
+ add_io_cnt * add_avg_cost) / io_count_sum;
+ io_count= io_count_sum;
+ }
}
/*
@@ -1599,6 +1604,7 @@ public:
KEY_PART_INFO *range_key_part;
int key_compare_result_on_equal;
bool eq_range;
+ bool internal_tmp_table; /* If internal tmp table */
/*
TRUE <=> the engine guarantees that returned records are within the range
@@ -1643,6 +1649,7 @@ public:
*/
/* Statistics variables */
ulonglong rows_read;
+ ulonglong rows_tmp_read;
ulonglong rows_changed;
/* One bigger than needed to avoid to test if key == MAX_KEY */
ulonglong index_rows_read[MAX_KEY+1];
@@ -1659,7 +1666,7 @@ public:
handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
:table_share(share_arg), table(0),
estimation_rows_to_insert(0), ht(ht_arg),
- ref(0), in_range_check_pushed_down(FALSE),
+ ref(0), end_range(NULL), in_range_check_pushed_down(FALSE),
key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
ref_length(sizeof(my_off_t)),
ft_handler(0), inited(NONE),
@@ -1685,7 +1692,7 @@ public:
}
/* ha_ methods: pubilc wrappers for private virtual API */
- int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
+ int ha_open(TABLE *table, const char *name, int mode, uint test_if_locked);
int ha_index_init(uint idx, bool sorted)
{
int result;
@@ -1716,6 +1723,7 @@ public:
DBUG_ENTER("ha_rnd_init");
DBUG_ASSERT(inited==NONE || (inited==RND && scan));
inited= (result= rnd_init(scan)) ? NONE: RND;
+ end_range= NULL;
DBUG_RETURN(result);
}
int ha_rnd_end()
@@ -1723,6 +1731,7 @@ public:
DBUG_ENTER("ha_rnd_end");
DBUG_ASSERT(inited==RND);
inited=NONE;
+ end_range= NULL;
DBUG_RETURN(rnd_end());
}
int ha_rnd_init_with_error(bool scan) __attribute__ ((warn_unused_result));
@@ -1809,7 +1818,7 @@ public:
uint get_dup_key(int error);
void reset_statistics()
{
- rows_read= rows_changed= 0;
+ rows_read= rows_changed= rows_tmp_read= 0;
bzero(index_rows_read, sizeof(index_rows_read));
}
virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
@@ -1894,7 +1903,7 @@ public:
*/
uint get_index(void) const
{ return inited == INDEX ? active_index : MAX_KEY; }
- virtual int close(void)=0;
+ int ha_close(void);
/**
@retval 0 Bulk update used by handler
@@ -1970,10 +1979,18 @@ protected:
virtual int index_last(uchar * buf)
{ return HA_ERR_WRONG_COMMAND; }
virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
+ virtual int close(void)=0;
+ inline void update_rows_read()
+ {
+ if (likely(!internal_tmp_table))
+ rows_read++;
+ else
+ rows_tmp_read++;
+ }
inline void update_index_statistics()
{
index_rows_read[active_index]++;
- rows_read++;
+ update_rows_read();
}
public:
@@ -2376,6 +2393,13 @@ public:
*/
virtual void cond_pop() { return; };
virtual Item *idx_cond_push(uint keyno, Item* idx_cond) { return idx_cond; }
+ /** Reset information about pushed index conditions */
+ virtual void cancel_pushed_idx_cond()
+ {
+ pushed_idx_cond= NULL;
+ pushed_idx_cond_keyno= MAX_KEY;
+ in_range_check_pushed_down= false;
+ }
virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes)
{ return COMPATIBLE_DATA_NO; }
@@ -2447,6 +2471,7 @@ private:
*/
virtual int open(const char *name, int mode, uint test_if_locked)=0;
+ /* Note: ha_index_read_idx_map() may buypass index_init() */
virtual int index_init(uint idx, bool sorted) { return 0; }
virtual int index_end() { return 0; }
/**
@@ -2604,6 +2629,7 @@ public:
virtual handlerton *partition_ht() const
{ return ht; }
inline int ha_write_tmp_row(uchar *buf);
+ inline int ha_update_tmp_row(const uchar * old_data, uchar * new_data);
};
#include "multi_range_read.h"
diff --git a/sql/item.cc b/sql/item.cc
index cad3e60e5fc..d321b74c1fc 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -31,6 +31,16 @@ const String my_null_string("NULL", 4, default_charset_info);
static int save_field_in_field(Field *from, bool *null_value,
Field *to, bool no_conversions);
+
+/**
+ Compare two Items for List<Item>::add_unique()
+*/
+
+bool cmp_items(Item *a, Item *b)
+{
+ return a->eq(b, FALSE);
+}
+
/****************************************************************************/
/* Hybrid_type_traits {_real} */
@@ -651,14 +661,14 @@ Item* Item::transform(Item_transformer transformer, uchar *arg)
A pointer to created wrapper item if successful, NULL - otherwise
*/
-Item* Item::set_expr_cache(THD *thd, List<Item *> &depends_on)
+Item* Item::set_expr_cache(THD *thd)
{
DBUG_ENTER("Item::set_expr_cache");
Item_cache_wrapper *wrapper;
if ((wrapper= new Item_cache_wrapper(this)) &&
!wrapper->fix_fields(thd, (Item**)&wrapper))
{
- if (wrapper->set_cache(thd, depends_on))
+ if (wrapper->set_cache(thd))
DBUG_RETURN(NULL);
DBUG_RETURN(wrapper);
}
@@ -742,6 +752,17 @@ bool Item_ident::remove_dependence_processor(uchar * arg)
}
+bool Item_ident::collect_outer_ref_processor(uchar *param)
+{
+ Collect_deps_prm *prm= (Collect_deps_prm *)param;
+ if (depended_from &&
+ depended_from->nest_level_base == prm->nest_level_base &&
+ depended_from->nest_level < prm->nest_level)
+ prm->parameters->add_unique(this, &cmp_items);
+ return FALSE;
+}
+
+
/**
Store the pointer to this item field into a list if not already there.
@@ -2153,6 +2174,11 @@ bool Item_field::enumerate_field_refs_processor(uchar *arg)
return FALSE;
}
+bool Item_field::update_table_bitmaps_processor(uchar *arg)
+{
+ update_table_bitmaps();
+ return FALSE;
+}
const char *Item_ident::full_name() const
{
@@ -4357,9 +4383,6 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
((ref_type == REF_ITEM || ref_type == FIELD_ITEM) ?
(Item_ident*) (*reference) :
0));
- context->select_lex->
- register_dependency_item(last_checked_context->select_lex,
- reference);
/*
A reference to a view field had been found and we
substituted it instead of this Item (find_field_in_tables
@@ -4460,9 +4483,6 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
mark_as_dependent(thd, last_checked_context->select_lex,
context->select_lex, rf,
rf);
- context->select_lex->
- register_dependency_item(last_checked_context->select_lex,
- reference);
return 0;
}
@@ -4471,9 +4491,6 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
mark_as_dependent(thd, last_checked_context->select_lex,
context->select_lex,
this, (Item_ident*)*reference);
- context->select_lex->
- register_dependency_item(last_checked_context->select_lex,
- reference);
if (last_checked_context->select_lex->having_fix_field)
{
Item_ref *rf;
@@ -4638,6 +4655,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (!outer_fixed && cached_table && cached_table->select_lex &&
context->select_lex &&
cached_table->select_lex != context->select_lex &&
+ !context->select_lex->is_merged_child_of(cached_table->select_lex) &&
is_outer_table(cached_table, context->select_lex))
{
int ret;
@@ -5181,6 +5199,10 @@ Field *Item::make_string_field(TABLE *table)
{
Field *field;
DBUG_ASSERT(collation.collation);
+ /*
+ Note: the following check is repeated in
+ subquery_types_allow_materialization():
+ */
if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB)
field= new Field_blob(max_length, maybe_null, name,
collation.collation);
@@ -5967,7 +5989,7 @@ bool Item::send(Protocol *protocol, String *buffer)
case MYSQL_TYPE_TIMESTAMP:
{
MYSQL_TIME tm;
- get_date(&tm, TIME_FUZZY_DATE);
+ get_date(&tm, TIME_FUZZY_DATE | sql_mode_for_dates());
if (!null_value)
{
if (f_type == MYSQL_TYPE_DATE)
@@ -6304,9 +6326,6 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
refer_type == FIELD_ITEM) ?
(Item_ident*) (*reference) :
0));
- context->select_lex->
- register_dependency_item(last_checked_context->select_lex,
- reference);
/*
view reference found, we substituted it instead of this
Item, so can quit
@@ -6357,9 +6376,6 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
thd->change_item_tree(reference, fld);
mark_as_dependent(thd, last_checked_context->select_lex,
thd->lex->current_select, fld, fld);
- context->select_lex->
- register_dependency_item(last_checked_context->select_lex,
- reference);
/*
A reference is resolved to a nest level that's outer or the same as
the nest level of the enclosing set function : adjust the value of
@@ -6383,9 +6399,6 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
DBUG_ASSERT(*ref && (*ref)->fixed);
mark_as_dependent(thd, last_checked_context->select_lex,
context->select_lex, this, this);
- context->select_lex->
- register_dependency_item(last_checked_context->select_lex,
- reference);
/*
A reference is resolved to a nest level that's outer or the same as
the nest level of the enclosing set function : adjust the value of
@@ -6400,12 +6413,6 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
}
else if (ref_type() != VIEW_REF)
{
- if (depended_from && reference)
- {
- DBUG_ASSERT(context->select_lex != get_depended_from());
- context->select_lex->register_dependency_item(get_depended_from(),
- reference);
- }
/*
It could be that we're referring to something that's in ancestor selects.
We must make an appropriate mark_as_dependent() call for each such
@@ -6768,7 +6775,19 @@ my_decimal *Item_ref::val_decimal(my_decimal *decimal_value)
int Item_ref::save_in_field(Field *to, bool no_conversions)
{
int res;
- DBUG_ASSERT(!result_field);
+ if (result_field)
+ {
+ if (result_field->is_null())
+ {
+ null_value= 1;
+ res= set_field_to_null_with_conversions(to, no_conversions);
+ return res;
+ }
+ to->set_notnull();
+ res= field_conv(to, result_field);
+ null_value= 0;
+ return res;
+ }
res= (*ref)->save_in_field(to, no_conversions);
null_value= (*ref)->null_value;
return res;
@@ -6883,40 +6902,6 @@ bool Item_direct_ref::get_date(MYSQL_TIME *ltime,uint fuzzydate)
}
-Item* Item_direct_ref_to_ident::transform(Item_transformer transformer,
- uchar *argument)
-{
- DBUG_ASSERT(!current_thd->is_stmt_prepare());
-
- Item *new_item= ident->transform(transformer, argument);
- if (!new_item)
- return 0;
- DBUG_ASSERT(new_item->type() == FIELD_ITEM || new_item->type() == REF_ITEM);
-
- if (ident != new_item)
- current_thd->change_item_tree((Item**)&ident, new_item);
- return (this->*transformer)(argument);
-}
-
-
-Item* Item_direct_ref_to_ident::compile(Item_analyzer analyzer, uchar **arg_p,
- Item_transformer transformer,
- uchar *arg_t)
-{
- if (!(this->*analyzer)(arg_p))
- return 0;
-
- uchar *arg_v= *arg_p;
- Item *new_item= ident->compile(analyzer, &arg_v, transformer, arg_t);
- if (new_item && ident != new_item)
- {
- DBUG_ASSERT(new_item->type() == FIELD_ITEM || new_item->type() == REF_ITEM);
- current_thd->change_item_tree((Item**)&ident, new_item);
- }
- return (this->*transformer)(arg_t);
-}
-
-
Item_cache_wrapper::~Item_cache_wrapper()
{
DBUG_ASSERT(expr_cache == 0);
@@ -6936,6 +6921,7 @@ Item_cache_wrapper::Item_cache_wrapper(Item *item_arg)
unsigned_flag= orig_item->unsigned_flag;
name= item_arg->name;
name_length= item_arg->name_length;
+ with_subselect= orig_item->with_subselect;
if ((expr_value= Item_cache::get_cache(orig_item)))
expr_value->setup(orig_item);
@@ -6944,11 +6930,28 @@ Item_cache_wrapper::Item_cache_wrapper(Item *item_arg)
}
+/**
+ Initialize the cache if it is needed
+*/
+
+void Item_cache_wrapper::init_on_demand()
+{
+ if (!expr_cache->is_inited())
+ {
+ orig_item->get_cache_parameters(parameters);
+ expr_cache->init();
+ }
+}
+
+
void Item_cache_wrapper::print(String *str, enum_query_type query_type)
{
str->append(func_name());
if (expr_cache)
+ {
+ init_on_demand();
expr_cache->print(str, query_type);
+ }
else
str->append(STRING_WITH_LEN("<<DISABLED>>"));
str->append('(');
@@ -6984,6 +6987,7 @@ void Item_cache_wrapper::cleanup()
expr_cache= 0;
/* expr_value is Item so it will be destroyed from list of Items */
expr_value= 0;
+ parameters.empty();
DBUG_VOID_RETURN;
}
@@ -7004,11 +7008,11 @@ void Item_cache_wrapper::cleanup()
@retval TRUE Error
*/
-bool Item_cache_wrapper::set_cache(THD *thd, List<Item*> &depends_on)
+bool Item_cache_wrapper::set_cache(THD *thd)
{
DBUG_ENTER("Item_cache_wrapper::set_cache");
DBUG_ASSERT(expr_cache == 0);
- expr_cache= new Expression_cache_tmptable(thd, depends_on, expr_value);
+ expr_cache= new Expression_cache_tmptable(thd, parameters, expr_value);
DBUG_RETURN(expr_cache == NULL);
}
@@ -7033,6 +7037,7 @@ Item *Item_cache_wrapper::check_cache()
{
Expression_cache_tmptable::result res;
Item *cached_value;
+ init_on_demand();
res= expr_cache->check_value(&cached_value);
if (res == Expression_cache_tmptable::HIT)
DBUG_RETURN(cached_value);
@@ -7318,7 +7323,11 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
((*ref)->fix_fields(thd, ref)))
return TRUE;
- return Item_direct_ref::fix_fields(thd, reference);
+ if (Item_direct_ref::fix_fields(thd, reference))
+ return TRUE;
+ if (view->table && view->table->maybe_null)
+ maybe_null= TRUE;
+ return FALSE;
}
/*
@@ -7561,7 +7570,7 @@ Item *Item_direct_view_ref::replace_equal_field(uchar *arg)
field_item->set_item_equal(item_equal);
Item *item= field_item->replace_equal_field(arg);
field_item->set_item_equal(0);
- return item;
+ return item != field_item ? item : this;
}
@@ -9109,6 +9118,12 @@ table_map Item_direct_view_ref::used_tables() const
(view->merged ? (*ref)->used_tables() : view->table->map);
}
+table_map Item_direct_view_ref::not_null_tables() const
+{
+ return get_depended_from() ?
+ 0 :
+ (view->merged ? (*ref)->not_null_tables() : view->table->map);
+}
/*
we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
@@ -9121,7 +9136,22 @@ table_map Item_ref_null_helper::used_tables() const
}
+/* Debugger help function */
+static char dbug_item_print_buf[256];
+const char *dbug_print_item(Item *item)
+{
+ char *buf= dbug_item_print_buf;
+ String str(buf, sizeof(dbug_item_print_buf), &my_charset_bin);
+ str.length(0);
+ if (!item)
+ return "(Item*)NULL";
+ item->print(&str ,QT_ORDINARY);
+ if (str.c_ptr() == buf)
+ return buf;
+ else
+ return "Couldn't fit into buffer";
+}
/*****************************************************************************
** Instantiate templates
*****************************************************************************/
diff --git a/sql/item.h b/sql/item.h
index 1829f45d00b..fa6918d8484 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -505,6 +505,7 @@ typedef void (*Cond_traverser) (const Item *item, void *arg);
class Item_equal;
class COND_EQUAL;
+class st_select_lex_unit;
class Item {
Item(const Item &); /* Prevent use of these */
@@ -1018,8 +1019,10 @@ public:
virtual bool mark_as_eliminated_processor(uchar *arg) { return 0; }
virtual bool eliminate_subselect_processor(uchar *arg) { return 0; }
virtual bool set_fake_select_as_master_processor(uchar *arg) { return 0; }
+ virtual bool update_table_bitmaps_processor(uchar *arg) { return 0; }
virtual bool view_used_tables_processor(uchar *arg) { return 0; }
virtual bool eval_not_null_tables(uchar *opt_arg) { return 0; }
+ virtual bool clear_sum_processor(uchar *opt_arg) { return 0; }
/* To call bool function for all arguments */
struct bool_func_call_args
@@ -1155,6 +1158,17 @@ public:
{
return FALSE;
}
+ struct Collect_deps_prm
+ {
+ List<Item> *parameters;
+ /* unit from which we count nest_level */
+ st_select_lex_unit *nest_level_base;
+ int nest_level;
+ };
+ /**
+ Collect outer references
+ */
+ virtual bool collect_outer_ref_processor(uchar *arg) {return FALSE; }
/**
Find a function of a given type
@@ -1249,7 +1263,7 @@ public:
{ return Field::GEOM_GEOMETRY; };
String *check_well_formed_result(String *str, bool send_error= 0);
bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs);
- Item* set_expr_cache(THD *thd, List<Item*> &depends_on);
+ Item* set_expr_cache(THD *thd);
virtual Item *get_cached_item() { return NULL; }
virtual Item_equal *get_item_equal() { return NULL; }
@@ -1273,9 +1287,27 @@ public:
walk(&Item::view_used_tables_processor, 0, (uchar *) view);
return view->view_used_tables;
}
+
+ /**
+ Collect and add to the list cache parameters for this Item.
+
+ @note Now implemented only for subqueries and in_optimizer,
+ if we need it for general function then this method should
+ be defined for Item_func.
+ */
+ virtual void get_cache_parameters(List<Item> &parameters) { };
+
+ virtual void mark_as_condition_AND_part(TABLE_LIST *embedding) {};
};
+/**
+ Compare two Items for List<Item>::add_unique()
+*/
+
+bool cmp_items(Item *a, Item *b);
+
+
/*
Class to be used to enumerate all field references in an item tree. This
includes references to outside but not fields of the tables within a
@@ -1677,6 +1709,10 @@ public:
virtual void print(String *str, enum_query_type query_type);
virtual bool change_context_processor(uchar *cntx)
{ context= (Name_resolution_context *)cntx; return FALSE; }
+ /**
+ Collect outer references
+ */
+ virtual bool collect_outer_ref_processor(uchar *arg);
friend bool insert_fields(THD *thd, Name_resolution_context *context,
const char *db_name,
const char *table_name, List_iterator<Item> *it,
@@ -1784,6 +1820,20 @@ public:
bool get_date_result(MYSQL_TIME *ltime,uint fuzzydate);
bool is_null() { return field->is_null(); }
void update_null_value();
+ void update_table_bitmaps()
+ {
+ if (field && field->table)
+ {
+ TABLE *tab= field->table;
+ tab->covering_keys.intersect(field->part_of_key);
+ tab->merge_keys.merge(field->part_of_key);
+ if (tab->read_set)
+ bitmap_fast_test_and_set(tab->read_set, field->field_index);
+ if (field->vcol_info)
+ tab->mark_virtual_col(field);
+ }
+ }
+ void update_used_tables() { update_table_bitmaps(); }
Item *get_tmp_table_item(THD *thd);
bool collect_item_field_processor(uchar * arg);
bool add_field_to_set_processor(uchar * arg);
@@ -1795,6 +1845,7 @@ public:
bool vcol_in_partition_func_processor(uchar *bool_arg);
bool check_vcol_func_processor(uchar *arg) { return FALSE;}
bool enumerate_field_refs_processor(uchar *arg);
+ bool update_table_bitmaps_processor(uchar *arg);
void cleanup();
Item_equal *get_item_equal() { return item_equal; }
void set_item_equal(Item_equal *item_eq) { item_equal= item_eq; }
@@ -2570,13 +2621,16 @@ public:
Field *get_tmp_table_field()
{ return result_field ? result_field : (*ref)->get_tmp_table_field(); }
Item *get_tmp_table_item(THD *thd);
- inline table_map used_tables() const;
- inline void update_used_tables();
+ table_map used_tables() const;
+ void update_used_tables();
bool const_item() const
{
return (*ref)->const_item();
}
- table_map not_null_tables() const { return (*ref)->not_null_tables(); }
+ table_map not_null_tables() const
+ {
+ return depended_from ? 0 : (*ref)->not_null_tables();
+ }
void set_result_field(Field *field) { result_field= field; }
bool is_result_field() { return 1; }
void save_in_result_field(bool no_conversions)
@@ -2713,9 +2767,6 @@ public:
virtual void print(String *str, enum_query_type query_type)
{ ident->print(str, query_type); }
- virtual Item* transform(Item_transformer transformer, uchar *arg);
- virtual Item* compile(Item_analyzer analyzer, uchar **arg_p,
- Item_transformer transformer, uchar *arg_t);
};
@@ -2742,8 +2793,11 @@ private:
*/
Item_cache *expr_value;
+ List<Item> parameters;
+
Item *check_cache();
- inline void cache();
+ void cache();
+ void init_on_demand();
public:
Item_cache_wrapper(Item *item_arg);
@@ -2753,7 +2807,7 @@ public:
enum Type type() const { return EXPR_CACHE_ITEM; }
enum Type real_type() const { return orig_item->type(); }
- bool set_cache(THD *thd, List<Item*> &depends_on);
+ bool set_cache(THD *thd);
bool fix_fields(THD *thd, Item **it);
void fix_length_and_dec() {}
@@ -2835,6 +2889,9 @@ public:
if (result_type() == ROW_RESULT)
orig_item->bring_value();
}
+ virtual bool is_expensive() { return orig_item->is_expensive(); }
+ bool is_expensive_processor(uchar *arg)
+ { return orig_item->is_expensive_processor(arg); }
bool check_vcol_func_processor(uchar *arg)
{
return trace_unsupported_by_check_vcol_func_processor("cache");
@@ -2881,6 +2938,7 @@ public:
Item *equal_fields_propagator(uchar *arg);
Item *replace_equal_field(uchar *arg);
table_map used_tables() const;
+ table_map not_null_tables() const;
bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
{
return (*ref)->walk(processor, walk_subquery, arg) ||
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index dc25cf5942c..a33dd090f14 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -29,8 +29,6 @@
#include <m_ctype.h>
#include "sql_select.h"
-static bool convert_const_to_int(THD *, Item_field *, Item **);
-
static Item_result item_store_type(Item_result a, Item *item,
my_bool unsigned_flag)
{
@@ -266,36 +264,61 @@ Item_bool_func2* Eq_creator::create(Item *a, Item *b) const
return new Item_func_eq(a, b);
}
+Item_bool_func2* Eq_creator::create_swap(Item *a, Item *b) const
+{
+ return new Item_func_eq(b, a);
+}
Item_bool_func2* Ne_creator::create(Item *a, Item *b) const
{
return new Item_func_ne(a, b);
}
+Item_bool_func2* Ne_creator::create_swap(Item *a, Item *b) const
+{
+ return new Item_func_ne(b, a);
+}
Item_bool_func2* Gt_creator::create(Item *a, Item *b) const
{
return new Item_func_gt(a, b);
}
+Item_bool_func2* Gt_creator::create_swap(Item *a, Item *b) const
+{
+ return new Item_func_lt(b, a);
+}
Item_bool_func2* Lt_creator::create(Item *a, Item *b) const
{
return new Item_func_lt(a, b);
}
+Item_bool_func2* Lt_creator::create_swap(Item *a, Item *b) const
+{
+ return new Item_func_gt(b, a);
+}
Item_bool_func2* Ge_creator::create(Item *a, Item *b) const
{
return new Item_func_ge(a, b);
}
+Item_bool_func2* Ge_creator::create_swap(Item *a, Item *b) const
+{
+ return new Item_func_le(b, a);
+}
Item_bool_func2* Le_creator::create(Item *a, Item *b) const
{
return new Item_func_le(a, b);
}
+Item_bool_func2* Le_creator::create_swap(Item *a, Item *b) const
+{
+ return new Item_func_ge(b, a);
+}
+
/*
Test functions
Most of these returns 0LL if false and 1LL if true and
@@ -434,7 +457,7 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item,
field_item->field_type() != MYSQL_TYPE_YEAR)
return 1;
- if ((*item)->const_item())
+ if ((*item)->const_item() && !(*item)->is_expensive())
{
TABLE *table= field->table;
ulong orig_sql_mode= thd->variables.sql_mode;
@@ -490,7 +513,6 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item,
void Item_bool_func2::fix_length_and_dec()
{
max_length= 1; // Function returns 0 or 1
- THD *thd;
/*
As some compare functions are generated after sql_yacc,
@@ -522,14 +544,14 @@ void Item_bool_func2::fix_length_and_dec()
/*
Make a special case of compare with fields to get nicer comparisons
- of numbers with constant string.
+ of bigint numbers with constant string.
This directly contradicts the manual (number and a string should
be compared as doubles), but seems to provide more
"intuitive" behavior in some cases (but less intuitive in others).
But disable conversion in case of LIKE function.
*/
- thd= current_thd;
+ THD *thd= current_thd;
if (functype() != LIKE_FUNC && !thd->lex->is_ps_or_view_context_analysis())
{
int field;
@@ -537,7 +559,8 @@ void Item_bool_func2::fix_length_and_dec()
args[field= 1]->real_item()->type() == FIELD_ITEM)
{
Item_field *field_item= (Item_field*) (args[field]->real_item());
- if (field_item->cmp_type() == INT_RESULT &&
+ if ((field_item->field_type() == MYSQL_TYPE_LONGLONG ||
+ field_item->field_type() == MYSQL_TYPE_YEAR) &&
convert_const_to_int(thd, field_item, &args[!field]))
args[0]->cmp_context= args[1]->cmp_context= INT_RESULT;
}
@@ -1374,6 +1397,36 @@ longlong Item_func_truth::val_int()
}
+bool Item_in_optimizer::is_top_level_item()
+{
+ return ((Item_in_subselect *)args[1])->is_top_level_item();
+}
+
+
+void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ /* This will re-calculate attributes of our Item_in_subselect: */
+ Item_bool_func::fix_after_pullout(new_parent, ref);
+
+ /* Then, re-calculate not_null_tables_cache: */
+ eval_not_null_tables(NULL);
+}
+
+
+bool Item_in_optimizer::eval_not_null_tables(uchar *opt_arg)
+{
+ not_null_tables_cache= 0;
+ if (is_top_level_item())
+ {
+ /*
+ It is possible to determine NULL-rejectedness of the left arguments
+ of IN only if it is a top-level predicate.
+ */
+ not_null_tables_cache= args[0]->not_null_tables();
+ }
+ return FALSE;
+}
+
bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
{
if ((!args[0]->fixed && args[0]->fix_fields(thd, args)) ||
@@ -1400,7 +1453,7 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
}
used_tables_cache= args[0]->used_tables();
}
- not_null_tables_cache= args[0]->not_null_tables();
+ eval_not_null_tables(NULL);
with_sum_func= args[0]->with_sum_func;
with_field= args[0]->with_field;
if ((const_item_cache= args[0]->const_item()))
@@ -1433,7 +1486,6 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
with_sum_func= with_sum_func || args[1]->with_sum_func;
with_field= with_field || args[1]->with_field;
used_tables_cache|= args[1]->used_tables();
- not_null_tables_cache|= args[1]->not_null_tables();
const_item_cache&= args[1]->const_item();
fixed= 1;
return FALSE;
@@ -1464,32 +1516,41 @@ Item *Item_in_optimizer::expr_cache_insert_transformer(uchar *thd_arg)
DBUG_ENTER("Item_in_optimizer::expr_cache_insert_transformer");
if (args[1]->type() != Item::SUBSELECT_ITEM)
DBUG_RETURN(this); // MAX/MIN transformed => do nothing
- List<Item*> &depends_on= ((Item_subselect *)args[1])->depends_on;
if (expr_cache)
DBUG_RETURN(expr_cache);
+ if (args[1]->expr_cache_is_needed(thd) &&
+ (expr_cache= set_expr_cache(thd)))
+ DBUG_RETURN(expr_cache);
+
+ DBUG_RETURN(this);
+}
+
+
+
+/**
+ Collect and add to the list cache parameters for this Item.
+
+ @param parameters The list where to add parameters
+*/
+
+void Item_in_optimizer::get_cache_parameters(List<Item> &parameters)
+{
/* Add left expression to the list of the parameters of the subquery */
if (args[0]->cols() == 1)
- depends_on.push_front((Item**)args);
+ parameters.add_unique(args[0], &cmp_items);
else
{
for (uint i= 0; i < args[0]->cols(); i++)
{
- depends_on.push_front(args[0]->addr(i));
+ parameters.add_unique(args[0]->element_index(i), &cmp_items);
}
}
-
- if (args[1]->expr_cache_is_needed(thd) &&
- (expr_cache= set_expr_cache(thd, depends_on)))
- DBUG_RETURN(expr_cache);
-
- /* no cache => return list in original state just to be safe */
- for (uint i= 0; i < args[0]->cols(); i++)
- depends_on.pop();
- DBUG_RETURN(this);
+ args[1]->get_cache_parameters(parameters);
}
+
/*
The implementation of optimized \<outer expression\> [NOT] IN \<subquery\>
predicates. The implementation works as follows.
@@ -1731,7 +1792,7 @@ Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument
if (!new_item)
return 0;
if (args[1] != new_item)
- current_thd->change_item_tree(args, new_item);
+ current_thd->change_item_tree(args + 1, new_item);
}
else
{
@@ -1751,7 +1812,7 @@ Item *Item_in_optimizer::transform(Item_transformer transformer, uchar *argument
Item_subselect::ANY_SUBS));
Item_in_subselect *in_arg= (Item_in_subselect*)args[1];
- in_arg->left_expr= args[0];
+ current_thd->change_item_tree(&in_arg->left_expr, args[0]);
}
return (this->*transformer)(argument);
}
@@ -2083,6 +2144,14 @@ bool Item_func_between::eval_not_null_tables(uchar *opt_arg)
}
+void Item_func_between::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ /* This will re-calculate attributes of the arguments */
+ Item_func_opt_neg::fix_after_pullout(new_parent, ref);
+ /* Then, re-calculate not_null_tables_cache according to our special rules */
+ eval_not_null_tables(NULL);
+}
+
void Item_func_between::fix_length_and_dec()
{
THD *thd= current_thd;
@@ -2117,7 +2186,8 @@ void Item_func_between::fix_length_and_dec()
!thd->lex->is_ps_or_view_context_analysis())
{
Item_field *field_item= (Item_field*) (args[0]->real_item());
- if (field_item->cmp_type() == INT_RESULT)
+ if (field_item->field_type() == MYSQL_TYPE_LONGLONG ||
+ field_item->field_type() == MYSQL_TYPE_YEAR)
{
/*
The following can't be recoded with || as convert_const_to_int
@@ -2463,6 +2533,16 @@ Item_func_if::eval_not_null_tables(uchar *opt_arg)
return 0;
}
+
+void Item_func_if::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ /* This will re-calculate attributes of the arguments */
+ Item_func::fix_after_pullout(new_parent, ref);
+ /* Then, re-calculate not_null_tables_cache according to our special rules */
+ eval_not_null_tables(NULL);
+}
+
+
void
Item_func_if::fix_length_and_dec()
{
@@ -2710,7 +2790,7 @@ Item *Item_func_case::find_item(String *str)
{
if (args[i]->real_item()->type() == NULL_ITEM)
continue;
- cmp_type= item_cmp_type(left_result_type, args[i]->result_type());
+ 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)))
@@ -2875,7 +2955,7 @@ void Item_func_case::fix_length_and_dec()
{
uint i;
agg[0]= args[first_expr_num];
- left_result_type= agg[0]->result_type();
+ left_result_type= agg[0]->cmp_type();
for (nagg= 0; nagg < ncases/2 ; nagg++)
agg[nagg+1]= args[nagg*2];
@@ -2893,17 +2973,21 @@ void Item_func_case::fix_length_and_dec()
found_types |= (1 << item_cmp_type(left_result_type, STRING_RESULT));
}
+ Item *date_arg= 0;
for (i= 0; i <= (uint)TIME_RESULT; i++)
{
if (found_types & (1 << i) && !cmp_items[i])
{
DBUG_ASSERT((Item_result)i != ROW_RESULT);
- DBUG_ASSERT((Item_result)i != TIME_RESULT);
if ((Item_result)i == STRING_RESULT &&
agg_arg_charsets(cmp_collation, agg, nagg, MY_COLL_CMP_CONV, 1))
return;
+
+ if ((Item_result)i == TIME_RESULT)
+ date_arg= find_date_time_item(args, arg_count, 0);
+
if (!(cmp_items[i]=
- cmp_item::get_comparator((Item_result)i, 0,
+ cmp_item::get_comparator((Item_result)i, date_arg,
cmp_collation.collation)))
return;
}
@@ -3494,10 +3578,13 @@ void cmp_item_row::store_value(Item *item)
for (uint i=0; i < n; i++)
{
if (!comparators[i])
+ {
+ DBUG_ASSERT(item->element_index(i)->cmp_type() != TIME_RESULT);
if (!(comparators[i]=
cmp_item::get_comparator(item->element_index(i)->result_type(), 0,
item->element_index(i)->collation.collation)))
break; // new failed
+ }
comparators[i]->store_value(item->element_index(i));
item->null_value|= item->element_index(i)->null_value;
}
@@ -3700,6 +3787,14 @@ Item_func_in::eval_not_null_tables(uchar *opt_arg)
}
+void Item_func_in::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+{
+ /* This will re-calculate attributes of the arguments */
+ Item_func_opt_neg::fix_after_pullout(new_parent, ref);
+ /* Then, re-calculate not_null_tables_cache according to our special rules */
+ eval_not_null_tables(NULL);
+}
+
static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
{
return cs->coll->strnncollsp(cs,
@@ -3798,7 +3893,8 @@ void Item_func_in::fix_length_and_dec()
!thd->lex->is_ps_or_view_context_analysis() && cmp_type != INT_RESULT)
{
Item_field *field_item= (Item_field*) (args[0]->real_item());
- if (field_item->cmp_type() == INT_RESULT)
+ if (field_item->field_type() == MYSQL_TYPE_LONGLONG ||
+ field_item->field_type() == MYSQL_TYPE_YEAR)
{
bool all_converted= TRUE;
for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
@@ -4023,15 +4119,12 @@ Item_cond::fix_fields(THD *thd, Item **ref)
DBUG_ASSERT(fixed == 0);
List_iterator<Item> li(list);
Item *item;
- TABLE_LIST *save_emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
#ifndef EMBEDDED_LIBRARY
uchar buff[sizeof(char*)]; // Max local vars in function
#endif
not_null_tables_cache= used_tables_cache= 0;
const_item_cache= 1;
- if (functype() != COND_AND_FUNC)
- thd->thd_marker.emb_on_expr_nest= NULL;
/*
and_table_cache is the value that Item_cond_or() returns for
not_null_tables()
@@ -4091,7 +4184,6 @@ Item_cond::fix_fields(THD *thd, Item **ref)
maybe_null=1;
}
thd->lex->current_select->cond_count+= list.elements;
- thd->thd_marker.emb_on_expr_nest= save_emb_on_expr_nest;
fix_length_and_dec();
fixed= 1;
return FALSE;
@@ -4103,6 +4195,7 @@ Item_cond::eval_not_null_tables(uchar *opt_arg)
{
Item *item;
List_iterator<Item> li(list);
+ not_null_tables_cache= (table_map) 0;
and_tables_cache= ~(table_map) 0;
while ((item=li++))
{
@@ -4361,6 +4454,17 @@ void Item_cond::neg_arguments(THD *thd)
}
+void Item_cond_and::mark_as_condition_AND_part(TABLE_LIST *embedding)
+{
+ List_iterator<Item> li(list);
+ Item *item;
+ while ((item=li++))
+ {
+ item->mark_as_condition_AND_part(embedding);
+ }
+}
+
+
/**
Evaluation of AND(expr, expr, expr ...).
@@ -5065,23 +5169,21 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
very fast to use.
*/
-longlong Item_cond_xor::val_int()
+longlong Item_func_xor::val_int()
{
DBUG_ASSERT(fixed == 1);
- List_iterator<Item> li(list);
- Item *item;
- int result=0;
- null_value=0;
- while ((item=li++))
+ int result= 0;
+ null_value= false;
+ for (uint i= 0; i < arg_count; i++)
{
- result^= (item->val_int() != 0);
- if (item->null_value)
+ result^= (args[i]->val_int() != 0);
+ if (args[i]->null_value)
{
- null_value=1;
+ null_value= true;
return 0;
}
}
- return (longlong) result;
+ return result;
}
/**
@@ -5122,6 +5224,33 @@ Item *Item_bool_rowready_func2::neg_transformer(THD *thd)
return item;
}
+/**
+ XOR can be negated by negating one of the operands:
+
+ NOT (a XOR b) => (NOT a) XOR b
+ => a XOR (NOT b)
+
+ @param thd Thread handle
+ @return New negated item
+*/
+Item *Item_func_xor::neg_transformer(THD *thd)
+{
+ Item *neg_operand;
+ Item_func_xor *new_item;
+ if ((neg_operand= args[0]->neg_transformer(thd)))
+ // args[0] has neg_tranformer
+ new_item= new(thd->mem_root) Item_func_xor(neg_operand, args[1]);
+ else if ((neg_operand= args[1]->neg_transformer(thd)))
+ // args[1] has neg_tranformer
+ new_item= new(thd->mem_root) Item_func_xor(args[0], neg_operand);
+ else
+ {
+ neg_operand= new(thd->mem_root) Item_func_not(args[0]);
+ new_item= new(thd->mem_root) Item_func_xor(neg_operand, args[1]);
+ }
+ return new_item;
+}
+
/**
a IS NULL -> a IS NOT NULL.
@@ -5579,7 +5708,7 @@ longlong Item_equal::val_int()
void Item_equal::fix_length_and_dec()
{
Item *item= get_first(NULL);
- eval_item= cmp_item::get_comparator(item->result_type(), 0,
+ eval_item= cmp_item::get_comparator(item->cmp_type(), item,
item->collation.collation);
}
@@ -5682,7 +5811,6 @@ Item* Item_equal::get_first(Item *field_item)
{
Item_equal_fields_iterator it(*this);
Item *item;
- JOIN_TAB *field_tab;
if (!field_item)
return (it++);
Field *field= ((Item_field *) (field_item->real_item()))->field;
@@ -5707,8 +5835,6 @@ Item* Item_equal::get_first(Item *field_item)
in presense of SJM nests.
*/
- field_tab= field->table->reginfo.join_tab;
-
TABLE_LIST *emb_nest= field->table->pos_in_table_list->embedding;
if (emb_nest && emb_nest->sj_mat_info && emb_nest->sj_mat_info->is_used)
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 285367ba9d6..81a18bb594e 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -259,6 +259,10 @@ public:
bool is_expensive();
void set_join_tab_idx(uint join_tab_idx_arg)
{ args[1]->set_join_tab_idx(join_tab_idx_arg); }
+ virtual void get_cache_parameters(List<Item> &parameters);
+ bool is_top_level_item();
+ bool eval_not_null_tables(uchar *opt_arg);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
};
class Comp_creator
@@ -266,7 +270,14 @@ class Comp_creator
public:
Comp_creator() {} /* Remove gcc warning */
virtual ~Comp_creator() {} /* Remove gcc warning */
+ /**
+ Create operation with given arguments.
+ */
virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
+ /**
+ Create operation with given arguments in swap order.
+ */
+ virtual Item_bool_func2* create_swap(Item *a, Item *b) const = 0;
virtual const char* symbol(bool invert) const = 0;
virtual bool eqne_op() const = 0;
virtual bool l_op() const = 0;
@@ -278,6 +289,7 @@ public:
Eq_creator() {} /* Remove gcc warning */
virtual ~Eq_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const;
+ virtual Item_bool_func2* create_swap(Item *a, Item *b) const;
virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
virtual bool eqne_op() const { return 1; }
virtual bool l_op() const { return 0; }
@@ -289,6 +301,7 @@ public:
Ne_creator() {} /* Remove gcc warning */
virtual ~Ne_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const;
+ virtual Item_bool_func2* create_swap(Item *a, Item *b) const;
virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
virtual bool eqne_op() const { return 1; }
virtual bool l_op() const { return 0; }
@@ -300,6 +313,7 @@ public:
Gt_creator() {} /* Remove gcc warning */
virtual ~Gt_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const;
+ virtual Item_bool_func2* create_swap(Item *a, Item *b) const;
virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
virtual bool eqne_op() const { return 0; }
virtual bool l_op() const { return 0; }
@@ -311,6 +325,7 @@ public:
Lt_creator() {} /* Remove gcc warning */
virtual ~Lt_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const;
+ virtual Item_bool_func2* create_swap(Item *a, Item *b) const;
virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
virtual bool eqne_op() const { return 0; }
virtual bool l_op() const { return 1; }
@@ -322,6 +337,7 @@ public:
Ge_creator() {} /* Remove gcc warning */
virtual ~Ge_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const;
+ virtual Item_bool_func2* create_swap(Item *a, Item *b) const;
virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
virtual bool eqne_op() const { return 0; }
virtual bool l_op() const { return 0; }
@@ -333,6 +349,7 @@ public:
Le_creator() {} /* Remove gcc warning */
virtual ~Le_creator() {} /* Remove gcc warning */
virtual Item_bool_func2* create(Item *a, Item *b) const;
+ virtual Item_bool_func2* create_swap(Item *a, Item *b) const;
virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
virtual bool eqne_op() const { return 0; }
virtual bool l_op() const { return 1; }
@@ -391,6 +408,26 @@ public:
}
};
+/**
+ XOR inherits from Item_bool_func2 because it is not optimized yet.
+ Later, when XOR is optimized, it needs to inherit from
+ Item_cond instead. See WL#5800.
+*/
+class Item_func_xor :public Item_bool_func2
+{
+public:
+ Item_func_xor(Item *i1, Item *i2) :Item_bool_func2(i1, i2) {}
+ enum Functype functype() const { return XOR_FUNC; }
+ const char *func_name() const { return "xor"; }
+ longlong val_int();
+ void top_level_item() {}
+ Item *neg_transformer(THD *thd);
+ bool subst_argument_checker(uchar **arg)
+ {
+ return (*arg != NULL);
+ }
+};
+
class Item_func_not :public Item_bool_func
{
public:
@@ -460,7 +497,7 @@ public:
show(0)
{}
virtual void top_level_item() { abort_on_null= 1; }
- bool top_level() { return abort_on_null; }
+ bool is_top_level_item() { return abort_on_null; }
longlong val_int();
enum Functype functype() const { return NOT_ALL_FUNC; }
const char *func_name() const { return "<not>"; }
@@ -638,6 +675,7 @@ public:
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
uint decimal_precision() const { return 1; }
bool eval_not_null_tables(uchar *opt_arg);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
};
@@ -739,6 +777,7 @@ public:
uint decimal_precision() const;
const char *func_name() const { return "if"; }
bool eval_not_null_tables(uchar *opt_arg);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
};
@@ -1277,6 +1316,7 @@ public:
bool is_bool_func() { return 1; }
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
bool eval_not_null_tables(uchar *opt_arg);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref);
};
class cmp_item_row :public cmp_item
@@ -1331,7 +1371,11 @@ public:
const_item_cache= 1;
}
else
+ {
args[0]->update_used_tables();
+ used_tables_cache= args[0]->used_tables();
+ const_item_cache= args[0]->const_item();
+ }
}
table_map not_null_tables() const { return 0; }
optimize_type select_optimize() const { return OPTIMIZE_NULL; }
@@ -1688,7 +1732,8 @@ public:
friend class Item_equal_fields_iterator;
friend Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
Item_equal *item_equal);
- friend bool setup_sj_materialization(struct st_join_table *tab);
+ friend bool setup_sj_materialization_part1(struct st_join_table *tab);
+ friend bool setup_sj_materialization_part2(struct st_join_table *tab);
};
class COND_EQUAL: public Sql_alloc
@@ -1775,6 +1820,7 @@ public:
return item;
}
Item *neg_transformer(THD *thd);
+ void mark_as_condition_AND_part(TABLE_LIST *embedding);
};
inline bool is_cond_and(Item *item)
@@ -1816,45 +1862,6 @@ inline bool is_cond_or(Item *item)
return (cond_item->functype() == Item_func::COND_OR_FUNC);
}
-/*
- XOR is Item_cond, not an Item_int_func because we could like to
- optimize (a XOR b) later on. It's low prio, though
-*/
-
-class Item_cond_xor :public Item_cond
-{
-public:
- Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2)
- {
- /*
- Items must be stored in args[] as well because this Item_cond is
- treated as a FUNC_ITEM (see type()). I.e., users of it will get
- it's children by calling arguments(), not argument_list(). This
- is a temporary solution until XOR is optimized and treated like
- a full Item_cond citizen.
- */
- arg_count= 2;
- args= tmp_arg;
- args[0]= i1;
- args[1]= i2;
- }
- enum Functype functype() const { return COND_XOR_FUNC; }
- /* TODO: remove the next line when implementing XOR optimization */
- enum Type type() const { return FUNC_ITEM; }
- longlong val_int();
- const char *func_name() const { return "xor"; }
- void top_level_item() {}
- /* Since child Items are stored in args[], Items cannot be added.
- However, since Item_cond_xor is treated as a FUNC_ITEM (see
- type()), the methods below should never be called.
- */
- bool add(Item *item) { DBUG_ASSERT(FALSE); return FALSE; }
- bool add_at_head(Item *item) { DBUG_ASSERT(FALSE); return FALSE; }
- bool add_at_head(List<Item> *nlist) { DBUG_ASSERT(FALSE); return FALSE; }
- void copy_andor_arguments(THD *thd, Item_cond *item) { DBUG_ASSERT(FALSE); }
-};
-
-
/* Some useful inline functions */
inline Item *and_conds(Item *a, Item *b)
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 54c60ea03e1..ce43f90be8d 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -152,11 +152,9 @@ Item_func::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
Item **arg,**arg_end;
- TABLE_LIST *save_emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
#endif
- thd->thd_marker.emb_on_expr_nest= NULL;
used_tables_cache= not_null_tables_cache= 0;
const_item_cache=1;
@@ -210,7 +208,6 @@ Item_func::fix_fields(THD *thd, Item **ref)
if (thd->is_error()) // An error inside fix_length_and_dec occured
return TRUE;
fixed= 1;
- thd->thd_marker.emb_on_expr_nest= save_emb_on_expr_nest;
return FALSE;
}
@@ -234,6 +231,7 @@ bool
Item_func::eval_not_null_tables(uchar *opt_arg)
{
Item **arg,**arg_end;
+ not_null_tables_cache= 0;
if (arg_count)
{
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
@@ -5065,12 +5063,16 @@ void Item_func_get_system_var::fix_length_and_dec()
switch (var->show_type())
{
case SHOW_LONG:
- case SHOW_INT:
case SHOW_HA_ROWS:
unsigned_flag= TRUE;
max_length= MY_INT64_NUM_DECIMAL_DIGITS;
decimals=0;
break;
+ case SHOW_INT:
+ unsigned_flag= FALSE;
+ max_length= MY_INT64_NUM_DECIMAL_DIGITS;
+ decimals=0;
+ break;
case SHOW_LONGLONG:
unsigned_flag= TRUE;
max_length= MY_INT64_NUM_DECIMAL_DIGITS;
@@ -5211,7 +5213,7 @@ longlong Item_func_get_system_var::val_int()
switch (var->show_type())
{
- case SHOW_INT: get_sys_var_safe (uint);
+ case SHOW_INT: get_sys_var_safe (int);
case SHOW_LONG: get_sys_var_safe (ulong);
case SHOW_LONGLONG: get_sys_var_safe (ulonglong);
case SHOW_HA_ROWS: get_sys_var_safe (ha_rows);
diff --git a/sql/item_func.h b/sql/item_func.h
index 63056f9079e..4ff7492bd89 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -44,7 +44,7 @@ public:
enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC,
GE_FUNC,GT_FUNC,FT_FUNC,
LIKE_FUNC,ISNULL_FUNC,ISNOTNULL_FUNC,
- COND_AND_FUNC, COND_OR_FUNC, COND_XOR_FUNC,
+ COND_AND_FUNC, COND_OR_FUNC, XOR_FUNC,
BETWEEN, IN_FUNC, MULT_EQUAL_FUNC,
INTERVAL_FUNC, ISNOTNULLTEST_FUNC,
SP_EQUALS_FUNC, SP_DISJOINT_FUNC,SP_INTERSECTS_FUNC,
diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h
index f637167d6d2..f3208c5b4d4 100644
--- a/sql/item_geofunc.h
+++ b/sql/item_geofunc.h
@@ -185,6 +185,7 @@ public:
String *val_str(String *);
void fix_length_and_dec()
{
+ Item_geometry_func::fix_length_and_dec();
for (unsigned int i= 0; i < arg_count; ++i)
{
if (args[i]->fixed && args[i]->field_type() != MYSQL_TYPE_GEOMETRY)
diff --git a/sql/item_row.cc b/sql/item_row.cc
index 99a1644cc48..46d5f13f6fa 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -93,6 +93,22 @@ bool Item_row::fix_fields(THD *thd, Item **ref)
}
+bool
+Item_row::eval_not_null_tables(uchar *opt_arg)
+{
+ Item **arg,**arg_end;
+ not_null_tables_cache= 0;
+ if (arg_count)
+ {
+ for (arg= items, arg_end= items+arg_count; arg != arg_end ; arg++)
+ {
+ not_null_tables_cache|= (*arg)->not_null_tables();
+ }
+ }
+ return FALSE;
+}
+
+
void Item_row::cleanup()
{
DBUG_ENTER("Item_row::cleanup");
@@ -133,11 +149,13 @@ void Item_row::fix_after_pullout(st_select_lex *new_parent, Item **ref)
{
used_tables_cache= 0;
const_item_cache= 1;
+ not_null_tables_cache= 0;
for (uint i= 0; i < arg_count; i++)
{
items[i]->fix_after_pullout(new_parent, &items[i]);
used_tables_cache|= items[i]->used_tables();
const_item_cache&= items[i]->const_item();
+ not_null_tables_cache|= items[i]->not_null_tables();
}
}
diff --git a/sql/item_row.h b/sql/item_row.h
index 0b43309391d..1572ef77b79 100644
--- a/sql/item_row.h
+++ b/sql/item_row.h
@@ -73,6 +73,7 @@ public:
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
Item *transform(Item_transformer transformer, uchar *arg);
+ bool eval_not_null_tables(uchar *opt_arg);
uint cols() { return arg_count; }
Item* element_index(uint i) { return items[i]; }
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 453773478d8..9abbdfcec4f 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -3026,16 +3026,16 @@ String *Item_load_file::val_str(String *str)
func_name(), current_thd->variables.max_allowed_packet);
goto err;
}
- if (tmp_value.alloc(stat_info.st_size))
+ if (tmp_value.alloc((size_t)stat_info.st_size))
goto err;
if ((file = my_open(file_name->ptr(), O_RDONLY, MYF(0))) < 0)
goto err;
- if (my_read(file, (uchar*) tmp_value.ptr(), stat_info.st_size, MYF(MY_NABP)))
+ if (my_read(file, (uchar*) tmp_value.ptr(), (size_t)stat_info.st_size, MYF(MY_NABP)))
{
my_close(file, MYF(0));
goto err;
}
- tmp_value.length(stat_info.st_size);
+ tmp_value.length((uint32)stat_info.st_size);
my_close(file, MYF(0));
null_value = 0;
DBUG_RETURN(&tmp_value);
@@ -3606,40 +3606,40 @@ void Item_func_dyncol_create::prepare_arguments()
DBUG_ASSERT(args[valpos]->field_type() == MYSQL_TYPE_NULL);
break;
case DYN_COL_INT:
- vals[i].long_value= args[valpos]->val_int();
+ vals[i].x.long_value= args[valpos]->val_int();
break;
case DYN_COL_UINT:
- vals[i].ulong_value= args[valpos]->val_int();
+ vals[i].x.ulong_value= args[valpos]->val_int();
break;
case DYN_COL_DOUBLE:
- vals[i].double_value= args[valpos]->val_real();
+ vals[i].x.double_value= args[valpos]->val_real();
break;
case DYN_COL_STRING:
res= args[valpos]->val_str(&tmp);
if (res &&
- (vals[i].string_value.str= my_strndup(res->ptr(), res->length(),
+ (vals[i].x.string.value.str= my_strndup(res->ptr(), res->length(),
MYF(MY_WME))))
{
- vals[i].string_value.length= res->length();
- vals[i].charset= res->charset();
+ vals[i].x.string.value.length= res->length();
+ vals[i].x.string.charset= res->charset();
}
else
{
args[valpos]->null_value= 1; // In case of out of memory
- vals[i].string_value.str= NULL;
- vals[i].string_value.length= 0; // just to be safe
+ vals[i].x.string.value.str= NULL;
+ vals[i].x.string.value.length= 0; // just to be safe
}
break;
case DYN_COL_DECIMAL:
if ((dres= args[valpos]->val_decimal(&dtmp)))
{
dynamic_column_prepare_decimal(&vals[i]);
- DBUG_ASSERT(vals[i].decimal_value.len == dres->len);
- vals[i].decimal_value.intg= dres->intg;
- vals[i].decimal_value.frac= dres->frac;
- vals[i].decimal_value.sign= dres->sign();
- memcpy(vals[i].decimal_buffer, dres->buf,
- sizeof(vals[i].decimal_buffer));
+ DBUG_ASSERT(vals[i].x.decimal.value.len == dres->len);
+ vals[i].x.decimal.value.intg= dres->intg;
+ vals[i].x.decimal.value.frac= dres->frac;
+ vals[i].x.decimal.value.sign= dres->sign();
+ memcpy(vals[i].x.decimal.buffer, dres->buf,
+ sizeof(vals[i].x.decimal.buffer));
}
else
{
@@ -3648,13 +3648,13 @@ void Item_func_dyncol_create::prepare_arguments()
}
break;
case DYN_COL_DATETIME:
- args[valpos]->get_date(&vals[i].time_value, TIME_FUZZY_DATE);
+ args[valpos]->get_date(&vals[i].x.time_value, TIME_FUZZY_DATE);
break;
case DYN_COL_DATE:
- args[valpos]->get_date(&vals[i].time_value, TIME_FUZZY_DATE);
+ args[valpos]->get_date(&vals[i].x.time_value, TIME_FUZZY_DATE);
break;
case DYN_COL_TIME:
- args[valpos]->get_time(&vals[i].time_value);
+ args[valpos]->get_time(&vals[i].x.time_value);
break;
default:
DBUG_ASSERT(0);
@@ -3663,7 +3663,7 @@ void Item_func_dyncol_create::prepare_arguments()
if (vals[i].type != DYN_COL_NULL && args[valpos]->null_value)
{
if (vals[i].type == DYN_COL_STRING)
- my_free(vals[i].string_value.str, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(vals[i].x.string.value.str, MYF(MY_ALLOW_ZERO_PTR));
vals[i].type= DYN_COL_NULL;
}
}
@@ -3677,7 +3677,7 @@ void Item_func_dyncol_create::cleanup_arguments()
for (i= 0; i < column_count; i++)
{
if (vals[i].type == DYN_COL_STRING)
- my_free(vals[i].string_value.str, MYF(MY_ALLOW_ZERO_PTR));
+ my_free(vals[i].x.string.value.str, MYF(MY_ALLOW_ZERO_PTR));
}
}
@@ -3894,19 +3894,19 @@ String *Item_dyncol_get::val_str(String *str_result)
goto null;
case DYN_COL_INT:
case DYN_COL_UINT:
- str_result->set_int(val.long_value, test(val.type == DYN_COL_UINT),
+ str_result->set_int(val.x.long_value, test(val.type == DYN_COL_UINT),
&my_charset_latin1);
break;
case DYN_COL_DOUBLE:
- str_result->set_real(val.double_value, NOT_FIXED_DEC, &my_charset_latin1);
+ str_result->set_real(val.x.double_value, NOT_FIXED_DEC, &my_charset_latin1);
break;
case DYN_COL_STRING:
- if ((char*) tmp.ptr() <= val.string_value.str &&
- (char*) tmp.ptr() + tmp.length() >= val.string_value.str)
+ if ((char*) tmp.ptr() <= val.x.string.value.str &&
+ (char*) tmp.ptr() + tmp.length() >= val.x.string.value.str)
{
/* value is allocated in tmp buffer; We have to make a copy */
- str_result->copy(val.string_value.str, val.string_value.length,
- val.charset);
+ str_result->copy(val.x.string.value.str, val.x.string.value.length,
+ val.x.string.charset);
}
else
{
@@ -3915,24 +3915,24 @@ String *Item_dyncol_get::val_str(String *str_result)
into a field or in a buffer for another item and this buffer
is not going to be deleted during expression evaluation
*/
- str_result->set(val.string_value.str, val.string_value.length,
- val.charset);
+ str_result->set(val.x.string.value.str, val.x.string.value.length,
+ val.x.string.charset);
}
break;
case DYN_COL_DECIMAL:
{
int res;
int length=
- my_decimal_string_length((const my_decimal*)&val.decimal_value);
+ my_decimal_string_length((const my_decimal*)&val.x.decimal.value);
if (str_result->alloc(length))
goto null;
- if ((res= decimal2string(&val.decimal_value, (char*) str_result->ptr(),
+ if ((res= decimal2string(&val.x.decimal.value, (char*) str_result->ptr(),
&length, 0, 0, ' ')) != E_DEC_OK)
{
char buff[40];
int len= sizeof(buff);
DBUG_ASSERT(length < (int)sizeof(buff));
- decimal2string(&val.decimal_value, buff, &len, 0, 0, ' ');
+ decimal2string(&val.x.decimal.value, buff, &len, 0, 0, ' ');
decimal_operation_results(res, buff, "CHAR");
}
str_result->set_charset(&my_charset_latin1);
@@ -3950,7 +3950,7 @@ String *Item_dyncol_get::val_str(String *str_result)
asked to return the time argument as a string.
*/
if (str_result->alloc(MAX_DATE_STRING_REP_LENGTH) ||
- !(length= my_TIME_to_str(&val.time_value, (char*) str_result->ptr(),
+ !(length= my_TIME_to_str(&val.x.time_value, (char*) str_result->ptr(),
AUTO_SEC_PART_DIGITS)))
goto null;
str_result->set_charset(&my_charset_latin1);
@@ -3980,20 +3980,20 @@ longlong Item_dyncol_get::val_int()
goto null;
case DYN_COL_UINT:
unsigned_flag= 1; // Make it possible for caller to detect sign
- return val.long_value;
+ return val.x.long_value;
case DYN_COL_INT:
unsigned_flag= 0; // Make it possible for caller to detect sign
- return val.long_value;
+ return val.x.long_value;
case DYN_COL_DOUBLE:
{
bool error;
longlong num;
- num= double_to_longlong(val.double_value, unsigned_flag, &error);
+ num= double_to_longlong(val.x.double_value, unsigned_flag, &error);
if (error)
{
char buff[30];
- sprintf(buff, "%lg", val.double_value);
+ sprintf(buff, "%lg", val.x.double_value);
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_DATA_OVERFLOW,
ER(ER_DATA_OVERFLOW),
@@ -4006,14 +4006,14 @@ longlong Item_dyncol_get::val_int()
{
int error;
longlong num;
- char *end= val.string_value.str + val.string_value.length, *org_end= end;
+ char *end= val.x.string.value.str + val.x.string.value.length, *org_end= end;
- num= my_strtoll10(val.string_value.str, &end, &error);
+ num= my_strtoll10(val.x.string.value.str, &end, &error);
if (end != org_end || error > 0)
{
char buff[80];
- strmake(buff, val.string_value.str, min(sizeof(buff)-1,
- val.string_value.length));
+ strmake(buff, val.x.string.value.str, min(sizeof(buff)-1,
+ val.x.string.value.length));
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_BAD_DATA,
ER(ER_BAD_DATA),
@@ -4026,18 +4026,18 @@ longlong Item_dyncol_get::val_int()
case DYN_COL_DECIMAL:
{
longlong num;
- my_decimal2int(E_DEC_FATAL_ERROR, &val.decimal_value, unsigned_flag,
+ my_decimal2int(E_DEC_FATAL_ERROR, &val.x.decimal.value, unsigned_flag,
&num);
return num;
}
case DYN_COL_DATETIME:
case DYN_COL_DATE:
case DYN_COL_TIME:
- unsigned_flag= !val.time_value.neg;
+ unsigned_flag= !val.x.time_value.neg;
if (unsigned_flag)
- return TIME_to_ulonglong(&val.time_value);
+ return TIME_to_ulonglong(&val.x.time_value);
else
- return -(longlong)TIME_to_ulonglong(&val.time_value);
+ return -(longlong)TIME_to_ulonglong(&val.x.time_value);
}
null:
@@ -4059,24 +4059,24 @@ double Item_dyncol_get::val_real()
case DYN_COL_NULL:
goto null;
case DYN_COL_UINT:
- return ulonglong2double(val.ulong_value);
+ return ulonglong2double(val.x.ulong_value);
case DYN_COL_INT:
- return (double) val.long_value;
+ return (double) val.x.long_value;
case DYN_COL_DOUBLE:
- return (double) val.double_value;
+ return (double) val.x.double_value;
case DYN_COL_STRING:
{
int error;
char *end;
- double res= my_strntod(val.charset, (char*) val.string_value.str,
- val.string_value.length, &end, &error);
+ double res= my_strntod(val.x.string.charset, (char*) val.x.string.value.str,
+ val.x.string.value.length, &end, &error);
- if (end != (char*) val.string_value.str + val.string_value.length ||
+ if (end != (char*) val.x.string.value.str + val.x.string.value.length ||
error)
{
char buff[80];
- strmake(buff, val.string_value.str, min(sizeof(buff)-1,
- val.string_value.length));
+ strmake(buff, val.x.string.value.str, min(sizeof(buff)-1,
+ val.x.string.value.length));
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_BAD_DATA,
ER(ER_BAD_DATA),
@@ -4088,13 +4088,13 @@ double Item_dyncol_get::val_real()
{
double res;
/* This will always succeed */
- decimal2double(&val.decimal_value, &res);
+ decimal2double(&val.x.decimal.value, &res);
return res;
}
case DYN_COL_DATETIME:
case DYN_COL_DATE:
case DYN_COL_TIME:
- return TIME_to_double(&val.time_value);
+ return TIME_to_double(&val.x.time_value);
}
null:
@@ -4116,22 +4116,22 @@ my_decimal *Item_dyncol_get::val_decimal(my_decimal *decimal_value)
case DYN_COL_NULL:
goto null;
case DYN_COL_UINT:
- int2my_decimal(E_DEC_FATAL_ERROR, val.long_value, TRUE, decimal_value);
+ int2my_decimal(E_DEC_FATAL_ERROR, val.x.long_value, TRUE, decimal_value);
break;
case DYN_COL_INT:
- int2my_decimal(E_DEC_FATAL_ERROR, val.long_value, FALSE, decimal_value);
+ int2my_decimal(E_DEC_FATAL_ERROR, val.x.long_value, FALSE, decimal_value);
break;
case DYN_COL_DOUBLE:
- double2my_decimal(E_DEC_FATAL_ERROR, val.double_value, decimal_value);
+ double2my_decimal(E_DEC_FATAL_ERROR, val.x.double_value, decimal_value);
break;
case DYN_COL_STRING:
{
int rc;
- rc= str2my_decimal(0, val.string_value.str, val.string_value.length,
- val.charset, decimal_value);
+ rc= str2my_decimal(0, val.x.string.value.str, val.x.string.value.length,
+ val.x.string.charset, decimal_value);
char buff[80];
- strmake(buff, val.string_value.str, min(sizeof(buff)-1,
- val.string_value.length));
+ strmake(buff, val.x.string.value.str, min(sizeof(buff)-1,
+ val.x.string.value.length));
if (rc != E_DEC_OK)
{
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
@@ -4142,14 +4142,14 @@ my_decimal *Item_dyncol_get::val_decimal(my_decimal *decimal_value)
break;
}
case DYN_COL_DECIMAL:
- decimal2my_decimal(&val.decimal_value, decimal_value);
+ decimal2my_decimal(&val.x.decimal.value, decimal_value);
break;
case DYN_COL_DATETIME:
case DYN_COL_DATE:
case DYN_COL_TIME:
- decimal_value= seconds2my_decimal(val.time_value.neg,
- TIME_to_ulonglong(&val.time_value),
- val.time_value.second_part,
+ decimal_value= seconds2my_decimal(val.x.time_value.neg,
+ TIME_to_ulonglong(&val.x.time_value),
+ val.x.time_value.second_part,
decimal_value);
break;
}
@@ -4178,36 +4178,36 @@ bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
signed_value= 1; // For error message
/* fall_trough */
case DYN_COL_UINT:
- if (signed_value || val.ulong_value <= LONGLONG_MAX)
+ if (signed_value || val.x.ulong_value <= LONGLONG_MAX)
{
- if (int_to_datetime_with_warn(val.ulong_value, ltime, fuzzy_date,
+ if (int_to_datetime_with_warn(val.x.ulong_value, ltime, fuzzy_date,
0 /* TODO */))
goto null;
return 0;
}
/* let double_to_datetime_with_warn() issue the warning message */
- val.double_value= static_cast<double>(ULONGLONG_MAX);
+ val.x.double_value= static_cast<double>(ULONGLONG_MAX);
/* fall_trough */
case DYN_COL_DOUBLE:
- if (double_to_datetime_with_warn(val.double_value, ltime, fuzzy_date,
+ if (double_to_datetime_with_warn(val.x.double_value, ltime, fuzzy_date,
0 /* TODO */))
goto null;
return 0;
case DYN_COL_DECIMAL:
- if (decimal_to_datetime_with_warn((my_decimal*)&val.decimal_value, ltime,
+ if (decimal_to_datetime_with_warn((my_decimal*)&val.x.decimal.value, ltime,
fuzzy_date, 0 /* TODO */))
goto null;
return 0;
case DYN_COL_STRING:
- if (str_to_datetime_with_warn(val.string_value.str,
- val.string_value.length,
+ if (str_to_datetime_with_warn(val.x.string.value.str,
+ val.x.string.value.length,
ltime, fuzzy_date) <= MYSQL_TIMESTAMP_ERROR)
goto null;
return 0;
case DYN_COL_DATETIME:
case DYN_COL_DATE:
case DYN_COL_TIME:
- *ltime= val.time_value;
+ *ltime= val.x.time_value;
return 0;
}
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 32e94d3226f..6134903fee6 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -38,11 +38,14 @@ Item_subselect::Item_subselect():
Item_result_field(), value_assigned(0), own_engine(0), thd(0), old_engine(0),
used_tables_cache(0), have_to_be_excluded(0), const_item_cache(1),
inside_first_fix_fields(0), done_first_fix_fields(FALSE),
- substitution(0), expr_cache(0), engine(0), forced_const(FALSE), eliminated(FALSE),
+ expr_cache(0), forced_const(FALSE), substitution(0), engine(0), eliminated(FALSE),
engine_changed(0), changed(0), is_correlated(FALSE)
{
DBUG_ENTER("Item_subselect::Item_subselect");
DBUG_PRINT("enter", ("this: 0x%lx", (ulong) this));
+#ifndef DBUG_OFF
+ exec_counter= 0;
+#endif
with_subselect= 1;
reset();
/*
@@ -125,11 +128,14 @@ void Item_subselect::cleanup()
}
if (engine)
engine->cleanup();
- depends_on.empty();
reset();
value_assigned= 0;
expr_cache= 0;
forced_const= FALSE;
+ DBUG_PRINT("info", ("exec_counter: %d", exec_counter));
+#ifndef DBUG_OFF
+ exec_counter= 0;
+#endif
DBUG_VOID_RETURN;
}
@@ -152,14 +158,32 @@ void Item_in_subselect::cleanup()
delete left_expr_cache;
left_expr_cache= NULL;
}
+ /*
+ TODO: This breaks the commented assert in add_strategy().
+ in_strategy&= ~SUBS_STRATEGY_CHOSEN;
+ */
first_execution= TRUE;
- if (in_strategy & SUBS_MATERIALIZATION)
- in_strategy= 0;
pushed_cond_guards= NULL;
Item_subselect::cleanup();
DBUG_VOID_RETURN;
}
+
+void Item_allany_subselect::cleanup()
+{
+ /*
+ The MAX/MIN transformation through injection is reverted through the
+ change_item_tree() mechanism. Revert the select_lex object of the
+ query to its initial state.
+ */
+ for (SELECT_LEX *sl= unit->first_select();
+ sl; sl= sl->next_select())
+ if (test_strategy(SUBS_MAXMIN_INJECTED))
+ sl->with_sum_func= false;
+ Item_in_subselect::cleanup();
+}
+
+
Item_subselect::~Item_subselect()
{
DBUG_ENTER("Item_subselect::~Item_subselect");
@@ -206,7 +230,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
return TRUE;
-
+
if (!(res= engine->prepare()))
{
// all transformation is done (used by prepared statements)
@@ -469,12 +493,12 @@ void Item_subselect::recalc_used_tables(st_select_lex *new_parent,
upper->item->walk(&Item::enumerate_field_refs_processor, FALSE,
(uchar*)&fixer);
used_tables_cache |= fixer.used_tables;
- /*
+ upper->item->walk(&Item::update_table_bitmaps_processor, FALSE, NULL);
+/*
if (after_pullout)
upper->item->fix_after_pullout(new_parent, &(upper->item));
upper->item->update_used_tables();
- used_tables_cache |= upper->item->used_tables();
- */
+*/
}
}
}
@@ -492,6 +516,20 @@ void Item_subselect::recalc_used_tables(st_select_lex *new_parent,
bool Item_subselect::walk(Item_processor processor, bool walk_subquery,
uchar *argument)
{
+ if (!(unit->uncacheable & ~UNCACHEABLE_DEPENDENT) && engine->is_executed() &&
+ !unit->describe)
+ {
+ /*
+ The subquery has already been executed (for real, it wasn't EXPLAIN's
+ fake execution) so it should not matter what it has inside.
+
+ The actual reason for not walking inside is that parts of the subquery
+ (e.g. JTBM join nests and their IN-equality conditions may have been
+ invalidated by irreversible cleanups (those happen after an uncorrelated
+ subquery has been executed).
+ */
+ return FALSE;
+ }
if (walk_subquery)
{
@@ -548,7 +586,9 @@ bool Item_subselect::exec()
DBUG_EXECUTE_IF("subselect_exec_fail", return 1;);
res= engine->exec();
-
+#ifndef DBUG_OFF
+ ++exec_counter;
+#endif
if (engine_changed)
{
engine_changed= 0;
@@ -558,6 +598,14 @@ bool Item_subselect::exec()
}
+void Item_subselect::get_cache_parameters(List<Item> &parameters)
+{
+ Collect_deps_prm prm= {&parameters,
+ unit->first_select()->nest_level_base,
+ unit->first_select()->nest_level};
+ walk(&Item::collect_outer_ref_processor, TRUE, (uchar*)&prm);
+}
+
int Item_in_subselect::optimize(double *out_rows, double *cost)
{
int res;
@@ -622,7 +670,7 @@ int Item_in_subselect::optimize(double *out_rows, double *cost)
bool Item_subselect::expr_cache_is_needed(THD *thd)
{
- return (depends_on.elements &&
+ return ((engine->uncacheable() & UNCACHEABLE_DEPENDENT) &&
engine->cols() == 1 &&
optimizer_flag(thd, OPTIMIZER_SWITCH_SUBQUERY_CACHE) &&
!(engine->uncacheable() & (UNCACHEABLE_RAND |
@@ -650,8 +698,7 @@ bool Item_subselect::expr_cache_is_needed(THD *thd)
bool Item_in_subselect::expr_cache_is_needed(THD *thd)
{
- return (depends_on.elements &&
- optimizer_flag(thd, OPTIMIZER_SWITCH_SUBQUERY_CACHE) &&
+ return (optimizer_flag(thd, OPTIMIZER_SWITCH_SUBQUERY_CACHE) &&
!(engine->uncacheable() & (UNCACHEABLE_RAND |
UNCACHEABLE_SIDEEFFECT)));
}
@@ -676,7 +723,7 @@ bool Item_in_subselect::exec()
- on a cost-based basis, that takes into account the cost of a cache
lookup, the cache hit rate, and the savings per cache hit.
*/
- if (!left_expr_cache && (in_strategy & SUBS_MATERIALIZATION))
+ if (!left_expr_cache && (test_strategy(SUBS_MATERIALIZATION)))
init_left_expr_cache();
/*
@@ -793,7 +840,10 @@ Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param,
{
DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect");
max= max_arg;
- init(select_lex, new select_max_min_finder_subselect(this, max_arg));
+ init(select_lex,
+ new select_max_min_finder_subselect(this, max_arg,
+ parent->substype() ==
+ Item_subselect::ALL_SUBS));
max_columns= 1;
maybe_null= 1;
max_columns= 1;
@@ -984,7 +1034,7 @@ Item* Item_singlerow_subselect::expr_cache_insert_transformer(uchar *thd_arg)
DBUG_RETURN(expr_cache);
if (expr_cache_is_needed(thd) &&
- (expr_cache= set_expr_cache(thd, depends_on)))
+ (expr_cache= set_expr_cache(thd)))
DBUG_RETURN(expr_cache);
DBUG_RETURN(this);
}
@@ -1136,9 +1186,11 @@ bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg)
Item_in_subselect::Item_in_subselect(Item * left_exp,
st_select_lex *select_lex):
- Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
- optimizer(0), pushed_cond_guards(NULL), in_strategy(0),
- is_jtbm_merged(FALSE), is_flattenable_semijoin(FALSE),
+ Item_exists_subselect(),
+ left_expr_cache(0), first_execution(TRUE), in_strategy(SUBS_NOT_TRANSFORMED),
+ optimizer(0), pushed_cond_guards(NULL), emb_on_expr_nest(NULL),
+ is_jtbm_merged(FALSE), is_flattenable_semijoin(FALSE),
+ is_registered_semijoin(FALSE),
upper_item(0)
{
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
@@ -1244,7 +1296,7 @@ Item* Item_exists_subselect::expr_cache_insert_transformer(uchar *thd_arg)
DBUG_RETURN(expr_cache);
if (substype() == EXISTS_SUBS && expr_cache_is_needed(thd) &&
- (expr_cache= set_expr_cache(thd, depends_on)))
+ (expr_cache= set_expr_cache(thd)))
DBUG_RETURN(expr_cache);
DBUG_RETURN(this);
}
@@ -1398,9 +1450,9 @@ String *Item_in_subselect::val_str(String *str)
bool Item_in_subselect::val_bool()
{
DBUG_ASSERT(fixed == 1);
- null_value= was_null= FALSE;
if (forced_const)
return value;
+ null_value= was_null= FALSE;
if (exec())
{
reset();
@@ -1557,7 +1609,7 @@ Item_in_subselect::single_value_transformer(JOIN *join)
bool Item_allany_subselect::transform_into_max_min(JOIN *join)
{
DBUG_ENTER("Item_allany_subselect::transform_into_max_min");
- if (!(in_strategy & SUBS_MAXMIN))
+ if (!test_strategy(SUBS_MAXMIN_INJECTED | SUBS_MAXMIN_ENGINE))
DBUG_RETURN(false);
Item **place= optimizer->arguments() + 1;
THD *thd= join->thd;
@@ -1568,11 +1620,20 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
*/
DBUG_ASSERT(!substitution);
- if (!select_lex->group_list.elements &&
- !select_lex->having &&
- !select_lex->with_sum_func &&
- !(select_lex->next_select()) &&
- select_lex->table_list.elements)
+ /*
+ Check if optimization with aggregate min/max possible
+ 1 There is no aggregate in the subquery
+ 2 It is not UNION
+ 3 There is tables
+ 4 It is not ALL subquery with possible NULLs in the SELECT list
+ */
+ if (!select_lex->group_list.elements && /*1*/
+ !select_lex->having && /*1*/
+ !select_lex->with_sum_func && /*1*/
+ !(select_lex->next_select()) && /*2*/
+ select_lex->table_list.elements && /*3*/
+ (!select_lex->ref_pointer_array[0]->maybe_null || /*4*/
+ substype() != Item_subselect::ALL_SUBS)) /*4*/
{
Item_sum_hybrid *item;
nesting_map save_allow_sum_func;
@@ -1617,6 +1678,12 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
if (join->prepare_stage2())
DBUG_RETURN(true);
subs= new Item_singlerow_subselect(select_lex);
+
+ /*
+ Remove other strategies if any (we already changed the query and
+ can't apply other strategy).
+ */
+ set_strategy(SUBS_MAXMIN_INJECTED);
}
else
{
@@ -1624,9 +1691,17 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
subs= item= new Item_maxmin_subselect(thd, this, select_lex, func->l_op());
if (upper_item)
upper_item->set_sub_test(item);
+ /*
+ Remove other strategies if any (we already changed the query and
+ can't apply other strategy).
+ */
+ set_strategy(SUBS_MAXMIN_ENGINE);
}
- /* fix fields is already called for left expression */
- subs= func->create(left_expr, subs);
+ /*
+ The swap is needed for expressions of type 'f1 < ALL ( SELECT ....)'
+ where we want to evaluate the sub query even if f1 would be null.
+ */
+ subs= func->create_swap(*(optimizer->get_cache()), subs);
thd->change_item_tree(place, subs);
if (subs->fix_fields(thd, &subs))
DBUG_RETURN(true);
@@ -1634,11 +1709,6 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
select_lex->master_unit()->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
select_lex->uncacheable&= ~UNCACHEABLE_DEPENDENT_INJECTED;
- /*
- Remove other strategies if there was (we already changed the query and
- can't apply other strategy).
- */
- in_strategy= SUBS_MAXMIN;
DBUG_RETURN(false);
}
@@ -1662,7 +1732,7 @@ bool Item_allany_subselect::is_maxmin_applicable(JOIN *join)
Check if max/min optimization applicable: It is top item of
WHERE condition.
*/
- return (abort_on_null || (upper_item && upper_item->top_level())) &&
+ return (abort_on_null || (upper_item && upper_item->is_top_level_item())) &&
!join->select_lex->master_unit()->uncacheable && !func->eqne_op();
}
@@ -2212,7 +2282,12 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
{
/* The argument list of the top-level AND may change after fix fields. */
and_args= ((Item_cond*) join_arg->conds)->argument_list();
- and_args->concat((List<Item> *) &join_arg->cond_equal->current_level);
+ List_iterator<Item_equal> li(join_arg->cond_equal->current_level);
+ Item_equal *elem;
+ while ((elem= li++))
+ {
+ and_args->push_back(elem);
+ }
}
}
@@ -2340,7 +2415,7 @@ err:
void Item_in_subselect::print(String *str, enum_query_type query_type)
{
- if (in_strategy & SUBS_IN_TO_EXISTS)
+ if (test_strategy(SUBS_IN_TO_EXISTS))
str->append(STRING_WITH_LEN("<exists>"));
else
{
@@ -2356,7 +2431,7 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
uint outer_cols_num;
List<Item> *inner_cols;
- if (in_strategy & SUBS_SEMI_JOIN)
+ if (test_strategy(SUBS_SEMI_JOIN))
return !( (*ref)= new Item_int(1));
/*
@@ -2410,7 +2485,6 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
return TRUE;
if (Item_subselect::fix_fields(thd_arg, ref))
return TRUE;
-
fixed= TRUE;
return FALSE;
}
@@ -2420,6 +2494,7 @@ void Item_in_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref)
{
left_expr->fix_after_pullout(new_parent, &left_expr);
Item_subselect::fix_after_pullout(new_parent, ref);
+ used_tables_cache |= left_expr->used_tables();
}
void Item_in_subselect::update_used_tables()
@@ -2531,8 +2606,8 @@ bool
Item_allany_subselect::select_transformer(JOIN *join)
{
DBUG_ENTER("Item_allany_subselect::select_transformer");
- DBUG_ASSERT((in_strategy & ~(SUBS_MAXMIN | SUBS_IN_TO_EXISTS)) == 0);
- in_strategy|= SUBS_IN_TO_EXISTS;
+ DBUG_ASSERT((in_strategy & ~(SUBS_MAXMIN_INJECTED | SUBS_MAXMIN_ENGINE |
+ SUBS_IN_TO_EXISTS | SUBS_STRATEGY_CHOSEN)) == 0);
if (upper_item)
upper_item->show= 1;
DBUG_RETURN(select_in_like_transformer(join));
@@ -2541,7 +2616,7 @@ Item_allany_subselect::select_transformer(JOIN *join)
void Item_allany_subselect::print(String *str, enum_query_type query_type)
{
- if (in_strategy & SUBS_IN_TO_EXISTS)
+ if (test_strategy(SUBS_IN_TO_EXISTS))
str->append(STRING_WITH_LEN("<exists>"));
else
{
@@ -2920,7 +2995,7 @@ int subselect_single_select_engine::exec()
executed= 1;
thd->where= save_where;
thd->lex->current_select= save_select;
- DBUG_RETURN(join->error||thd->is_fatal_error);
+ DBUG_RETURN(join->error || thd->is_fatal_error || thd->is_error());
}
thd->where= save_where;
thd->lex->current_select= save_select;
@@ -3856,9 +3931,10 @@ subselect_hash_sj_engine::get_strategy_using_data()
bitmap_set_bit(&non_null_key_parts, i);
--count_partial_match_columns;
}
- if (result_sink->get_null_count_of_col(i) ==
- tmp_table->file->stats.records)
+ if (result_sink->get_null_count_of_col(i) == tmp_table->file->stats.records)
++count_null_only_columns;
+ if (result_sink->get_null_count_of_col(i))
+ ++count_columns_with_nulls;
}
/* If no column contains NULLs use regular hash index lookups. */
@@ -4334,7 +4410,13 @@ double get_fanout_with_deps(JOIN *join, table_map tset)
for (JOIN_TAB *tab= first_top_level_tab(join, WITHOUT_CONST_TABLES); tab;
tab= next_top_level_tab(join, tab))
{
- if ((tab->table->map & checked_deps) && !tab->emb_sj_nest &&
+ /*
+ Ignore SJM nests. They have tab->table==NULL. There is no point to walk
+ inside them, because GROUP BY clause cannot refer to tables from within
+ subquery.
+ */
+ if (!tab->is_sjm_nest() && (tab->table->map & checked_deps) &&
+ !tab->emb_sj_nest &&
tab->records_read != 0)
{
fanout *= rows2double(tab->records_read);
@@ -4524,7 +4606,8 @@ int subselect_hash_sj_engine::exec()
/* The subquery should be optimized, and materialized only once. */
DBUG_ASSERT(materialize_join->optimized && !is_materialized);
materialize_join->exec();
- if ((res= test(materialize_join->error || thd->is_fatal_error)))
+ if ((res= test(materialize_join->error || thd->is_fatal_error ||
+ thd->is_error())))
goto err;
/*
@@ -4565,29 +4648,50 @@ int subselect_hash_sj_engine::exec()
if (strategy == PARTIAL_MATCH)
{
uint count_pm_keys; /* Total number of keys needed for partial matching. */
- MY_BITMAP *nn_key_parts; /* The key parts of the only non-NULL index. */
- uint covering_null_row_width;
+ MY_BITMAP *nn_key_parts= NULL; /* Key parts of the only non-NULL index. */
+ uint count_non_null_columns= 0; /* Number of columns in nn_key_parts. */
+ bool has_covering_null_row;
+ bool has_covering_null_columns;
select_materialize_with_stats *result_sink=
(select_materialize_with_stats *) result;
+ uint field_count= tmp_table->s->fields;
- nn_key_parts= (count_partial_match_columns < tmp_table->s->fields) ?
- &non_null_key_parts : NULL;
+ if (count_partial_match_columns < field_count)
+ {
+ nn_key_parts= &non_null_key_parts;
+ count_non_null_columns= bitmap_bits_set(nn_key_parts);
+ }
+ has_covering_null_row= (result_sink->get_max_nulls_in_row() == field_count);
+ has_covering_null_columns= (count_non_null_columns +
+ count_null_only_columns == field_count);
- if (result_sink->get_max_nulls_in_row() ==
- tmp_table->s->fields -
- (nn_key_parts ? bitmap_bits_set(nn_key_parts) : 0))
- covering_null_row_width= result_sink->get_max_nulls_in_row();
- else
- covering_null_row_width= 0;
+ if (has_covering_null_row && has_covering_null_columns)
+ {
+ /*
+ The whole table consist of only NULL values. The result of IN is
+ a constant UNKNOWN.
+ */
+ DBUG_ASSERT(tmp_table->file->stats.records == 1);
+ item_in->value= 0;
+ item_in->null_value= 1;
+ item_in->make_const();
+ item_in->set_first_execution();
+ DBUG_RETURN(FALSE);
+ }
- if (covering_null_row_width)
- count_pm_keys= nn_key_parts ? 1 : 0;
+ if (has_covering_null_row)
+ {
+ DBUG_ASSERT(count_partial_match_columns = field_count);
+ count_pm_keys= 0;
+ }
+ else if (has_covering_null_columns)
+ count_pm_keys= 1;
else
count_pm_keys= count_partial_match_columns - count_null_only_columns +
- (nn_key_parts ? 1 : 0);
+ (nn_key_parts ? 1 : 0);
choose_partial_match_strategy(test(nn_key_parts),
- test(covering_null_row_width),
+ has_covering_null_row,
&partial_match_key_parts);
DBUG_ASSERT(strategy == PARTIAL_MATCH_MERGE ||
strategy == PARTIAL_MATCH_SCAN);
@@ -4597,7 +4701,9 @@ int subselect_hash_sj_engine::exec()
new subselect_rowid_merge_engine(thd, (subselect_uniquesubquery_engine*)
lookup_engine, tmp_table,
count_pm_keys,
- covering_null_row_width,
+ has_covering_null_row,
+ has_covering_null_columns,
+ count_columns_with_nulls,
item, result,
semi_join_conds->argument_list());
if (!pm_engine ||
@@ -4622,7 +4728,9 @@ int subselect_hash_sj_engine::exec()
lookup_engine, tmp_table,
item, result,
semi_join_conds->argument_list(),
- covering_null_row_width)))
+ has_covering_null_row,
+ has_covering_null_columns,
+ count_columns_with_nulls)))
{
/* This is an irrecoverable error. */
res= 1;
@@ -5058,49 +5166,56 @@ subselect_partial_match_engine::subselect_partial_match_engine(
TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
- uint covering_null_row_width_arg)
+ bool has_covering_null_row_arg,
+ bool has_covering_null_columns_arg,
+ uint count_columns_with_nulls_arg)
:subselect_engine(thd_arg, item_arg, result_arg),
tmp_table(tmp_table_arg), lookup_engine(engine_arg),
equi_join_conds(equi_join_conds_arg),
- covering_null_row_width(covering_null_row_width_arg)
+ has_covering_null_row(has_covering_null_row_arg),
+ has_covering_null_columns(has_covering_null_columns_arg),
+ count_columns_with_nulls(count_columns_with_nulls_arg)
{}
int subselect_partial_match_engine::exec()
{
Item_in_subselect *item_in= (Item_in_subselect *) item;
- int res;
+ int copy_res, lookup_res;
/* Try to find a matching row by index lookup. */
- res= lookup_engine->copy_ref_key_simple();
- if (res == -1)
+ copy_res= lookup_engine->copy_ref_key_simple();
+ if (copy_res == -1)
{
/* The result is FALSE based on the outer reference. */
item_in->value= 0;
item_in->null_value= 0;
return 0;
}
- else if (res == 0)
+ else if (copy_res == 0)
{
/* Search for a complete match. */
- if ((res= lookup_engine->index_lookup()))
+ if ((lookup_res= lookup_engine->index_lookup()))
{
/* An error occured during lookup(). */
item_in->value= 0;
item_in->null_value= 0;
- return res;
+ return lookup_res;
}
- else if (item_in->value)
+ else if (item_in->value || !count_columns_with_nulls)
{
/*
A complete match was found, the result of IN is TRUE.
+ If no match was found, and there are no NULLs in the materialized
+ subquery, then the result is guaranteed to be false because this
+ branch is executed when the outer reference has no NULLs as well.
Notice: (this->item == lookup_engine->item)
*/
return 0;
}
}
- if (covering_null_row_width == tmp_table->s->fields)
+ if (has_covering_null_row)
{
/*
If there is a NULL-only row that coveres all columns the result of IN
@@ -5164,7 +5279,6 @@ void subselect_partial_match_engine::print(String *str,
/*
@param non_null_key_parts
@param partial_match_key_parts A union of all single-column NULL key parts.
- @param count_partial_match_columns Number of NULL keyparts (set bits above).
@retval FALSE the engine was initialized successfully
@retval TRUE there was some (memory allocation) error during initialization,
@@ -5185,20 +5299,26 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
Item_in_subselect *item_in= (Item_in_subselect*) item;
int error;
- if (keys_count == 0)
+ if (merge_keys_count == 0)
{
+ DBUG_ASSERT(bitmap_bits_set(partial_match_key_parts) == 0 ||
+ has_covering_null_row);
/* There is nothing to initialize, we will only do regular lookups. */
return FALSE;
}
- DBUG_ASSERT(!covering_null_row_width || (covering_null_row_width &&
- keys_count == 1 &&
- non_null_key_parts));
+ /*
+ If all nullable columns contain only NULLs, there must be one index
+ over all non-null columns.
+ */
+ DBUG_ASSERT(!has_covering_null_columns ||
+ (has_covering_null_columns &&
+ merge_keys_count == 1 && non_null_key_parts));
/*
Allocate buffers to hold the merged keys and the mapping between rowids and
row numbers.
*/
- if (!(merge_keys= (Ordered_key**) thd->alloc(keys_count *
+ if (!(merge_keys= (Ordered_key**) thd->alloc(merge_keys_count *
sizeof(Ordered_key*))) ||
!(row_num_to_rowid= (uchar*) my_malloc((size_t)(row_count * rowid_length),
MYF(MY_WME))))
@@ -5217,15 +5337,13 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
}
/*
- If there is a covering NULL row, the only key that is needed is the
- only non-NULL key that is already created above. We create keys on
- NULL-able columns only if there is no covering NULL row.
+ If all nullable columns contain NULLs, the only key that is needed is the
+ only non-NULL key that is already created above.
*/
- if (!covering_null_row_width)
+ if (!has_covering_null_columns)
{
- if (bitmap_init_memroot(&matching_keys, keys_count, thd->mem_root) ||
- bitmap_init_memroot(&matching_outer_cols, keys_count, thd->mem_root) ||
- bitmap_init_memroot(&null_only_columns, keys_count, thd->mem_root))
+ if (bitmap_init_memroot(&matching_keys, merge_keys_count, thd->mem_root) ||
+ bitmap_init_memroot(&matching_outer_cols, merge_keys_count, thd->mem_root))
return TRUE;
/*
@@ -5234,31 +5352,25 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
*/
for (uint i= 0; i < partial_match_key_parts->n_bits; i++)
{
- if (!bitmap_is_set(partial_match_key_parts, i))
+ /* Skip columns that have no NULLs, or contain only NULLs. */
+ if (!bitmap_is_set(partial_match_key_parts, i) ||
+ result_sink->get_null_count_of_col(i) == row_count)
continue;
- if (result_sink->get_null_count_of_col(i) == row_count)
- {
- bitmap_set_bit(&null_only_columns, cur_keyid);
- continue;
- }
- else
- {
- merge_keys[cur_keyid]= new Ordered_key(
+ merge_keys[cur_keyid]= new Ordered_key(
cur_keyid, tmp_table,
item_in->left_expr->element_index(i),
result_sink->get_null_count_of_col(i),
result_sink->get_min_null_of_col(i),
result_sink->get_max_null_of_col(i),
row_num_to_rowid);
- if (merge_keys[cur_keyid]->init(i))
- return TRUE;
- merge_keys[cur_keyid]->first();
- }
+ if (merge_keys[cur_keyid]->init(i))
+ return TRUE;
+ merge_keys[cur_keyid]->first();
++cur_keyid;
}
}
- DBUG_ASSERT(cur_keyid == keys_count);
+ DBUG_ASSERT(cur_keyid == merge_keys_count);
/* Populate the indexes with data from the temporary table. */
if (tmp_table->file->ha_rnd_init_with_error(1))
@@ -5299,7 +5411,7 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
non_null_key->add_key(cur_rownum);
}
- for (uint i= (non_null_key ? 1 : 0); i < keys_count; i++)
+ for (uint i= (non_null_key ? 1 : 0); i < merge_keys_count; i++)
{
/*
Check if the first and only indexed column contains NULL in the curent
@@ -5316,14 +5428,14 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
tmp_table->file->ha_rnd_end();
/* Sort all the keys by their NULL selectivity. */
- my_qsort(merge_keys, keys_count, sizeof(Ordered_key*),
+ my_qsort(merge_keys, merge_keys_count, sizeof(Ordered_key*),
(qsort_cmp) cmp_keys_by_null_selectivity);
/* Sort the keys in each of the indexes. */
- for (uint i= 0; i < keys_count; i++)
+ for (uint i= 0; i < merge_keys_count; i++)
merge_keys[i]->sort_keys();
- if (init_queue(&pq, keys_count, 0, FALSE,
+ if (init_queue(&pq, merge_keys_count, 0, FALSE,
subselect_rowid_merge_engine::cmp_keys_by_cur_rownum, NULL,
0, 0))
return TRUE;
@@ -5335,10 +5447,10 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
subselect_rowid_merge_engine::~subselect_rowid_merge_engine()
{
/* None of the resources below is allocated if there are no ordered keys. */
- if (keys_count)
+ if (merge_keys_count)
{
my_free((char*) row_num_to_rowid, MYF(0));
- for (uint i= 0; i < keys_count; i++)
+ for (uint i= 0; i < merge_keys_count; i++)
delete merge_keys[i];
delete_queue(&pq);
if (tmp_table->file->inited == handler::RND)
@@ -5396,6 +5508,10 @@ subselect_rowid_merge_engine::cmp_keys_by_cur_rownum(void *arg,
Check if certain table row contains a NULL in all columns for which there is
no match in the corresponding value index.
+ @note
+ There is no need to check the columns that contain only NULLs, because
+ those are guaranteed to match.
+
@retval TRUE if a NULL row exists
@retval FALSE otherwise
*/
@@ -5403,16 +5519,14 @@ subselect_rowid_merge_engine::cmp_keys_by_cur_rownum(void *arg,
bool subselect_rowid_merge_engine::test_null_row(rownum_t row_num)
{
Ordered_key *cur_key;
- uint cur_id;
- for (uint i = 0; i < keys_count; i++)
+ for (uint i = 0; i < merge_keys_count; i++)
{
cur_key= merge_keys[i];
- cur_id= cur_key->get_keyid();
- if (bitmap_is_set(&matching_keys, cur_id))
+ if (bitmap_is_set(&matching_keys, cur_key->get_keyid()))
{
/*
- The key 'i' (with id 'cur_keyid') already matches a value in row 'row_num',
- thus we skip it as it can't possibly match a NULL.
+ The key 'i' (with id 'cur_keyid') already matches a value in row
+ 'row_num', thus we skip it as it can't possibly match a NULL.
*/
continue;
}
@@ -5435,6 +5549,8 @@ bool subselect_rowid_merge_engine::partial_match()
Ordered_key *cur_key;
rownum_t cur_row_num;
uint count_nulls_in_search_key= 0;
+ uint max_covering_null_row_len=
+ ((select_materialize_with_stats *) result)->get_max_nulls_in_row();
bool res= FALSE;
/* If there is a non-NULL key, it must be the first key in the keys array. */
@@ -5457,11 +5573,10 @@ bool subselect_rowid_merge_engine::partial_match()
}
/*
- If there is a NULL (sub)row that covers all NULL-able columns,
- then there is a guranteed partial match, and we don't need to search
- for the matching row.
- */
- if (covering_null_row_width)
+ If all nullable columns contain only NULLs, then there is a guranteed
+ partial match, and we don't need to search for a matching row.
+ */
+ if (has_covering_null_columns)
{
res= TRUE;
goto end;
@@ -5473,7 +5588,7 @@ bool subselect_rowid_merge_engine::partial_match()
Do not add the non_null_key, since it was already processed above.
*/
bitmap_clear_all(&matching_outer_cols);
- for (uint i= test(non_null_key); i < keys_count; i++)
+ for (uint i= test(non_null_key); i < merge_keys_count; i++)
{
DBUG_ASSERT(merge_keys[i]->get_column_count() == 1);
if (merge_keys[i]->get_search_key(0)->null_value)
@@ -5501,8 +5616,16 @@ bool subselect_rowid_merge_engine::partial_match()
If there is no NULL (sub)row that covers all NULL columns, and there is no
single match for any of the NULL columns, the result is FALSE.
*/
- if (pq.elements - test(non_null_key) == 0)
+ if ((pq.elements == 1 && non_null_key &&
+ max_covering_null_row_len < merge_keys_count - 1) ||
+ pq.elements == 0)
{
+ if (pq.elements == 0)
+ {
+ DBUG_ASSERT(!non_null_key); /* Must follow from the logic of this method */
+ /* This case must be handled by subselect_partial_match_engine::exec() */
+ DBUG_ASSERT(max_covering_null_row_len != tmp_table->s->fields);
+ }
res= FALSE;
goto end;
}
@@ -5511,7 +5634,6 @@ bool subselect_rowid_merge_engine::partial_match()
min_key= (Ordered_key*) queue_remove_top(&pq);
min_row_num= min_key->current();
- bitmap_copy(&matching_keys, &null_only_columns);
bitmap_set_bit(&matching_keys, min_key->get_keyid());
bitmap_union(&matching_keys, &matching_outer_cols);
if (min_key->next_same())
@@ -5547,7 +5669,7 @@ bool subselect_rowid_merge_engine::partial_match()
{
min_key= cur_key;
min_row_num= cur_row_num;
- bitmap_copy(&matching_keys, &null_only_columns);
+ bitmap_clear_all(&matching_keys);
bitmap_set_bit(&matching_keys, min_key->get_keyid());
bitmap_union(&matching_keys, &matching_outer_cols);
}
@@ -5568,6 +5690,8 @@ bool subselect_rowid_merge_engine::partial_match()
DBUG_ASSERT(FALSE);
end:
+ if (!has_covering_null_columns)
+ bitmap_clear_all(&matching_keys);
queue_remove_all(&pq);
tmp_table->file->ha_rnd_end();
return res;
@@ -5580,10 +5704,14 @@ subselect_table_scan_engine::subselect_table_scan_engine(
Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
- uint covering_null_row_width_arg)
+ bool has_covering_null_row_arg,
+ bool has_covering_null_columns_arg,
+ uint count_columns_with_nulls_arg)
:subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg, item_arg,
result_arg, equi_join_conds_arg,
- covering_null_row_width_arg)
+ has_covering_null_row_arg,
+ has_covering_null_columns_arg,
+ count_columns_with_nulls_arg)
{}
@@ -5622,10 +5750,6 @@ bool subselect_table_scan_engine::partial_match()
tmp_table->file->extra_opt(HA_EXTRA_CACHE,
current_thd->variables.read_buff_size);
- /*
- TIMOUR:
- scan_table() also calls "table->null_row= 0;", why, do we need it?
- */
for (;;)
{
error= tmp_table->file->ha_rnd_next(tmp_table->record[0]);
@@ -5674,3 +5798,4 @@ end:
void subselect_table_scan_engine::cleanup()
{
}
+
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 5342e4e754e..0ec0969e0ae 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -52,6 +52,17 @@ protected:
bool inside_first_fix_fields;
bool done_first_fix_fields;
+ Item *expr_cache;
+ /*
+ Set to TRUE if at optimization or execution time we determine that this
+ item's value is a constant. We need this member because it is not possible
+ to substitute 'this' with a constant item.
+ */
+ bool forced_const;
+#ifndef DBUG_OFF
+ /* Count the number of times this subquery predicate has been executed. */
+ uint exec_counter;
+#endif
public:
/*
Used inside Item_subselect::fix_fields() according to this scenario:
@@ -66,19 +77,13 @@ public:
substitution= NULL;
< Item_subselect::fix_fields
*/
+ /* TODO make this protected member again. */
Item *substitution;
- /* unit of subquery */
- st_select_lex_unit *unit;
- Item *expr_cache;
/* engine that perform execution of subselect (single select or union) */
+ /* TODO make this protected member again. */
subselect_engine *engine;
- /*
- Set to TRUE if at optimization or execution time we determine that this
- item's value is a constant. We need this member because it is not possible
- to substitute 'this' with a constant item.
- */
- bool forced_const;
-
+ /* unit of subquery */
+ st_select_lex_unit *unit;
/* A reference from inside subquery predicate to somewhere outside of it */
class Ref_to_outside : public Sql_alloc
{
@@ -97,14 +102,6 @@ public:
List<Ref_to_outside> upper_refs;
st_select_lex *parent_select;
- /**
- List of references on items subquery depends on (externally resolved);
-
- @note We can't store direct links on Items because it could be
- substituted with other item (for example for grouping).
- */
- List<Item*> depends_on;
-
/*
TRUE<=>Table Elimination has made it redundant to evaluate this select
(and so it is not part of QEP, etc)
@@ -220,6 +217,7 @@ public:
@retval FALSE otherwise
*/
bool is_expensive_processor(uchar *arg) { return TRUE; }
+
/**
Get the SELECT_LEX structure associated with this Item.
@return the SELECT_LEX structure associated with this Item
@@ -227,6 +225,7 @@ public:
st_select_lex* get_select_lex();
const char *func_name() const { DBUG_ASSERT(0); return "subselect"; }
virtual bool expr_cache_is_needed(THD *);
+ virtual void get_cache_parameters(List<Item> &parameters);
friend class select_result_interceptor;
friend class Item_in_optimizer;
@@ -354,14 +353,19 @@ TABLE_LIST * const NO_JOIN_NEST=(TABLE_LIST*)0x1;
based on user-set optimizer switches, semantic analysis and cost comparison.
*/
#define SUBS_NOT_TRANSFORMED 0 /* No execution method was chosen for this IN. */
-#define SUBS_SEMI_JOIN 1 /* IN was converted to semi-join. */
-#define SUBS_IN_TO_EXISTS 2 /* IN was converted to correlated EXISTS. */
-#define SUBS_MATERIALIZATION 4 /* Execute IN via subquery materialization. */
+/* The Final decision about the strategy is made. */
+#define SUBS_STRATEGY_CHOSEN 1
+#define SUBS_SEMI_JOIN 2 /* IN was converted to semi-join. */
+#define SUBS_IN_TO_EXISTS 4 /* IN was converted to correlated EXISTS. */
+#define SUBS_MATERIALIZATION 8 /* Execute IN via subquery materialization. */
/* Partial matching substrategies of MATERIALIZATION. */
-#define SUBS_PARTIAL_MATCH_ROWID_MERGE 8
-#define SUBS_PARTIAL_MATCH_TABLE_SCAN 16
+#define SUBS_PARTIAL_MATCH_ROWID_MERGE 16
+#define SUBS_PARTIAL_MATCH_TABLE_SCAN 32
/* ALL/ANY will be transformed with max/min optimization */
-#define SUBS_MAXMIN 32
+/* The subquery has not aggregates, transform it into a MAX/MIN query. */
+#define SUBS_MAXMIN_INJECTED 64
+/* The subquery has aggregates, use a special max/min subselect engine. */
+#define SUBS_MAXMIN_ENGINE 128
/**
@@ -396,6 +400,8 @@ protected:
Item *expr;
bool was_null;
bool abort_on_null;
+ /* A bitmap of possible execution strategies for an IN predicate. */
+ uchar in_strategy;
public:
Item_in_optimizer *optimizer;
protected:
@@ -426,7 +432,6 @@ public:
join nest pointer - the predicate is an AND-part of ON expression
of a join nest
NULL - for all other locations
- See also THD::emb_on_expr_nest.
*/
TABLE_LIST *emb_on_expr_nest;
/*
@@ -441,11 +446,7 @@ public:
*/
bool sjm_scan_allowed;
double jtbm_read_time;
- double jtbm_record_count;
-
- /* A bitmap of possible execution strategies for an IN predicate. */
- uchar in_strategy;
-
+ double jtbm_record_count;
bool is_jtbm_merged;
/*
@@ -454,6 +455,11 @@ public:
bool is_flattenable_semijoin;
/*
+ TRUE<=>registered in the list of semijoins in outer select
+ */
+ bool is_registered_semijoin;
+
+ /*
Used to determine how this subselect item is represented in the item tree,
in case there is a need to locate it there and replace with something else.
Two options are possible:
@@ -481,8 +487,8 @@ public:
Item_in_subselect(Item * left_expr, st_select_lex *select_lex);
Item_in_subselect()
:Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE),
- abort_on_null(0), optimizer(0),
- pushed_cond_guards(NULL), func(NULL), in_strategy(SUBS_NOT_TRANSFORMED),
+ abort_on_null(0), in_strategy(SUBS_NOT_TRANSFORMED), optimizer(0),
+ pushed_cond_guards(NULL), func(NULL), emb_on_expr_nest(NULL),
is_jtbm_merged(FALSE),
upper_item(0)
{}
@@ -526,6 +532,70 @@ public:
user.
*/
int get_identifier();
+
+ void mark_as_condition_AND_part(TABLE_LIST *embedding)
+ {
+ emb_on_expr_nest= embedding;
+ }
+
+ bool test_strategy(uchar strategy)
+ { return test(in_strategy & strategy); }
+
+ /**
+ Test that the IN strategy was chosen for execution. This is so
+ when the CHOSEN flag is ON, and there is no other strategy.
+ */
+ bool test_set_strategy(uchar strategy)
+ {
+ DBUG_ASSERT(strategy == SUBS_SEMI_JOIN ||
+ strategy == SUBS_IN_TO_EXISTS ||
+ strategy == SUBS_MATERIALIZATION ||
+ strategy == SUBS_PARTIAL_MATCH_ROWID_MERGE ||
+ strategy == SUBS_PARTIAL_MATCH_TABLE_SCAN ||
+ strategy == SUBS_MAXMIN_INJECTED ||
+ strategy == SUBS_MAXMIN_ENGINE);
+ return ((in_strategy & SUBS_STRATEGY_CHOSEN) &&
+ (in_strategy & ~SUBS_STRATEGY_CHOSEN) == strategy);
+ }
+
+ bool is_set_strategy()
+ { return test(in_strategy & SUBS_STRATEGY_CHOSEN); }
+
+ bool has_strategy()
+ { return in_strategy != SUBS_NOT_TRANSFORMED; }
+
+ void add_strategy (uchar strategy)
+ {
+ DBUG_ASSERT(strategy != SUBS_NOT_TRANSFORMED);
+ DBUG_ASSERT(!(strategy & SUBS_STRATEGY_CHOSEN));
+ /*
+ TODO: PS re-execution breaks this condition, because
+ check_and_do_in_subquery_rewrites() is called for each reexecution
+ and re-adds the same strategies.
+ DBUG_ASSERT(!(in_strategy & SUBS_STRATEGY_CHOSEN));
+ */
+ in_strategy|= strategy;
+ }
+
+ void reset_strategy(uchar strategy)
+ {
+ DBUG_ASSERT(strategy != SUBS_NOT_TRANSFORMED);
+ in_strategy= strategy;
+ }
+
+ void set_strategy(uchar strategy)
+ {
+ /* Check that only one strategy is set for execution. */
+ DBUG_ASSERT(strategy == SUBS_SEMI_JOIN ||
+ strategy == SUBS_IN_TO_EXISTS ||
+ strategy == SUBS_MATERIALIZATION ||
+ strategy == SUBS_PARTIAL_MATCH_ROWID_MERGE ||
+ strategy == SUBS_PARTIAL_MATCH_TABLE_SCAN ||
+ strategy == SUBS_MAXMIN_INJECTED ||
+ strategy == SUBS_MAXMIN_ENGINE);
+ in_strategy= (SUBS_STRATEGY_CHOSEN | strategy);
+ }
+
friend class Item_ref_null_helper;
friend class Item_is_not_null_test;
friend class Item_in_optimizer;
@@ -545,6 +615,7 @@ public:
Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc,
st_select_lex *select_lex, bool all);
+ void cleanup();
// only ALL subquery has upper not
subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
bool select_transformer(JOIN *join);
@@ -862,7 +933,7 @@ public:
tmp_table(NULL), is_materialized(FALSE), materialize_engine(old_engine),
materialize_join(NULL), semi_join_conds(NULL), lookup_engine(NULL),
count_partial_match_columns(0), count_null_only_columns(0),
- strategy(UNDEFINED)
+ count_columns_with_nulls(0), strategy(UNDEFINED)
{}
~subselect_hash_sj_engine();
@@ -900,6 +971,7 @@ protected:
MY_BITMAP partial_match_key_parts;
uint count_partial_match_columns;
uint count_null_only_columns;
+ uint count_columns_with_nulls;
/* Possible execution strategies that can be used to compute hash semi-join.*/
enum exec_strategy {
UNDEFINED,
@@ -1126,11 +1198,19 @@ protected:
/* A list of equalities between each pair of IN operands. */
List<Item> *equi_join_conds;
/*
- If there is a row, such that all its NULL-able components are NULL, this
- member is set to the number of covered columns. If there is no covering
- row, then this is 0.
+ True if there is an all NULL row in tmp_table. If so, then if there is
+ no complete match, there is a guaranteed partial match.
+ */
+ bool has_covering_null_row;
+
+ /*
+ True if all nullable columns of tmp_table consist of only NULL values.
+ If so, then if there is a match in the non-null columns, there is a
+ guaranteed partial match.
*/
- uint covering_null_row_width;
+ bool has_covering_null_columns;
+ uint count_columns_with_nulls;
+
protected:
virtual bool partial_match()= 0;
public:
@@ -1139,7 +1219,9 @@ public:
TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
- uint covering_null_row_width_arg);
+ bool has_covering_null_row_arg,
+ bool has_covering_null_columns_arg,
+ uint count_columns_with_nulls_arg);
int prepare() { return 0; }
int exec();
void fix_length_and_dec(Item_cache**) {}
@@ -1187,11 +1269,6 @@ protected:
*/
MY_BITMAP matching_outer_cols;
/*
- Columns that consist of only NULLs. Such columns match any value.
- Computed once per query execution.
- */
- MY_BITMAP null_only_columns;
- /*
Indexes of row numbers, sorted by <column_value, row_number>. If an
index may contain NULLs, the NULLs are stored efficiently in a bitmap.
@@ -1200,13 +1277,13 @@ protected:
non-NULL columns, it is contained in keys[0].
*/
Ordered_key **merge_keys;
- /* The number of elements in keys. */
- uint keys_count;
+ /* The number of elements in merge_keys. */
+ uint merge_keys_count;
/*
An index on all non-NULL columns of 'tmp_table'. The index has the
logical form: <[v_i1 | ... | v_ik], rownum>. It allows to find the row
number where the columns c_i1,...,c1_k contain the values v_i1,...,v_ik.
- If such an index exists, it is always the first element of 'keys'.
+ If such an index exists, it is always the first element of 'merge_keys'.
*/
Ordered_key *non_null_key;
/*
@@ -1231,15 +1308,19 @@ protected:
public:
subselect_rowid_merge_engine(THD *thd_arg,
subselect_uniquesubquery_engine *engine_arg,
- TABLE *tmp_table_arg, uint keys_count_arg,
- uint covering_null_row_width_arg,
+ TABLE *tmp_table_arg, uint merge_keys_count_arg,
+ bool has_covering_null_row_arg,
+ bool has_covering_null_columns_arg,
+ uint count_columns_with_nulls_arg,
Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg)
:subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg,
item_arg, result_arg, equi_join_conds_arg,
- covering_null_row_width_arg),
- keys_count(keys_count_arg), non_null_key(NULL)
+ has_covering_null_row_arg,
+ has_covering_null_columns_arg,
+ count_columns_with_nulls_arg),
+ merge_keys_count(merge_keys_count_arg), non_null_key(NULL)
{}
~subselect_rowid_merge_engine();
bool init(MY_BITMAP *non_null_key_parts, MY_BITMAP *partial_match_key_parts);
@@ -1258,7 +1339,9 @@ public:
TABLE *tmp_table_arg, Item_subselect *item_arg,
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
- uint covering_null_row_width_arg);
+ bool has_covering_null_row_arg,
+ bool has_covering_null_columns_arg,
+ uint count_columns_with_nulls_arg);
void cleanup();
virtual enum_engine_type engine_type() { return TABLE_SCAN_ENGINE; }
};
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index e7fe2095481..063406990cb 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -319,7 +319,6 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
if (aggr_level >= 0)
{
ref_by= ref;
- thd->lex->current_select->register_dependency_item(aggr_sel, ref);
/* Add the object to the list of registered objects assigned to aggr_sel */
if (!aggr_sel->inner_sum_func_list)
next= this;
@@ -356,6 +355,18 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref)
}
+bool Item_sum::collect_outer_ref_processor(uchar *param)
+{
+ Collect_deps_prm *prm= (Collect_deps_prm *)param;
+ SELECT_LEX *ds;
+ if ((ds= depended_from()) &&
+ ds->nest_level_base == prm->nest_level_base &&
+ ds->nest_level < prm->nest_level)
+ prm->parameters->add_unique(this, &cmp_items);
+ return FALSE;
+}
+
+
Item_sum::Item_sum(List<Item> &list) :arg_count(list.elements),
forced_const(FALSE)
{
@@ -2587,7 +2598,7 @@ bool Item_sum_count_distinct::add()
*/
return tree->unique_add(table->record[0] + table->s->null_bytes);
}
- if ((error= table->file->ha_write_row(table->record[0])) &&
+ if ((error= table->file->ha_write_tmp_row(table->record[0])) &&
table->file->is_fatal_error(error, HA_CHECK_DUP))
return TRUE;
return FALSE;
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 851b77ddeae..0d557a030d8 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -374,6 +374,7 @@ public:
virtual Field *create_tmp_field(bool group, TABLE *table,
uint convert_blob_length);
bool walk(Item_processor processor, bool walk_subquery, uchar *argument);
+ virtual bool collect_outer_ref_processor(uchar *param);
bool init_sum_func_check(THD *thd);
bool check_sum_func(THD *thd, Item **ref);
bool register_sum_func(THD *thd, Item **ref);
@@ -387,6 +388,7 @@ public:
{
return trace_unsupported_by_check_vcol_func_processor(func_name());
}
+ bool clear_sum_processor(uchar *arg) { clear(); return 0; }
};
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index b080f2e9707..3a1e3a93f72 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1370,7 +1370,8 @@ longlong Item_temporal_func::val_int()
MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE))
return 0;
- return (longlong)TIME_to_ulonglong(&ltime);
+ longlong v= TIME_to_ulonglong(&ltime);
+ return ltime.neg ? -v : v;
}
@@ -2303,7 +2304,17 @@ bool Item_date_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
return 1;
ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
ltime->time_type= MYSQL_TIMESTAMP_DATE;
- return 0;
+
+ int unused;
+ if (check_date(ltime, ltime->year || ltime->month || ltime->day,
+ fuzzy_date, &unused))
+ {
+ Lazy_string_time str(ltime);
+ make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ &str, MYSQL_TIMESTAMP_DATE, 0);
+ return (null_value= 1);
+ }
+ return (null_value= 0);
}
@@ -2425,7 +2436,6 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
long days, microseconds;
longlong seconds;
int l_sign= sign, was_cut= 0;
- uint dec= decimals;
if (is_date) // TIMESTAMP function
{
@@ -2467,10 +2477,6 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
ltime->time_type= is_time ? MYSQL_TIMESTAMP_TIME : MYSQL_TIMESTAMP_DATETIME;
- if (cached_field_type == MYSQL_TYPE_STRING &&
- (l_time1.second_part || l_time2.second_part))
- dec= TIME_SECOND_PART_DIGITS;
-
if (!is_time)
{
get_date_from_daynr(days,&ltime->year,&ltime->month,&ltime->day);
diff --git a/sql/lex.h b/sql/lex.h
index 6ab234f8d81..3041168e4fb 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -238,6 +238,7 @@ static SYMBOL symbols[] = {
{ "GRANTS", SYM(GRANTS)},
{ "GROUP", SYM(GROUP_SYM)},
{ "HANDLER", SYM(HANDLER_SYM)},
+ { "HARD", SYM(HARD_SYM)},
{ "HASH", SYM(HASH_SYM)},
{ "HAVING", SYM(HAVING)},
{ "HELP", SYM(HELP_SYM)},
@@ -496,6 +497,7 @@ static SYMBOL symbols[] = {
{ "SNAPSHOT", SYM(SNAPSHOT_SYM)},
{ "SMALLINT", SYM(SMALLINT)},
{ "SOCKET", SYM(SOCKET_SYM)},
+ { "SOFT", SYM(SOFT_SYM)},
{ "SOME", SYM(ANY_SYM)},
{ "SONAME", SYM(SONAME_SYM)},
{ "SOUNDS", SYM(SOUNDS_SYM)},
diff --git a/sql/log.cc b/sql/log.cc
index d345d0f6102..e99493945bf 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -70,7 +70,7 @@ static LEX_STRING const write_error_msg=
static my_bool opt_optimize_thread_scheduling= TRUE;
ulong binlog_checksum_options;
#ifndef DBUG_OFF
-static ulong opt_binlog_dbug_fsync_sleep= 0;
+ulong opt_binlog_dbug_fsync_sleep= 0;
#endif
static my_bool mutexes_inited;
@@ -1062,17 +1062,6 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
query_length= command_name[thd->command].length;
}
- if (!query_length)
- {
- /*
- Not a real query; Reset counts for slow query logging
- (QQ: Wonder if this is really needed)
- */
- thd->sent_row_count= thd->examined_row_count= 0;
- thd->query_plan_flags= QPLAN_INIT;
- thd->query_plan_fsort_passes= 0;
- }
-
for (current_handler= slow_log_handler_list; *current_handler ;)
error= (*current_handler++)->log_slow(thd, current_time,
user_host_buff, user_host_len,
@@ -1809,7 +1798,7 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv)
log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
log_query.append("`"))
DBUG_RETURN(1);
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
TRUE, TRUE, errcode);
DBUG_RETURN(mysql_bin_log.write(&qinfo));
@@ -1833,7 +1822,7 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
log_query.append("`"))
DBUG_RETURN(1);
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
TRUE, TRUE, errcode);
DBUG_RETURN(mysql_bin_log.write(&qinfo));
@@ -5166,7 +5155,7 @@ int query_error_code(THD *thd, bool not_killed)
{
int error;
- if (not_killed || (thd->killed == THD::KILL_BAD_DATA))
+ if (not_killed || (killed_mask_hard(thd->killed) == KILL_BAD_DATA))
{
error= thd->is_error() ? thd->main_da.sql_errno() : 0;
@@ -5175,7 +5164,8 @@ int query_error_code(THD *thd, bool not_killed)
is not set to these errors when specified not_killed by the
caller.
*/
- if (error == ER_SERVER_SHUTDOWN || error == ER_QUERY_INTERRUPTED)
+ if (error == ER_SERVER_SHUTDOWN || error == ER_QUERY_INTERRUPTED ||
+ error == ER_NEW_ABORTING_CONNECTION || error == ER_CONNECTION_KILLED)
error= 0;
}
else
@@ -7077,27 +7067,10 @@ static MYSQL_SYSVAR_ENUM(
BINLOG_CHECKSUM_ALG_OFF,
&binlog_checksum_typelib);
-#ifndef DBUG_OFF
-static MYSQL_SYSVAR_ULONG(
- dbug_fsync_sleep,
- opt_binlog_dbug_fsync_sleep,
- PLUGIN_VAR_RQCMDARG,
- "Extra sleep (in microseconds) to add to binlog fsync(), for debugging",
- NULL,
- NULL,
- 0,
- 0,
- ULONG_MAX,
- 0);
-#endif
-
static struct st_mysql_sys_var *binlog_sys_vars[]=
{
MYSQL_SYSVAR(optimize_thread_scheduling),
MYSQL_SYSVAR(checksum),
-#ifndef DBUG_OFF
- MYSQL_SYSVAR(dbug_fsync_sleep),
-#endif
NULL
};
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 3dad0c87e00..ae7a37f2b3d 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -437,6 +437,7 @@ inline bool unexpected_error_code(int unexpected_error)
case ER_NET_READ_ERROR:
case ER_NET_ERROR_ON_WRITE:
case ER_QUERY_INTERRUPTED:
+ case ER_CONNECTION_KILLED:
case ER_SERVER_SHUTDOWN:
case ER_NEW_ABORTING_CONNECTION:
return(TRUE);
@@ -3686,7 +3687,7 @@ Default database: '%s'. Query: '%s'",
{
DBUG_PRINT("info",("error ignored"));
clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
- thd->killed= THD::NOT_KILLED;
+ thd->killed= NOT_KILLED;
/*
When an error is expected and matches the actual error the
slave does not report any error and by consequence changes
diff --git a/sql/log_event.h b/sql/log_event.h
index 4053db4e3e7..ab58aac5fd0 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -3082,7 +3082,7 @@ char *str_to_hex(char *to, const char *from, uint len);
/**
@class Annotate_rows_log_event
- In row-based mode, if binlog_annotate_rows_events = ON, each group of
+ In row-based mode, if binlog_annotate_row_events = ON, each group of
Table_map_log_events is preceded by an Annotate_rows_log_event which
contains the query which caused the subsequent rows operations.
diff --git a/sql/multi_range_read.cc b/sql/multi_range_read.cc
index c666c571787..055a9268417 100644
--- a/sql/multi_range_read.cc
+++ b/sql/multi_range_read.cc
@@ -424,10 +424,10 @@ void Mrr_ordered_index_reader::interrupt_read()
{
DBUG_ASSERT(support_scan_interruptions);
TABLE *table= file->get_table();
+ KEY *used_index= &table->key_info[file->active_index];
/* Save the current key value */
key_copy(saved_key_tuple, table->record[0],
- &table->key_info[file->active_index],
- keypar.key_tuple_length);
+ used_index, used_index->key_length);
if (saved_primary_key)
{
@@ -452,9 +452,9 @@ void Mrr_ordered_index_reader::position()
void Mrr_ordered_index_reader::resume_read()
{
TABLE *table= file->get_table();
+ KEY *used_index= &table->key_info[file->active_index];
key_restore(table->record[0], saved_key_tuple,
- &table->key_info[file->active_index],
- keypar.key_tuple_length);
+ used_index, used_index->key_length);
if (saved_primary_key)
{
key_restore(table->record[0], saved_primary_key,
@@ -531,7 +531,7 @@ int Mrr_ordered_index_reader::init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
mrr_funcs= *seq_funcs;
source_exhausted= FALSE;
if (support_scan_interruptions)
- bzero(saved_key_tuple, keypar.key_tuple_length);
+ bzero(saved_key_tuple, key_info->key_length);
have_saved_rowid= FALSE;
return 0;
}
@@ -848,12 +848,14 @@ int DsMrr_impl::dsmrr_init(handler *h_arg, RANGE_SEQ_IF *seq_funcs,
if (h_idx->primary_key_is_clustered())
{
uint pk= h_idx->get_table()->s->primary_key;
- saved_pk_length= h_idx->get_table()->key_info[pk].key_length;
+ if (pk != MAX_KEY)
+ saved_pk_length= h_idx->get_table()->key_info[pk].key_length;
}
-
+
+ KEY *used_index= &h_idx->get_table()->key_info[h_idx->active_index];
if (reader_factory.ordered_index_reader.
set_interruption_temp_buffer(primary_file->ref_length,
- keypar.key_tuple_length,
+ used_index->key_length,
saved_pk_length,
&full_buf, full_buf_end))
goto use_default_impl;
@@ -1075,7 +1077,7 @@ void DsMrr_impl::close_second_handler()
{
secondary_file->ha_index_or_rnd_end();
secondary_file->ha_external_lock(current_thd, F_UNLCK);
- secondary_file->close();
+ secondary_file->ha_close();
delete secondary_file;
secondary_file= NULL;
}
@@ -1635,7 +1637,8 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
uint *buffer_size, COST_VECT *cost)
{
ulong max_buff_entries, elem_size;
- ha_rows rows_in_full_step, rows_in_last_step;
+ ha_rows rows_in_full_step;
+ ha_rows rows_in_last_step;
uint n_full_steps;
double index_read_cost;
@@ -1660,7 +1663,7 @@ bool DsMrr_impl::get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
/* Adjust buffer size if we expect to use only part of the buffer */
if (n_full_steps)
{
- get_sort_and_sweep_cost(table, rows, cost);
+ get_sort_and_sweep_cost(table, rows_in_full_step, cost);
cost->multiply(n_full_steps);
}
else
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index f12874be1ea..e335406493c 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -118,8 +118,6 @@ char *sql_strmake_with_convert(const char *str, size_t arg_length,
CHARSET_INFO *from_cs,
size_t max_res_length,
CHARSET_INFO *to_cs, size_t *result_length);
-uint kill_one_thread(THD *thd, ulong id, bool only_kill_query);
-void sql_kill(THD *thd, ulong id, bool only_kill_query);
bool net_request_file(NET* net, const char* fname);
char* query_table_status(THD *thd,const char *db,const char *table_name);
@@ -413,7 +411,6 @@ protected:
#define DELAYED_LIMIT 100 /**< pause after xxx inserts */
#define DELAYED_QUEUE_SIZE 1000
#define DELAYED_WAIT_TIMEOUT 5*60 /**< Wait for delayed insert */
-#define FLUSH_TIME 0 /**< Don't flush tables */
#define MAX_CONNECT_ERRORS 10 ///< errors before disabling host
#ifdef __NETWARE__
@@ -423,8 +420,6 @@ protected:
#endif
#if defined(__WIN__)
-#undef FLUSH_TIME
-#define FLUSH_TIME 1800 /**< Flush every half hour */
#define INTERRUPT_PRIOR -2
#define CONNECT_PRIOR -1
@@ -594,64 +589,30 @@ protected:
#define OPTIMIZER_SWITCH_JOIN_CACHE_HASHED (1ULL << 22)
#define OPTIMIZER_SWITCH_JOIN_CACHE_BKA (1ULL << 23)
#define OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE (1ULL << 24)
-#ifdef DBUG_OFF
-# define OPTIMIZER_SWITCH_LAST (1ULL << 25)
-#else
-# define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1ULL << 25)
-# define OPTIMIZER_SWITCH_LAST (1ULL << 26)
-#endif
+#define OPTIMIZER_SWITCH_TABLE_ELIMINATION (1ULL << 25)
+#define OPTIMIZER_SWITCH_LAST (1ULL << 26)
-#ifdef DBUG_OFF
/* The following must be kept in sync with optimizer_switch_str in mysqld.cc */
/*
TODO: Materialization is off by default to mimic 5.1/5.2 behavior.
Once cost based choice between materialization and in-to-exists should be
enabled by default, add OPTIMIZER_SWITCH_MATERIALIZATION
*/
-# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
- OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
- OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
- OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
- OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN | \
- OPTIMIZER_SWITCH_DERIVED_MERGE | \
- OPTIMIZER_SWITCH_DERIVED_WITH_KEYS | \
- OPTIMIZER_SWITCH_FIRSTMATCH | \
- OPTIMIZER_SWITCH_LOOSE_SCAN | \
- OPTIMIZER_SWITCH_IN_TO_EXISTS | \
- OPTIMIZER_SWITCH_SEMIJOIN | \
- OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE|\
- OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN|\
- OPTIMIZER_SWITCH_SUBQUERY_CACHE|\
- OPTIMIZER_SWITCH_MRR|\
- OPTIMIZER_SWITCH_MRR_SORT_KEYS|\
- OPTIMIZER_SWITCH_SUBQUERY_CACHE | \
- OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL | \
- OPTIMIZER_SWITCH_JOIN_CACHE_HASHED | \
- OPTIMIZER_SWITCH_JOIN_CACHE_BKA | \
- OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE)
-#else
-# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
+#define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
- OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN | \
- OPTIMIZER_SWITCH_DERIVED_MERGE | \
- OPTIMIZER_SWITCH_DERIVED_WITH_KEYS | \
OPTIMIZER_SWITCH_TABLE_ELIMINATION | \
- OPTIMIZER_SWITCH_FIRSTMATCH | \
- OPTIMIZER_SWITCH_LOOSE_SCAN | \
OPTIMIZER_SWITCH_IN_TO_EXISTS | \
- OPTIMIZER_SWITCH_SEMIJOIN | \
OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE|\
OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN|\
- OPTIMIZER_SWITCH_SUBQUERY_CACHE|\
- OPTIMIZER_SWITCH_MRR|\
- OPTIMIZER_SWITCH_MRR_SORT_KEYS|\
OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL | \
OPTIMIZER_SWITCH_JOIN_CACHE_HASHED | \
OPTIMIZER_SWITCH_JOIN_CACHE_BKA | \
- OPTIMIZER_SWITCH_OPTIMIZE_JOIN_BUFFER_SIZE)
-#endif
+ OPTIMIZER_SWITCH_SUBQUERY_CACHE |\
+ OPTIMIZER_SWITCH_SEMIJOIN | \
+ OPTIMIZER_SWITCH_FIRSTMATCH | \
+ OPTIMIZER_SWITCH_LOOSE_SCAN )
/*
Replication uses 8 bytes to store SQL_MODE in the binary log. The day you
@@ -808,17 +769,6 @@ inline THD *_current_thd(void)
#endif
#define current_thd _current_thd()
-
-/**
- The meat of thd_proc_info(THD*, char*), a macro that packs the last
- three calling-info parameters.
-*/
-extern "C"
-const char *set_thd_proc_info(THD *thd, const char *info,
- const char *calling_func,
- const char *calling_file,
- const unsigned int calling_line);
-
/**
Enumerate possible types of a table from re-execution
standpoint.
@@ -995,6 +945,7 @@ inline bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *table_list)
inline bool check_some_routine_access(THD *thd, const char *db,
const char *name, bool is_proc)
{ return false; }
+#define decrease_user_connections(X) do { } while(0) /* nothing */
#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
bool multi_update_precheck(THD *thd, TABLE_LIST *tables);
@@ -1125,6 +1076,10 @@ struct Query_cache_query_flags
#define query_cache_is_cacheable_query(L) 0
#endif /*HAVE_QUERY_CACHE*/
+uint kill_one_thread(THD *thd, ulong id, killed_state kill_signal);
+void sql_kill(THD *thd, ulong id, killed_state kill_signal);
+void sql_kill_user(THD *thd, LEX_USER *str, killed_state kill_signal);
+
/*
Error injector Macros to enable easy testing of recovery after failures
in various error cases.
@@ -1228,7 +1183,9 @@ bool init_new_connection_handler_thread();
void reset_mqh(LEX_USER *lu, bool get_them);
bool check_mqh(THD *thd, uint check_command);
void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
void decrease_user_connections(USER_CONN *uc);
+#endif
bool thd_init_client_charset(THD *thd, uint cs_number);
inline bool is_supported_parser_charset(CHARSET_INFO *cs)
{
@@ -1690,6 +1647,7 @@ bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *group,bool asc);
bool push_new_name_resolution_context(THD *thd,
TABLE_LIST *left_op,
TABLE_LIST *right_op);
+Item *normalize_cond(Item *cond);
void add_join_on(TABLE_LIST *b,Item *expr);
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields,
SELECT_LEX *lex);
@@ -2184,6 +2142,7 @@ extern ulonglong thd_startup_options;
extern ulong thread_id;
extern ulong binlog_cache_use, binlog_cache_disk_use;
extern ulong aborted_threads,aborted_connects;
+extern ulong opt_progress_report_time;
extern ulong delayed_insert_timeout;
extern ulong delayed_insert_limit, delayed_queue_size;
extern ulong delayed_insert_threads, delayed_insert_writes;
@@ -2196,14 +2155,15 @@ extern MYSQL_PLUGIN_IMPORT ulong max_connections;
extern ulong max_connect_errors, connect_timeout;
extern ulong extra_max_connections;
extern ulong slave_net_timeout, slave_trans_retries;
-extern uint max_user_connections;
+extern int max_user_connections;
+extern bool max_user_connections_checking;
extern ulonglong denied_connections;
extern ulong what_to_log,flush_time;
extern ulong query_buff_size;
extern ulong max_prepared_stmt_count, prepared_stmt_count;
extern ulong binlog_cache_size, open_files_limit;
extern ulonglong max_binlog_cache_size;
-extern ulong max_binlog_size, max_relay_log_size;
+extern ulong max_binlog_size, max_relay_log_size, opt_binlog_dbug_fsync_sleep;
extern ulong opt_binlog_rows_event_max_size;
extern my_bool opt_master_verify_checksum;
extern my_bool opt_slave_sql_verify_checksum;
@@ -2224,6 +2184,9 @@ extern uint test_flags,select_errors,ha_open_options;
extern uint protocol_version, mysqld_port, mysqld_extra_port, dropping_tables;
extern uint delay_key_write_options;
extern ulong max_long_data_size;
+extern uint internal_tmp_table_max_key_length;
+extern uint internal_tmp_table_max_key_segments;
+
#endif /* MYSQL_SERVER */
#if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS
extern MYSQL_PLUGIN_IMPORT uint lower_case_table_names;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 08794b6ab68..1d8a352b97e 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -350,9 +350,7 @@ static const char *optimizer_switch_names[]=
"join_cache_hashed",
"join_cache_bka",
"optimize_join_buffer_size",
-#ifndef DBUG_OFF
"table_elimination",
-#endif
"default", NullS
};
@@ -384,9 +382,7 @@ static const unsigned int optimizer_switch_names_len[]=
sizeof("join_cache_hashed") - 1,
sizeof("join_cache_bka") - 1,
sizeof("optimize_join_buffer_size") - 1,
-#ifndef DBUG_OFF
sizeof("table_elimination") - 1,
-#endif
sizeof("default") - 1
};
TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
@@ -485,9 +481,9 @@ static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
"index_merge_sort_union=on,"
"index_merge_intersection=on,"
"index_merge_sort_intersection=off,"
- "index_condition_pushdown=on,"
- "derived_merge=on,"
- "derived_with_keys=on,"
+ "index_condition_pushdown=off,"
+ "derived_merge=off,"
+ "derived_with_keys=off,"
"firstmatch=on,"
"loosescan=on,"
"materialization=off,"
@@ -496,17 +492,17 @@ static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
"partial_match_rowid_merge=on,"
"partial_match_table_scan=on,"
"subquery_cache=on,"
- "mrr=on,"
+ "mrr=off,"
"mrr_cost_based=off,"
- "mrr_sort_keys=on,"
+ "mrr_sort_keys=off,"
"join_cache_incremental=on,"
"join_cache_hashed=on,"
"join_cache_bka=on,"
- "optimize_join_buffer_size=on"
-#ifndef DBUG_OFF
- ",table_elimination=on";
-#else
+ "optimize_join_buffer_size=off,"
+ "table_elimination=on";
;
+#ifdef SAFEMALLOC
+my_bool sf_malloc_trough_check= 0;
#endif
static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
static char *opt_init_slave, *language_ptr, *opt_init_connect;
@@ -571,7 +567,7 @@ my_bool opt_local_infile, opt_slave_compressed_protocol;
my_bool opt_safe_user_create = 0, opt_no_mix_types = 0;
my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
my_bool opt_log_slave_updates= 0;
-my_bool opt_replicate_annotate_rows_events= 0;
+my_bool opt_replicate_annotate_row_events= 0;
bool slave_warning_issued = false;
/*
@@ -673,7 +669,12 @@ ulong extra_max_connections;
*/
ulong max_long_data_size;
-uint max_user_connections= 0;
+/* Limits for internal temporary tables (MyISAM or Aria) */
+uint internal_tmp_table_max_key_length;
+uint internal_tmp_table_max_key_segments;
+
+int max_user_connections= 0;
+bool max_user_connections_checking=0;
ulonglong denied_connections;
/**
Limit of the total number of prepared statements in the server.
@@ -706,6 +707,7 @@ char mysql_real_data_home[FN_REFLEN],
language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
*opt_init_file, *opt_tc_log_file,
def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
+const char *opt_basename;
char mysql_unpacked_real_data_home[FN_REFLEN];
int mysql_unpacked_real_data_home_len;
uint reg_ext_length;
@@ -1086,7 +1088,7 @@ static void close_connections(void)
if (tmp->slave_thread)
continue;
- tmp->killed= THD::KILL_CONNECTION;
+ tmp->killed= KILL_SERVER_HARD;
thread_scheduler.post_kill_notification(tmp);
pthread_mutex_lock(&tmp->LOCK_thd_data);
if (tmp->mysys_var)
@@ -1146,7 +1148,7 @@ static void close_connections(void)
tmp->thread_id,
(tmp->main_security_ctx.user ?
tmp->main_security_ctx.user : ""));
- close_connection(tmp,0,0);
+ close_connection(tmp,ER_SERVER_SHUTDOWN,0);
}
#endif
DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
@@ -2037,7 +2039,18 @@ void close_connection(THD *thd, uint errcode, bool lock)
errcode ? ER(errcode) : ""));
if (lock)
(void) pthread_mutex_lock(&LOCK_thread_count);
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_CONNECTION;
+
+ if (global_system_variables.log_warnings > 3)
+ {
+ Security_context *sctx= &thd->main_security_ctx;
+ sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
+ thd->thread_id,(thd->db ? thd->db : "unconnected"),
+ sctx->user ? sctx->user : "unauthenticated",
+ sctx->host_or_ip,
+ (errcode ? ER(errcode) : "CLOSE_CONNECTION"));
+ }
+
if ((vio= thd->net.vio) != 0)
{
if (errcode)
@@ -2135,6 +2148,7 @@ static bool cache_thread()
*/
thd->mysys_var->abort= 0;
thd->thr_create_utime= microsecond_interval_timer();
+ thd->start_utime= thd->thr_create_utime;
threads.append(thd);
return(1);
}
@@ -2199,24 +2213,6 @@ void flush_thread_cache()
}
-#ifdef THREAD_SPECIFIC_SIGPIPE
-/**
- Aborts a thread nicely. Comes here on SIGPIPE.
-
- @todo
- One should have to fix that thr_alarm know about this thread too.
-*/
-extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
-{
- THD *thd=current_thd;
- DBUG_ENTER("abort_thread");
- if (thd)
- thd->killed= THD::KILL_CONNECTION;
- DBUG_VOID_RETURN;
-}
-#endif
-
-
/******************************************************************************
Setup a signal thread with handles all signals.
Because Linux doesn't support schemas use a mutex to check that
@@ -2694,6 +2690,8 @@ or misconfigured. This error can also be caused by malfunctioning hardware.\n",
We will try our best to scrape up some info that will hopefully help diagnose\n\
the problem, but since we have already crashed, something is definitely wrong\n\
and this may fail.\n\n");
+ set_server_version();
+ fprintf(stderr, "Server version: %s\n", server_version);
fprintf(stderr, "key_buffer_size=%lu\n",
(ulong) dflt_key_cache->key_cache_mem_size);
fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
@@ -2739,29 +2737,47 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
{
const char *kreason= "UNKNOWN";
switch (thd->killed) {
- case THD::NOT_KILLED:
+ case NOT_KILLED:
+ case KILL_HARD_BIT:
kreason= "NOT_KILLED";
break;
- case THD::KILL_BAD_DATA:
+ case KILL_BAD_DATA:
+ case KILL_BAD_DATA_HARD:
kreason= "KILL_BAD_DATA";
break;
- case THD::KILL_CONNECTION:
+ case KILL_CONNECTION:
+ case KILL_CONNECTION_HARD:
kreason= "KILL_CONNECTION";
break;
- case THD::KILL_QUERY:
+ case KILL_QUERY:
+ case KILL_QUERY_HARD:
kreason= "KILL_QUERY";
break;
- case THD::KILLED_NO_VALUE:
- kreason= "KILLED_NO_VALUE";
+ case KILL_SYSTEM_THREAD:
+ case KILL_SYSTEM_THREAD_HARD:
+ kreason= "KILL_SYSTEM_THREAD";
+ break;
+ case KILL_SERVER:
+ case KILL_SERVER_HARD:
+ kreason= "KILL_SERVER";
break;
}
fprintf(stderr, "\nTrying to get some variables.\n"
"Some pointers may be invalid and cause the dump to abort.\n");
fprintf(stderr, "Query (%p): ", thd->query());
- my_safe_print_str(thd->query(), min(1024, thd->query_length()));
+ my_safe_print_str(thd->query(), min(65536,thd->query_length()));
fprintf(stderr, "Connection ID (thread ID): %lu\n", (ulong) thd->thread_id);
fprintf(stderr, "Status: %s\n", kreason);
- fputc('\n', stderr);
+ fprintf(stderr, "Optimizer switch: ");
+ ulonglong optsw= thd->variables.optimizer_switch;
+ for (uint i= 0; optimizer_switch_names[i+1]; i++, optsw >>= 1)
+ {
+ if (i)
+ fputc(',', stderr);
+ fprintf(stderr, "%s=%s",
+ optimizer_switch_names[i], optsw & 1 ? "on" : "off");
+ }
+ fprintf(stderr, "\n\n");
}
fprintf(stderr, "\
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
@@ -3102,7 +3118,7 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
MYSQL_ERROR::enum_warning_level level;
sql_print_message_func func;
DBUG_ENTER("my_message_sql");
- DBUG_PRINT("error", ("error: %u message: '%s'", error, str));
+ DBUG_PRINT("error", ("error: %u message: '%s' Flag: %d", error, str, MyFlags));
DBUG_ASSERT(str != NULL);
/*
@@ -3118,7 +3134,8 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
{
/* At least, prevent new abuse ... */
DBUG_ASSERT(strncmp(str, "MyISAM table", 12) == 0 ||
- strncmp(str, "Aria table", 11) == 0);
+ strncmp(str, "Aria table", 11) == 0 ||
+ (MyFlags & ME_JUST_INFO));
error= ER_UNKNOWN_ERROR;
}
@@ -3145,7 +3162,10 @@ int my_message_sql(uint error, const char *str, myf MyFlags)
this could be improved by having a common stack of handlers.
*/
if (thd->handle_error(error, str, level))
+ {
+ DBUG_PRINT("info", ("error handled by handle_error()"));
DBUG_RETURN(0);
+ }
if (level == MYSQL_ERROR::WARN_LEVEL_WARN)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, error, str);
@@ -3224,7 +3244,7 @@ to_error_log:
/* When simulating OOM, skip writing to error log to avoid mtr errors */
DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(0););
- if (!thd || (MyFlags & ME_NOREFRESH))
+ if (!thd || thd->log_all_errors || (MyFlags & ME_NOREFRESH))
(*func)("%s: %s", my_progname_short, str); /* purecov: inspected */
DBUG_RETURN(0);
}
@@ -3270,6 +3290,7 @@ const char *load_default_groups[]= {
#endif
"mysqld", "server", MYSQL_BASE_VERSION,
"mariadb", MARIADB_BASE_VERSION,
+"client-server",
0, 0};
#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
@@ -3489,7 +3510,6 @@ static int init_common_variables(const char *conf_file_name, int argc,
char **argv, const char **groups)
{
char buff[FN_REFLEN], *s;
- const char *basename;
umask(((~my_umask) & 0666));
tzset(); // Set tzname
@@ -3549,13 +3569,13 @@ static int init_common_variables(const char *conf_file_name, int argc,
strmake(glob_hostname, STRING_WITH_LEN("localhost"));
sql_print_warning("gethostname failed, using '%s' as hostname",
glob_hostname);
- basename= "mysql";
+ opt_basename= "mysql";
}
else
{
- basename= glob_hostname;
+ opt_basename= glob_hostname;
}
- strmake(pidfile_name, basename, sizeof(pidfile_name)-5);
+ strmake(pidfile_name, opt_basename, sizeof(pidfile_name)-5);
strmov(fn_ext(pidfile_name),".pid"); // Add proper extension
/*
@@ -4285,11 +4305,13 @@ a file name for --log-bin-index option", opt_binlog_index_name);
require a name. But as we don't want to break many existing setups, we
only give warning, not error.
*/
- sql_print_warning("No argument was provided to --log-bin, and "
- "--log-bin-index was not used; so replication "
- "may break when this MySQL server acts as a "
- "master and has his hostname changed!! Please "
- "use '--log-bin=%s' to avoid this problem.", ln);
+ sql_print_warning("No argument was provided to --log-bin and "
+ "neither --log-basename or --log-bin-index where "
+ "used; This may cause repliction to break when this "
+ "server acts as a master and has its hostname "
+ "changed!! Please use '--log-basename=%s' or "
+ "'--log-bin=%s' to avoid this problem.",
+ opt_basename, ln);
}
if (ln == buf)
{
@@ -4448,6 +4470,11 @@ a file name for --log-bin-index option", opt_binlog_index_name);
sql_print_error("Aria engine is not enabled or did not start. The Aria engine must be enabled to continue as mysqld was configured with --with-aria-tmp-tables");
unireg_abort(1);
}
+ internal_tmp_table_max_key_length= maria_max_key_length();
+ internal_tmp_table_max_key_segments= maria_max_key_segments();
+#else
+ internal_tmp_table_max_key_length= myisam_max_key_length();
+ internal_tmp_table_max_key_segments= myisam_max_key_segments();
#endif
tc_log= (total_ha_2pc > 1 ? (opt_bin_log ?
@@ -5259,7 +5286,7 @@ void create_thread_to_handle_connection(THD *thd)
thread_created++;
threads.append(thd);
DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
- thd->prior_thr_create_utime= thd->start_utime= microsecond_interval_timer();
+ thd->prior_thr_create_utime= microsecond_interval_timer();
if ((error=pthread_create(&thd->real_id,&connection_attrib,
handle_one_connection,
(void*) thd)))
@@ -5269,7 +5296,7 @@ void create_thread_to_handle_connection(THD *thd)
("Can't create thread to handle request (error %d)",
error));
thread_count--;
- thd->killed= THD::KILL_CONNECTION; // Safety
+ thd->killed= KILL_CONNECTION; // Safety
(void) pthread_mutex_unlock(&LOCK_thread_count);
pthread_mutex_lock(&LOCK_connection_count);
@@ -5282,7 +5309,7 @@ void create_thread_to_handle_connection(THD *thd)
ER(ER_CANT_CREATE_THREAD), error);
net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff);
(void) pthread_mutex_lock(&LOCK_thread_count);
- close_connection(thd,0,0);
+ close_connection(thd,ER_OUT_OF_RESOURCES,0);
delete thd;
(void) pthread_mutex_unlock(&LOCK_thread_count);
return;
@@ -5990,7 +6017,7 @@ enum options_mysqld
OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB,
OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES,
OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB,
- OPT_BINLOG_FORMAT,
+ OPT_BINLOG_FORMAT, OPT_DEBUG_BINLOG_FSYNC_SLEEP,
OPT_BINLOG_ANNOTATE_ROWS_EVENTS,
OPT_REPLICATE_ANNOTATE_ROWS_EVENTS,
#ifndef DBUG_OFF
@@ -6019,7 +6046,7 @@ enum options_mysqld
OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
OPT_NDB_USE_COPYING_ALTER_TABLE,
- OPT_SKIP_SAFEMALLOC, OPT_MUTEX_DEADLOCK_DETECTOR,
+ OPT_SAFEMALLOC, OPT_MUTEX_DEADLOCK_DETECTOR,
OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
OPT_SKIP_SYMLINKS,
OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
@@ -6081,7 +6108,7 @@ enum options_mysqld
OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
- OPT_WAIT_TIMEOUT,
+ OPT_WAIT_TIMEOUT, OPT_PROGRESS_REPORT_TIME,
OPT_ERROR_LOG_FILE,
OPT_DEFAULT_WEEK_FORMAT,
OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS,
@@ -6140,7 +6167,9 @@ enum options_mysqld
OPT_SECURE_FILE_PRIV,
OPT_MIN_EXAMINED_ROW_LIMIT,
OPT_LOG_SLOW_SLAVE_STATEMENTS,
- OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_DEBUG_ASSERT_IF_CRASHED_TABLE, OPT_OLD_MODE,
+ OPT_DEBUG_CRC, OPT_DEBUG_ON, OPT_DEBUG_ASSERT_IF_CRASHED_TABLE,
+ OPT_DEBUG_ASSERT_ON_ERROR,
+ OPT_OLD_MODE,
OPT_TEST_IGNORE_WRONG_OPTIONS, OPT_TEST_RESTART,
#if defined(ENABLED_DEBUG_SYNC)
OPT_DEBUG_SYNC_TIMEOUT,
@@ -6214,6 +6243,12 @@ struct my_option my_long_options[] =
{"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
&my_bind_addr_str, &my_bind_addr_str, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifndef DBUG_OFF
+ {"debug-binlog-fsync-sleep", OPT_DEBUG_BINLOG_FSYNC_SLEEP,
+ "Extra sleep (in microseconds) to add to binlog fsync(), for debugging",
+ &opt_binlog_dbug_fsync_sleep, &opt_binlog_dbug_fsync_sleep,
+ 0, GET_ULONG, REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0},
+#endif
{"binlog_format", OPT_BINLOG_FORMAT,
"Does not have any effect without '--log-bin'. "
"Tell the master the form of binary logging to use: either 'row' for "
@@ -6227,17 +6262,17 @@ struct my_option my_long_options[] =
#endif
, &opt_binlog_format, &opt_binlog_format,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"binlog-annotate-rows-events", OPT_BINLOG_ANNOTATE_ROWS_EVENTS,
+ {"binlog-annotate-row-events", OPT_BINLOG_ANNOTATE_ROWS_EVENTS,
"Tells the master to annotate RBR events with the statement that "
"caused these events.",
- (uchar**) &global_system_variables.binlog_annotate_rows_events,
- (uchar**) &max_system_variables.binlog_annotate_rows_events,
+ (uchar**) &global_system_variables.binlog_annotate_row_events,
+ (uchar**) &max_system_variables.binlog_annotate_row_events,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"replicate-annotate-rows-events", OPT_REPLICATE_ANNOTATE_ROWS_EVENTS,
+ {"replicate-annotate-row-events", OPT_REPLICATE_ANNOTATE_ROWS_EVENTS,
"Tells the slave to write annotate rows events recieved from the master "
"to its own binary log. Sensible only in pair with log-slave-updates option.",
- (uchar**) &opt_replicate_annotate_rows_events,
- (uchar**) &opt_replicate_annotate_rows_events,
+ (uchar**) &opt_replicate_annotate_row_events,
+ (uchar**) &opt_replicate_annotate_row_events,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"binlog-do-db", OPT_BINLOG_DO_DB,
"Tells the master it should log updates for the specified database, "
@@ -6330,6 +6365,10 @@ struct my_option my_long_options[] =
"Do an assert in handler::print_error() if we get a crashed table",
&debug_assert_if_crashed_table, &debug_assert_if_crashed_table,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"debug-assert-on-error", OPT_DEBUG_ASSERT_ON_ERROR,
+ "Do an assert in various functions if we get a fatal error",
+ &my_assert_on_error, &my_assert_on_error,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"default-character-set", OPT_DEFAULT_CHARACTER_SET_OLD,
"Set the default character set (deprecated option, use --character-set-server instead).",
@@ -6417,8 +6456,8 @@ struct my_option my_long_options[] =
&opt_debugging, &opt_debugging,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"general_log", OPT_GENERAL_LOG,
- "Enable/disable general log. Filename can be specified with --general-log-file or --log-basename. Is 'hostname.err' by default.",
- &opt_log, &opt_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ "Enable/disable general log. Filename can be specified with --general-log-file or --log-basename. Is 'hostname.log' by default.",
+ &opt_log, &opt_log, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef HAVE_LARGE_PAGES
{"large-pages", OPT_ENABLE_LARGE_PAGES, "Enable support for large pages. "
"Disable with --skip-large-pages.", &opt_large_pages, &opt_large_pages,
@@ -6585,8 +6624,7 @@ each time the SQL thread starts.",
"log and this option just turns on --log-bin instead.",
&opt_update_logname, &opt_update_logname, 0, GET_STR,
OPT_ARG, 0, 0, 0, 0, 0, 0},
- {"log-warnings", 'W', "Log some not critical warnings to the general log "
- "file.",
+ {"log-warnings", 'W', "Log some not critical warnings to the general log file. Value can be between 0-11; The higher value, the more warnings",
&global_system_variables.log_warnings,
&max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0,
0, 0, 0},
@@ -6992,12 +7030,11 @@ each time the SQL thread starts.",
{"skip-networking", OPT_SKIP_NETWORKING,
"Don't allow connection with TCP/IP.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0,
0, 0, 0},
-#ifndef DBUG_OFF
#ifdef SAFEMALLOC
- {"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
- "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG,
- 0, 0, 0, 0, 0, 0},
-#endif
+ {"safemalloc", OPT_SAFEMALLOC,
+ "Check all memory allocation for every malloc/free call.",
+ &sf_malloc_trough_check, &sf_malloc_trough_check, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
#endif
{"skip-show-database", OPT_SKIP_SHOW_DB,
"Don't allow 'SHOW DATABASE' commands.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
@@ -7211,7 +7248,7 @@ each time the SQL thread starts.",
{ "flush_time", OPT_FLUSH_TIME,
"A dedicated thread is created to flush all tables at the given interval.",
&flush_time, &flush_time, 0, GET_ULONG, REQUIRED_ARG,
- FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0},
+ 0 , 0, LONG_TIMEOUT, 0, 1, 0},
{ "ft_boolean_syntax", OPT_FT_BOOLEAN_SYNTAX,
"List of operators for MATCH ... AGAINST ( ... IN BOOLEAN MODE).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -7424,9 +7461,9 @@ each time the SQL thread starts.",
&max_system_variables.max_tmp_tables, 0, GET_ULONG,
REQUIRED_ARG, 32, 1, (longlong) ULONG_MAX, 0, 1, 0},
{"max_user_connections", OPT_MAX_USER_CONNECTIONS,
- "The maximum number of active connections for a single user (0 = no limit).",
- &max_user_connections, &max_user_connections, 0, GET_UINT,
- REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0},
+ "The maximum number of active connections for a single user (0 = no limit. In addition global max_user_connections counting and checking is permanently disabled).",
+ &max_user_connections, &max_user_connections, 0, GET_INT,
+ REQUIRED_ARG, 0, 0, INT_MAX, 0, 1, 0},
{"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
"After this many write locks, allow some read locks to run in between.",
&max_write_lock_count, &max_write_lock_count, 0, GET_ULONG,
@@ -7555,9 +7592,7 @@ each time the SQL thread starts.",
"subquery_cache, outer_join_with_cache, semijoin_with_cache, "
"join_cache_incremental, join_cache_hashed, join_cache_bka, "
"optimize_join_buffer_size"
-#ifndef DBUG_OFF
", table_elimination"
-#endif
"} and val={on, off, default}.",
&optimizer_switch_str, &optimizer_switch_str, 0, GET_STR, REQUIRED_ARG,
/*OPTIMIZER_SWITCH_DEFAULT*/0, 0, 0, 0, 0, 0},
@@ -7580,6 +7615,11 @@ each time the SQL thread starts.",
&global_system_variables.preload_buff_size,
&max_system_variables.preload_buff_size, 0, GET_ULONG,
REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
+ {"progress_report_time", OPT_PROGRESS_REPORT_TIME,
+ "Seconds between sending progress reports to the client for slow commands. Set to 0 to disable progress reporting.",
+ &global_system_variables.progress_report_time,
+ &max_system_variables.progress_report_time,
+ 0, GET_ULONG, REQUIRED_ARG, 5, 0, ULONG_MAX, 0, 1, 0},
{"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
"Allocation block size for query parsing and execution.",
&global_system_variables.query_alloc_block_size,
@@ -7784,7 +7824,7 @@ each time the SQL thread starts.",
"Define threads usage for handling queries: "
"one-thread-per-connection"
#if HAVE_POOL_OF_THREADS == 1
- ", pool-of-threads"
+ ", pool-of-threads "
#endif
"or no-threads.",
&opt_thread_handling, &opt_thread_handling,
@@ -8262,6 +8302,8 @@ SHOW_VAR status_vars[]= {
{"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
{"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
{"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
+ {"Handler_tmp_update", (char*) offsetof(STATUS_VAR, ha_tmp_update_count), SHOW_LONG_STATUS},
+ {"Handler_tmp_write", (char*) offsetof(STATUS_VAR, ha_tmp_write_count), SHOW_LONG_STATUS},
{"Key", (char*) &show_default_keycache, SHOW_FUNC},
{"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
{"Max_used_connections", (char*) &max_used_connections, SHOW_LONG},
@@ -8276,6 +8318,7 @@ SHOW_VAR status_vars[]= {
{"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_FUNC},
{"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS},
{"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS},
+ {"Rows_tmp_read", (char*) offsetof(STATUS_VAR, rows_tmp_read), SHOW_LONGLONG_STATUS},
#ifdef HAVE_QUERY_CACHE
{"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
{"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
@@ -9394,11 +9437,6 @@ mysqld_get_one_option(int optid,
}
strmake(ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1);
break;
- case OPT_SKIP_SAFEMALLOC:
-#ifdef SAFEMALLOC
- sf_malloc_quick=1;
-#endif
- break;
case OPT_LOWER_CASE_TABLE_NAMES:
lower_case_table_names= argument ? atoi(argument) : 1;
lower_case_table_names_used= 1;
@@ -9578,6 +9616,19 @@ static int get_options(int *argc,char **argv)
myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
my_crc_dbug_check= opt_my_crc_dbug_check;
+ /*
+ Log mysys errors when we don't have a thd or thd->log_all_errors is set
+ (recovery) to the log. This is mainly useful for debugging strange system
+ errors.
+ */
+ if (global_system_variables.log_warnings >= 10)
+ my_global_flags= MY_WME | ME_JUST_INFO;
+ /* Log all errors not handled by thd->handle_error() to my_message_sql() */
+ if (global_system_variables.log_warnings >= 11)
+ my_global_flags|= ME_NOREFRESH;
+ if (my_assert_on_error)
+ debug_assert_if_crashed_table= 1;
+
/* long_query_time is in microseconds */
global_system_variables.long_query_time= max_system_variables.long_query_time=
(longlong) (long_query_time * 1000000.0);
@@ -9593,6 +9644,9 @@ static int get_options(int *argc,char **argv)
&global_system_variables.datetime_format))
return 1;
+#ifdef SAFEMALLOC
+ sf_malloc_quick= !sf_malloc_trough_check;
+#endif
#ifdef EMBEDDED_LIBRARY
one_thread_scheduler(&thread_scheduler);
one_thread_scheduler(&extra_thread_scheduler);
@@ -9616,6 +9670,8 @@ static int get_options(int *argc,char **argv)
if (!max_long_data_size_used)
max_long_data_size= global_system_variables.max_allowed_packet;
+ /* Rember if max_user_connections was 0 at startup */
+ max_user_connections_checking= max_user_connections != 0;
return 0;
}
diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc
index e0a2d3b1f30..3a9c813b93c 100644
--- a/sql/opt_index_cond_pushdown.cc
+++ b/sql/opt_index_cond_pushdown.cc
@@ -83,15 +83,44 @@ bool uses_index_fields_only(Item *item, TABLE *tbl, uint keyno,
case Item::FIELD_ITEM:
{
Item_field *item_field= (Item_field*)item;
- if (item_field->field->table != tbl)
+ Field *field= item_field->field;
+ if (field->table != tbl)
return TRUE;
/*
The below is probably a repetition - the first part checks the
other two, but let's play it safe:
*/
- return item_field->field->part_of_key.is_set(keyno) &&
- item_field->field->type() != MYSQL_TYPE_GEOMETRY &&
- item_field->field->type() != MYSQL_TYPE_BLOB;
+ if(!field->part_of_key.is_set(keyno) ||
+ field->type() == MYSQL_TYPE_GEOMETRY ||
+ field->type() == MYSQL_TYPE_BLOB)
+ return FALSE;
+ KEY *key_info= tbl->key_info + keyno;
+ KEY_PART_INFO *key_part= key_info->key_part;
+ KEY_PART_INFO *key_part_end= key_part + key_info->key_parts;
+ for ( ; key_part < key_part_end; key_part++)
+ {
+ if (field->eq(key_part->field))
+ return !(key_part->key_part_flag & HA_PART_KEY_SEG);
+ }
+ if ((tbl->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
+ tbl->s->primary_key != MAX_KEY &&
+ tbl->s->primary_key != keyno)
+ {
+ key_info= tbl->key_info + tbl->s->primary_key;
+ key_part= key_info->key_part;
+ key_part_end= key_part + key_info->key_parts;
+ for ( ; key_part < key_part_end; key_part++)
+ {
+ /*
+ It does not make sense to use the fact that the engine can read in
+ a full field if the key if the index is built only over a part
+ of this field.
+ */
+ if (field->eq(key_part->field))
+ return !(key_part->key_part_flag & HA_PART_KEY_SEG);
+ }
+ }
+ return FALSE;
}
case Item::REF_ITEM:
return uses_index_fields_only(item->real_item(), tbl, keyno,
@@ -210,11 +239,9 @@ Item *make_cond_for_index(Item *cond, TABLE *table, uint keyno,
}
-Item *make_cond_remainder(Item *cond, bool exclude_index)
+Item *make_cond_remainder(Item *cond, TABLE *table, uint keyno,
+ bool other_tbls_ok, bool exclude_index)
{
- if (exclude_index && cond->marker == ICP_COND_USES_INDEX_ONLY)
- return 0; /* Already checked */
-
if (cond->type() == Item::COND_ITEM)
{
table_map tbl_map= 0;
@@ -228,7 +255,8 @@ Item *make_cond_remainder(Item *cond, bool exclude_index)
Item *item;
while ((item=li++))
{
- Item *fix= make_cond_remainder(item, exclude_index);
+ Item *fix= make_cond_remainder(item, table, keyno,
+ other_tbls_ok, exclude_index);
if (fix)
{
new_cond->argument_list()->push_back(fix);
@@ -255,7 +283,8 @@ Item *make_cond_remainder(Item *cond, bool exclude_index)
Item *item;
while ((item=li++))
{
- Item *fix= make_cond_remainder(item, FALSE);
+ Item *fix= make_cond_remainder(item, table, keyno,
+ other_tbls_ok, FALSE);
if (!fix)
return (COND*) 0;
new_cond->argument_list()->push_back(fix);
@@ -267,7 +296,14 @@ Item *make_cond_remainder(Item *cond, bool exclude_index)
return new_cond;
}
}
- return cond;
+ else
+ {
+ if (exclude_index &&
+ uses_index_fields_only(cond, table, keyno, other_tbls_ok))
+ return 0;
+ else
+ return cond;
+ }
}
@@ -288,30 +324,13 @@ void push_index_cond(JOIN_TAB *tab, uint keyno)
{
DBUG_ENTER("push_index_cond");
Item *idx_cond;
- bool do_index_cond_pushdown=
- ((tab->table->file->index_flags(keyno, 0, 1) &
- HA_DO_INDEX_COND_PUSHDOWN) &&
- optimizer_flag(tab->join->thd, OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN));
-
- /*
- Do not try index condition pushdown on indexes which have partially-covered
- columns. Unpacking from a column prefix into index tuple is not a supported
- operation in some engines, see e.g. MySQL BUG#42991.
- TODO: a better solution would be not to consider partially-covered columns
- as parts of the index and still produce/check index condition for
- fully-covered index columns.
- */
- KEY *key_info= tab->table->key_info + keyno;
- for (uint kp= 0; kp < key_info->key_parts; kp++)
- {
- if ((key_info->key_part[kp].key_part_flag & HA_PART_KEY_SEG))
- {
- do_index_cond_pushdown= FALSE;
- break;
- }
- }
- if (do_index_cond_pushdown)
+ if ((tab->table->file->index_flags(keyno, 0, 1) &
+ HA_DO_INDEX_COND_PUSHDOWN) &&
+ optimizer_flag(tab->join->thd, OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN) &&
+ tab->join->thd->lex->sql_command != SQLCOM_UPDATE_MULTI &&
+ tab->join->thd->lex->sql_command != SQLCOM_DELETE_MULTI &&
+ tab->type != JT_CONST && tab->type != JT_SYSTEM)
{
DBUG_EXECUTE("where",
print_where(tab->select_cond, "full cond", QT_ORDINARY););
@@ -356,7 +375,8 @@ void push_index_cond(JOIN_TAB *tab, uint keyno)
tab->ref.disable_cache= TRUE;
Item *row_cond= tab->idx_cond_fact_out ?
- make_cond_remainder(tab->select_cond, TRUE) :
+ make_cond_remainder(tab->select_cond, tab->table, keyno,
+ tab->icp_other_tables_ok, TRUE) :
tab->pre_idx_push_select_cond;
DBUG_EXECUTE("where",
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index dc987e196f4..121c923845f 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1136,10 +1136,10 @@ int SEL_IMERGE::and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree,
2. In the second mode, when is_first_check_pass==FALSE :
2.1. For each rt_j in the imerge that can be ored (see the function
- sel_trees_can_be_ored), but not must be ored, with rt the function
- replaces rt_j for a range tree such that for each index for which
- ranges are defined in both in rt_j and rt the tree contains the
- result of oring of these ranges.
+ sel_trees_can_be_ored) with rt the function replaces rt_j for a
+ range tree such that for each index for which ranges are defined
+ in both in rt_j and rt the tree contains the result of oring of
+ these ranges.
2.2. In other cases the function does not produce any imerge.
When is_first_check==TRUE the function returns FALSE in the parameter
@@ -1163,7 +1163,7 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param,
bool *is_last_check_pass)
{
bool was_ored= FALSE;
- *is_last_check_pass= TRUE;
+ *is_last_check_pass= is_first_check_pass;
SEL_TREE** or_tree = trees;
for (uint i= 0; i < n_trees; i++, or_tree++)
{
@@ -1174,7 +1174,7 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param,
{
bool must_be_ored= sel_trees_must_be_ored(param, *or_tree, tree,
ored_keys);
- if (must_be_ored || !is_first_check_pass)
+ if (must_be_ored || !is_first_check_pass)
{
result_keys.clear_all();
result= *or_tree;
@@ -1210,22 +1210,19 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param,
{
if (result_keys.is_clear_all())
result->type= SEL_TREE::ALWAYS;
- *is_last_check_pass= TRUE;
if ((result->type == SEL_TREE::MAYBE) ||
(result->type == SEL_TREE::ALWAYS))
return 1;
/* SEL_TREE::IMPOSSIBLE is impossible here */
result->keys_map= result_keys;
*or_tree= result;
- if (is_first_check_pass)
- return 0;
was_ored= TRUE;
}
}
if (was_ored)
return 0;
- if (!*is_last_check_pass &&
+ if (is_first_check_pass && !*is_last_check_pass &&
!(tree= new SEL_TREE(tree, FALSE, param)))
return (-1);
return or_sel_tree(param, tree);
@@ -1804,7 +1801,7 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
DBUG_PRINT("info", ("Freeing separate handler 0x%lx (free: %d)", (long) file,
free_file));
file->ha_external_lock(current_thd, F_UNLCK);
- file->close();
+ file->ha_close();
delete file;
}
}
@@ -1999,7 +1996,7 @@ int QUICK_RANGE_SELECT::init_ror_merged_scan(bool reuse_handler)
if (init() || reset())
{
file->ha_external_lock(thd, F_UNLCK);
- file->close();
+ file->ha_close();
goto failure;
}
free_file= TRUE;
@@ -7292,7 +7289,7 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
case Item_func::MULT_EQUAL_FUNC:
{
Item_equal *item_equal= (Item_equal *) cond;
- if (!(value= item_equal->get_const()))
+ if (!(value= item_equal->get_const()) || value->is_expensive())
DBUG_RETURN(0);
Item_equal_fields_iterator it(*item_equal);
ref_tables= value->used_tables();
@@ -7325,6 +7322,9 @@ static SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param,COND *cond)
}
else
DBUG_RETURN(0);
+ if (value && value->is_expensive())
+ DBUG_RETURN(0);
+
ftree= get_full_func_mm_tree(param, cond_func, field_item, value, inv);
}
@@ -8379,9 +8379,9 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
/* Build the imerge part of the tree for the formula (1) */
SEL_TREE *rt1= tree1;
SEL_TREE *rt2= tree2;
- if (!no_merges1)
+ if (no_merges1)
rt1= new SEL_TREE(tree1, TRUE, param);
- if (!no_merges2)
+ if (no_merges2)
rt2= new SEL_TREE(tree2, TRUE, param);
if (!rt1 || !rt2 ||
result->merges.push_back(imerge_from_ranges) ||
@@ -8695,7 +8695,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
{
key1->free_tree();
key2->free_tree();
- return 0; // Can't optimize this
+ return 0; // Can't optimize this
}
// If one of the key is MAYBE_KEY then the found region may be bigger
@@ -8719,248 +8719,553 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
swap_variables(SEL_ARG *,key1,key2);
}
if (key1->use_count > 0 && !(key1=key1->clone_tree(param)))
- return 0; // OOM
+ return 0; // OOM
}
// Add tree at key2 to tree at key1
bool key2_shared=key2->use_count != 0;
key1->maybe_flag|=key2->maybe_flag;
+ /*
+ Notation for illustrations used in the rest of this function:
+
+ Range: [--------]
+ ^ ^
+ start stop
+
+ Two overlapping ranges:
+ [-----] [----] [--]
+ [---] or [---] or [-------]
+
+ Ambiguity: ***
+ The range starts or stops somewhere in the "***" range.
+ Example: a starts before b and may end before/the same plase/after b
+ a: [----***]
+ b: [---]
+
+ Adjacent ranges:
+ Ranges that meet but do not overlap. Example: a = "x < 3", b = "x >= 3"
+ a: ----]
+ b: [----
+ */
+
uint max_part_no= max(key1->max_part_no, key2->max_part_no);
for (key2=key2->first(); key2; )
{
- SEL_ARG *tmp=key1->find_range(key2); // Find key1.min <= key2.min
- int cmp;
+ /*
+ key1 consists of one or more ranges. tmp is the range currently
+ being handled.
+
+ initialize tmp to the latest range in key1 that starts the same
+ place or before the range in key2 starts
+
+ key2: [------]
+ key1: [---] [-----] [----]
+ ^
+ tmp
+ */
+ SEL_ARG *tmp=key1->find_range(key2);
+
+ /*
+ Used to describe how two key values are positioned compared to
+ each other. Consider key_value_a.<cmp_func>(key_value_b):
+
+ -2: key_value_a is smaller than key_value_b, and they are adjacent
+ -1: key_value_a is smaller than key_value_b (not adjacent)
+ 0: the key values are equal
+ 1: key_value_a is bigger than key_value_b (not adjacent)
+ -2: key_value_a is bigger than key_value_b, and they are adjacent
+
+ Example: "cmp= tmp->cmp_max_to_min(key2)"
+
+ key2: [-------- (10 <= x ...)
+ tmp: -----] (... x < 10) => cmp==-2
+ tmp: ----] (... x <= 9) => cmp==-1
+ tmp: ------] (... x = 10) => cmp== 0
+ tmp: --------] (... x <= 12) => cmp== 1
+ (cmp == 2 does not make sense for cmp_max_to_min())
+ */
+ int cmp= 0;
if (!tmp)
{
- tmp=key1->first(); // tmp.min > key2.min
+ /*
+ The range in key2 starts before the first range in key1. Use
+ the first range in key1 as tmp.
+
+ key2: [--------]
+ key1: [****--] [----] [-------]
+ ^
+ tmp
+ */
+ tmp=key1->first();
cmp= -1;
}
- else if ((cmp=tmp->cmp_max_to_min(key2)) < 0)
- { // Found tmp.max < key2.min
+ else if ((cmp= tmp->cmp_max_to_min(key2)) < 0)
+ {
+ /*
+ This is the case:
+ key2: [-------]
+ tmp: [----**]
+ */
SEL_ARG *next=tmp->next;
- /* key1 on the left of key2 non-overlapping */
if (cmp == -2 && eq_tree(tmp->next_key_part,key2->next_key_part))
{
- // Join near ranges like tmp.max < 0 and key2.min >= 0
- SEL_ARG *key2_next=key2->next;
- if (key2_shared)
- {
- if (!(key2=new SEL_ARG(*key2)))
- return 0; // out of memory
- key2->increment_use_count(key1->use_count+1);
- key2->next=key2_next; // New copy of key2
- }
- key2->copy_min(tmp);
- if (!(key1=key1->tree_delete(tmp)))
- { // Only one key in tree
- key1=key2;
- key1->make_root();
- key2=key2_next;
- break;
- }
+ /*
+ Adjacent (cmp==-2) and equal next_key_parts => ranges can be merged
+
+ This is the case:
+ key2: [-------]
+ tmp: [----]
+
+ Result:
+ key2: [-------------] => inserted into key1 below
+ tmp: => deleted
+ */
+ SEL_ARG *key2_next=key2->next;
+ if (key2_shared)
+ {
+ if (!(key2=new SEL_ARG(*key2)))
+ return 0; // out of memory
+ key2->increment_use_count(key1->use_count+1);
+ key2->next=key2_next; // New copy of key2
+ }
+
+ key2->copy_min(tmp);
+ if (!(key1=key1->tree_delete(tmp)))
+ { // Only one key in tree
+ key1=key2;
+ key1->make_root();
+ key2=key2_next;
+ break;
+ }
}
- if (!(tmp=next)) // tmp.min > key2.min
- break; // Copy rest of key2
+ if (!(tmp=next)) // Move to next range in key1. Now tmp.min > key2.min
+ break; // No more ranges in key1. Copy rest of key2
}
+
if (cmp < 0)
- { // tmp.min > key2.min
+ {
+ /*
+ This is the case:
+ key2: [--***]
+ tmp: [----]
+ */
int tmp_cmp;
- if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0) // if tmp.min > key2.max
+ if ((tmp_cmp=tmp->cmp_min_to_max(key2)) > 0)
{
- /* tmp is on the right of key2 non-overlapping */
- if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
- { // ranges are connected
- tmp->copy_min_to_min(key2);
- key1->merge_flags(key2);
- if (tmp->min_flag & NO_MIN_RANGE &&
- tmp->max_flag & NO_MAX_RANGE)
- {
- if (key1->maybe_flag)
- return new SEL_ARG(SEL_ARG::MAYBE_KEY);
- return 0;
- }
- key2->increment_use_count(-1); // Free not used tree
- key2=key2->next;
- continue;
- }
- else
- {
- SEL_ARG *next=key2->next; // Keys are not overlapping
- if (key2_shared)
- {
- SEL_ARG *cpy= new SEL_ARG(*key2); // Must make copy
- if (!cpy)
- return 0; // OOM
- key1=key1->insert(cpy);
- key2->increment_use_count(key1->use_count+1);
- }
- else
- key1=key1->insert(key2); // Will destroy key2_root
- key2=next;
- continue;
- }
+ /*
+ This is the case:
+ key2: [------**]
+ tmp: [----]
+ */
+ if (tmp_cmp == 2 && eq_tree(tmp->next_key_part,key2->next_key_part))
+ {
+ /*
+ Adjacent ranges with equal next_key_part. Merge like this:
+
+ This is the case:
+ key2: [------]
+ tmp: [-----]
+
+ Result:
+ key2: [------]
+ tmp: [-------------]
+
+ Then move on to next key2 range.
+ */
+ tmp->copy_min_to_min(key2);
+ key1->merge_flags(key2);
+ if (tmp->min_flag & NO_MIN_RANGE &&
+ tmp->max_flag & NO_MAX_RANGE)
+ {
+ if (key1->maybe_flag)
+ return new SEL_ARG(SEL_ARG::MAYBE_KEY);
+ return 0;
+ }
+ key2->increment_use_count(-1); // Free not used tree
+ key2=key2->next;
+ continue;
+ }
+ else
+ {
+ /*
+ key2 not adjacent to tmp or has different next_key_part.
+ Insert into key1 and move to next range in key2
+
+ This is the case:
+ key2: [------**]
+ tmp: [----]
+
+ Result:
+ key1_ [------**][----]
+ ^ ^
+ insert tmp
+ */
+ SEL_ARG *next=key2->next;
+ if (key2_shared)
+ {
+ SEL_ARG *cpy= new SEL_ARG(*key2); // Must make copy
+ if (!cpy)
+ return 0; // OOM
+ key1=key1->insert(cpy);
+ key2->increment_use_count(key1->use_count+1);
+ }
+ else
+ key1=key1->insert(key2); // Will destroy key2_root
+ key2=next;
+ continue;
+ }
}
}
- /*
- tmp.min >= key2.min && tmp.min <= key.max (overlapping ranges)
- key2.min <= tmp.min <= key2.max
- */
+ /*
+ The ranges in tmp and key2 are overlapping:
+
+ key2: [----------]
+ tmp: [*****-----*****]
+
+ Corollary: tmp.min <= key2.max
+ */
if (eq_tree(tmp->next_key_part,key2->next_key_part))
{
+ // Merge overlapping ranges with equal next_key_part
if (tmp->is_same(key2))
{
- /*
- Found exact match of key2 inside key1.
+ /*
+ Found exact match of key2 inside key1.
Use the relevant range in key1.
*/
- tmp->merge_flags(key2); // Copy maybe flags
- key2->increment_use_count(-1); // Free not used tree
+ tmp->merge_flags(key2); // Copy maybe flags
+ key2->increment_use_count(-1); // Free not used tree
}
else
{
- SEL_ARG *last=tmp;
- SEL_ARG *first=tmp;
- /*
- Find the last range in tmp that overlaps key2 and has the same
- condition on the rest of the keyparts.
+ SEL_ARG *last= tmp;
+ SEL_ARG *first= tmp;
+
+ /*
+ Find the last range in key1 that overlaps key2 and
+ where all ranges first...last have the same next_key_part as
+ key2.
+
+ key2: [****----------------------*******]
+ key1: [--] [----] [---] [-----] [xxxx]
+ ^ ^ ^
+ first last different next_key_part
+
+ Since key2 covers them, the ranges between first and last
+ are merged into one range by deleting first...last-1 from
+ the key1 tree. In the figure, this applies to first and the
+ two consecutive ranges. The range of last is then extended:
+ * last.min: Set to min(key2.min, first.min)
+ * last.max: If there is a last->next that overlaps key2 (i.e.,
+ last->next has a different next_key_part):
+ Set adjacent to last->next.min
+ Otherwise: Set to max(key2.max, last.max)
+
+ Result:
+ key2: [****----------------------*******]
+ [--] [----] [---] => deleted from key1
+ key1: [**------------------------***][xxxx]
+ ^ ^
+ tmp=last different next_key_part
*/
- while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
- eq_tree(last->next->next_key_part,key2->next_key_part))
- {
+ while (last->next && last->next->cmp_min_to_max(key2) <= 0 &&
+ eq_tree(last->next->next_key_part,key2->next_key_part))
+ {
/*
- We've found the last overlapping key1 range in last.
- This means that the ranges between (and including) the
- first overlapping range (tmp) and the last overlapping range
- (last) are fully nested into the current range of key2
- and can safely be discarded. We just need the minimum endpoint
- of the first overlapping range (tmp) so we can compare it with
- the minimum endpoint of the enclosing key2 range.
+ last->next is covered by key2 and has same next_key_part.
+ last can be deleted
*/
- SEL_ARG *save=last;
- last=last->next;
- key1=key1->tree_delete(save);
- }
+ SEL_ARG *save=last;
+ last=last->next;
+ key1=key1->tree_delete(save);
+ }
+ // Redirect tmp to last which will cover the entire range
+ tmp= last;
+
/*
- The tmp range (the first overlapping range) could have been discarded
- by the previous loop. We should re-direct tmp to the new united range
- that's taking its place.
+ We need the minimum endpoint of first so we can compare it
+ with the minimum endpoint of the enclosing key2 range.
*/
- tmp= last;
last->copy_min(first);
bool full_range= last->copy_min(key2);
if (!full_range)
{
if (last->next && key2->cmp_max_to_min(last->next) >= 0)
{
- last->max_value= last->next->min_value;
- if (last->next->min_flag & NEAR_MIN)
- last->max_flag&= ~NEAR_MAX;
- else
- last->max_flag|= NEAR_MAX;
+ /*
+ This is the case:
+ key2: [-------------]
+ key1: [***------] [xxxx]
+ ^ ^
+ last different next_key_part
+
+ Extend range of last up to last->next:
+ key2: [-------------]
+ key1: [***--------][xxxx]
+ */
+ last->copy_min_to_max(last->next);
}
else
+ /*
+ This is the case:
+ key2: [--------*****]
+ key1: [***---------] [xxxx]
+ ^ ^
+ last different next_key_part
+
+ Extend range of last up to max(last.max, key2.max):
+ key2: [--------*****]
+ key1: [***----------**] [xxxx]
+ */
full_range= last->copy_max(key2);
}
- if (full_range)
- { // Full range
- key1->free_tree();
- for (; key2 ; key2=key2->next)
- key2->increment_use_count(-1); // Free not used tree
- if (key1->maybe_flag)
- return new SEL_ARG(SEL_ARG::MAYBE_KEY);
- return 0;
- }
+ if (full_range)
+ { // Full range
+ key1->free_tree();
+ for (; key2 ; key2=key2->next)
+ key2->increment_use_count(-1); // Free not used tree
+ if (key1->maybe_flag)
+ return new SEL_ARG(SEL_ARG::MAYBE_KEY);
+ return 0;
+ }
}
}
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
- { // tmp.min <= x < key2.min
+ {
+ /*
+ This is the case ("cmp>=0" means that tmp.max >= key2.min):
+ key2: [----]
+ tmp: [------------*****]
+ */
+
+ if (!tmp->next_key_part)
+ {
+ /*
+ tmp->next_key_part is empty: cut the range that is covered
+ by tmp from key2.
+ Reason: (key2->next_key_part OR tmp->next_key_part) will be
+ empty and therefore equal to tmp->next_key_part. Thus, this
+ part of the key2 range is completely covered by tmp.
+ */
+ if (tmp->cmp_max_to_max(key2) >= 0)
+ {
+ /*
+ tmp covers the entire range in key2.
+ key2: [----]
+ tmp: [-----------------]
+
+ Move on to next range in key2
+ */
+ key2->increment_use_count(-1); // Free not used tree
+ key2=key2->next;
+ continue;
+ }
+ else
+ {
+ /*
+ This is the case:
+ key2: [-------]
+ tmp: [---------]
+
+ Result:
+ key2: [---]
+ tmp: [---------]
+ */
+ if (key2->use_count)
+ {
+ SEL_ARG *key2_cpy= new SEL_ARG(*key2);
+ if (key2_cpy)
+ return 0;
+ key2= key2_cpy;
+ }
+ key2->copy_max_to_min(tmp);
+ continue;
+ }
+ }
+
+ /*
+ The ranges are overlapping but have not been merged because
+ next_key_part of tmp and key2 differ.
+ key2: [----]
+ tmp: [------------*****]
+
+ Split tmp in two where key2 starts:
+ key2: [----]
+ key1: [--------][--*****]
+ ^ ^
+ insert tmp
+ */
SEL_ARG *new_arg=tmp->clone_first(key2);
if (!new_arg)
- return 0; // OOM
- if ((new_arg->next_key_part= key1->next_key_part))
- new_arg->increment_use_count(key1->use_count+1);
+ return 0; // OOM
+ if ((new_arg->next_key_part= tmp->next_key_part))
+ new_arg->increment_use_count(key1->use_count+1);
tmp->copy_min_to_min(key2);
key1=key1->insert(new_arg);
- }
+ } // tmp.min >= key2.min due to this if()
- // tmp.min >= key2.min && tmp.min <= key2.max
- SEL_ARG key(*key2); // Get copy we can modify
+ /*
+ Now key2.min <= tmp.min <= key2.max:
+ key2: [---------]
+ tmp: [****---*****]
+ */
+ SEL_ARG key2_cpy(*key2); // Get copy we can modify
for (;;)
{
- if (tmp->cmp_min_to_min(&key) > 0)
- { // key.min <= x < tmp.min
- SEL_ARG *new_arg=key.clone_first(tmp);
- if (!new_arg)
- return 0; // OOM
- if ((new_arg->next_key_part=key.next_key_part))
- new_arg->increment_use_count(key1->use_count+1);
- key1=key1->insert(new_arg);
- }
- if ((cmp=tmp->cmp_max_to_max(&key)) <= 0)
- { // tmp.min. <= x <= tmp.max
- tmp->maybe_flag|= key.maybe_flag;
- key.increment_use_count(key1->use_count+1);
- tmp->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
- if (!cmp) // Key2 is ready
- break;
- key.copy_max_to_min(tmp);
- if (!(tmp=tmp->next))
- {
- SEL_ARG *tmp2= new SEL_ARG(key);
- if (!tmp2)
- return 0; // OOM
- key1=key1->insert(tmp2);
- key2=key2->next;
- goto end;
- }
- if (tmp->cmp_min_to_max(&key) > 0)
- {
- SEL_ARG *tmp2= new SEL_ARG(key);
- if (!tmp2)
- return 0; // OOM
- key1=key1->insert(tmp2);
- break;
- }
+ if (tmp->cmp_min_to_min(&key2_cpy) > 0)
+ {
+ /*
+ This is the case:
+ key2_cpy: [------------]
+ key1: [-*****]
+ ^
+ tmp
+
+ Result:
+ key2_cpy: [---]
+ key1: [-------][-*****]
+ ^ ^
+ insert tmp
+ */
+ SEL_ARG *new_arg=key2_cpy.clone_first(tmp);
+ if (!new_arg)
+ return 0; // OOM
+ if ((new_arg->next_key_part=key2_cpy.next_key_part))
+ new_arg->increment_use_count(key1->use_count+1);
+ key1=key1->insert(new_arg);
+ key2_cpy.copy_min_to_min(tmp);
+ }
+ // Now key2_cpy.min == tmp.min
+
+ if ((cmp= tmp->cmp_max_to_max(&key2_cpy)) <= 0)
+ {
+ /*
+ tmp.max <= key2_cpy.max:
+ key2_cpy: a) [-------] or b) [----]
+ tmp: [----] [----]
+
+ Steps:
+ 1) Update next_key_part of tmp: OR it with key2_cpy->next_key_part.
+ 2) If case a: Insert range [tmp.max, key2_cpy.max] into key1 using
+ next_key_part of key2_cpy
+
+ Result:
+ key1: a) [----][-] or b) [----]
+ */
+ tmp->maybe_flag|= key2_cpy.maybe_flag;
+ key2_cpy.increment_use_count(key1->use_count+1);
+ tmp->next_key_part= key_or(param, tmp->next_key_part,
+ key2_cpy.next_key_part);
+
+ if (!cmp)
+ break; // case b: done with this key2 range
+
+ // Make key2_cpy the range [tmp.max, key2_cpy.max]
+ key2_cpy.copy_max_to_min(tmp);
+ if (!(tmp=tmp->next))
+ {
+ /*
+ No more ranges in key1. Insert key2_cpy and go to "end"
+ label to insert remaining ranges in key2 if any.
+ */
+ SEL_ARG *tmp2= new SEL_ARG(key2_cpy);
+ if (!tmp2)
+ return 0; // OOM
+ key1=key1->insert(tmp2);
+ key2=key2->next;
+ goto end;
+ }
+ if (tmp->cmp_min_to_max(&key2_cpy) > 0)
+ {
+ /*
+ The next range in key1 does not overlap with key2_cpy.
+ Insert this range into key1 and move on to the next range
+ in key2.
+ */
+ SEL_ARG *tmp2= new SEL_ARG(key2_cpy);
+ if (!tmp2)
+ return 0; // OOM
+ key1=key1->insert(tmp2);
+ break;
+ }
+ /*
+ key2_cpy overlaps with the next range in key1 and the case
+ is now "key2.min <= tmp.min <= key2.max". Go back to for(;;)
+ to handle this situation.
+ */
+ continue;
}
else
{
- SEL_ARG *new_arg=tmp->clone_last(&key); // tmp.min <= x <= key.max
- if (!new_arg)
- return 0; // OOM
- tmp->copy_max_to_min(&key);
- tmp->increment_use_count(key1->use_count+1);
- /* Increment key count as it may be used for next loop */
- key.increment_use_count(1);
- new_arg->next_key_part= key_or(param, tmp->next_key_part, key.next_key_part);
- key1=key1->insert(new_arg);
- break;
+ /*
+ This is the case:
+ key2_cpy: [-------]
+ tmp: [------------]
+
+ Result:
+ key1: [-------][---]
+ ^ ^
+ new_arg tmp
+ Steps:
+ 0) If tmp->next_key_part is empty: do nothing. Reason:
+ (key2_cpy->next_key_part OR tmp->next_key_part) will be
+ empty and therefore equal to tmp->next_key_part. Thus,
+ the range in key2_cpy is completely covered by tmp
+ 1) Make new_arg with range [tmp.min, key2_cpy.max].
+ new_arg->next_key_part is OR between next_key_part
+ of tmp and key2_cpy
+ 2) Make tmp the range [key2.max, tmp.max]
+ 3) Insert new_arg into key1
+ */
+ if (!tmp->next_key_part) // Step 0
+ {
+ key2_cpy.increment_use_count(-1); // Free not used tree
+ break;
+ }
+ SEL_ARG *new_arg=tmp->clone_last(&key2_cpy);
+ if (!new_arg)
+ return 0; // OOM
+ tmp->copy_max_to_min(&key2_cpy);
+ tmp->increment_use_count(key1->use_count+1);
+ /* Increment key count as it may be used for next loop */
+ key2_cpy.increment_use_count(1);
+ new_arg->next_key_part= key_or(param, tmp->next_key_part,
+ key2_cpy.next_key_part);
+ key1=key1->insert(new_arg);
+ break;
}
}
- key2=key2->next;
+ // Move on to next range in key2
+ key2=key2->next;
}
end:
+ /*
+ Add key2 ranges that are non-overlapping with and higher than the
+ highest range in key1.
+ */
while (key2)
{
SEL_ARG *next=key2->next;
if (key2_shared)
{
- SEL_ARG *tmp=new SEL_ARG(*key2); // Must make copy
+ SEL_ARG *tmp=new SEL_ARG(*key2); // Must make copy
if (!tmp)
- return 0;
+ return 0;
key2->increment_use_count(key1->use_count+1);
key1=key1->insert(tmp);
}
else
- key1=key1->insert(key2); // Will destroy key2_root
+ key1=key1->insert(key2); // Will destroy key2_root
key2=next;
}
key1->use_count++;
+
key1->max_part_no= max_part_no;
return key1;
}
@@ -11728,17 +12033,19 @@ check_group_min_max_predicates(Item *cond, Item_field *min_max_arg_item,
Disallow loose index scan if the MIN/MAX argument field is referenced by
a subquery in the WHERE clause.
*/
+
if (cond_type == Item::SUBSELECT_ITEM)
{
Item_subselect *subs_cond= (Item_subselect*) cond;
if (subs_cond->is_correlated)
{
- DBUG_ASSERT(subs_cond->depends_on.elements > 0);
- List_iterator_fast<Item*> li(subs_cond->depends_on);
- Item **dep;
+ DBUG_ASSERT(subs_cond->upper_refs.elements > 0);
+ List_iterator_fast<Item_subselect::Ref_to_outside>
+ li(subs_cond->upper_refs);
+ Item_subselect::Ref_to_outside *dep;
while ((dep= li++))
{
- if ((*dep)->eq(min_max_arg_item, FALSE))
+ if (dep->item->eq(min_max_arg_item, FALSE))
DBUG_RETURN(FALSE);
}
}
@@ -13341,7 +13648,6 @@ print_key(KEY_PART *key_part, const uchar *key, uint used_length)
{
char buff[1024];
const uchar *key_end= key+used_length;
- String tmp(buff,sizeof(buff),&my_charset_bin);
uint store_length;
TABLE *table= key_part->field->table;
my_bitmap_map *old_sets[2];
@@ -13350,6 +13656,7 @@ print_key(KEY_PART *key_part, const uchar *key, uint used_length)
for (; key < key_end; key+=store_length, key_part++)
{
+ String tmp(buff,sizeof(buff),&my_charset_bin);
Field *field= key_part->field;
store_length= key_part->store_length;
diff --git a/sql/opt_range.h b/sql/opt_range.h
index d7a0c1e2f8f..e498d229dde 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -274,7 +274,6 @@ public:
virtual bool reverse_sorted() = 0;
virtual bool unique_key_range() { return false; }
- virtual bool clustered_pk_range() { return false; }
/*
Request that this quick select produces sorted output. Not all quick
@@ -355,6 +354,12 @@ public:
Table record buffer used by this quick select.
*/
uchar *record;
+
+ virtual void replace_handler(handler *new_file)
+ {
+ DBUG_ASSERT(0); /* Only supported in QUICK_RANGE_SELECT */
+ }
+
#ifndef DBUG_OFF
/*
Print quick select information to DBUG_FILE. Caller is responsible
@@ -450,6 +455,7 @@ public:
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
+ virtual void replace_handler(handler *new_file) { file= new_file; }
private:
/* Default copy ctor used by QUICK_SELECT_DESC */
friend class TRP_ROR_INTERSECT;
@@ -593,9 +599,6 @@ public:
MEM_ROOT alloc;
THD *thd;
virtual int read_keys_and_merge()= 0;
-
- bool clustered_pk_range() { return test(pk_quick_select); }
-
/* used to get rows collected in Unique */
READ_RECORD read_record;
};
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 8ff45e0306e..56815a624e2 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -177,13 +177,13 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs);
static bool replace_where_subcondition(JOIN *join, Item **expr,
Item *old_cond, Item *new_cond,
bool do_fix_fields);
-static int subq_sj_candidate_cmp(Item_in_subselect* const *el1,
- Item_in_subselect* const *el2);
+static int subq_sj_candidate_cmp(Item_in_subselect* el1, Item_in_subselect* el2,
+ void *arg);
static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred);
static bool convert_subq_to_jtbm(JOIN *parent_join,
Item_in_subselect *subq_pred, bool *remove);
static TABLE_LIST *alloc_join_nest(THD *thd);
-static uint get_tmp_table_rec_length(List<Item> &items);
+static uint get_tmp_table_rec_length(Item **p_list, uint elements);
static double get_tmp_table_lookup_cost(THD *thd, double row_count,
uint row_size);
static double get_tmp_table_write_cost(THD *thd, double row_count,
@@ -210,6 +210,74 @@ end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
/*
+ Check if Materialization strategy is allowed for given subquery predicate.
+
+ @param thd Thread handle
+ @param in_subs The subquery predicate
+ @param child_select The select inside predicate (the function will
+ check it is the only one)
+
+ @return TRUE - Materialization is applicable
+ FALSE - Otherwise
+*/
+
+bool is_materialization_applicable(THD *thd, Item_in_subselect *in_subs,
+ st_select_lex *child_select)
+{
+ st_select_lex_unit* parent_unit= child_select->master_unit();
+ /*
+ Check if the subquery predicate can be executed via materialization.
+ The required conditions are:
+ 0. The materialization optimizer switch was set.
+ 1. Subquery is a single SELECT (not a UNION).
+ TODO: this is a limitation that can be fixed
+ 2. Subquery is not a table-less query. In this case there is no
+ point in materializing.
+ 2A The upper query is not a table-less SELECT ... FROM DUAL. We
+ can't do materialization for SELECT .. FROM DUAL because it
+ does not call setup_subquery_materialization(). We could make
+ SELECT ... FROM DUAL call that function but that doesn't seem
+ to be the case that is worth handling.
+ 3. Either the subquery predicate is a top-level predicate, or at
+ least one partial match strategy is enabled. If no partial match
+ strategy is enabled, then materialization cannot be used for
+ non-top-level queries because it cannot handle NULLs correctly.
+ 4. Subquery is non-correlated
+ TODO:
+ This condition is too restrictive (limitation). It can be extended to:
+ (Subquery is non-correlated ||
+ Subquery is correlated to any query outer to IN predicate ||
+ (Subquery is correlated to the immediate outer query &&
+ Subquery !contains {GROUP BY, ORDER BY [LIMIT],
+ aggregate functions}) && subquery predicate is not under "NOT IN"))
+
+ (*) The subquery must be part of a SELECT statement. The current
+ condition also excludes multi-table update statements.
+ A note about prepared statements: we want the if-branch to be taken on
+ PREPARE and each EXECUTE. The rewrites are only done once, but we need
+ select_lex->sj_subselects list to be populated for every EXECUTE.
+
+ */
+ if (optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION) && // 0
+ !child_select->is_part_of_union() && // 1
+ parent_unit->first_select()->leaf_tables.elements && // 2
+ thd->lex->sql_command == SQLCOM_SELECT && // *
+ child_select->outer_select()->leaf_tables.elements && // 2A
+ subquery_types_allow_materialization(in_subs) &&
+ (in_subs->is_top_level_item() || //3
+ optimizer_flag(thd,
+ OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) || //3
+ optimizer_flag(thd,
+ OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN)) && //3
+ !in_subs->is_correlated) //4
+ {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
Check if we need JOIN::prepare()-phase subquery rewrites and if yes, do them
SYNOPSIS
@@ -340,10 +408,10 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
!select_lex->is_part_of_union() && // 2
!select_lex->group_list.elements && !join->order && // 3
!join->having && !select_lex->with_sum_func && // 4
- thd->thd_marker.emb_on_expr_nest && // 5
+ in_subs->emb_on_expr_nest && // 5
select_lex->outer_select()->join && // 6
parent_unit->first_select()->leaf_tables.elements && // 7
- !in_subs->in_strategy && // 8
+ !in_subs->has_strategy() && // 8
select_lex->outer_select()->leaf_tables.elements && // 9
!((join->select_options | // 10
select_lex->outer_select()->join->select_options) // 10
@@ -353,12 +421,18 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
(void)subquery_types_allow_materialization(in_subs);
- in_subs->emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
in_subs->is_flattenable_semijoin= TRUE;
/* Register the subquery for further processing in flatten_subqueries() */
- select_lex->
- outer_select()->join->sj_subselects.append(thd->mem_root, in_subs);
+ if (!in_subs->is_registered_semijoin)
+ {
+ Query_arena *arena, backup;
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+ select_lex->outer_select()->sj_subselects.push_back(in_subs);
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ in_subs->is_registered_semijoin= TRUE;
+ }
}
else
{
@@ -375,65 +449,27 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
*/
if (in_subs)
{
- /*
- Check if the subquery predicate can be executed via materialization.
- The required conditions are:
- 0. The materialization optimizer switch was set.
- 1. Subquery is a single SELECT (not a UNION).
- TODO: this is a limitation that can be fixed
- 2. Subquery is not a table-less query. In this case there is no
- point in materializing.
- 2A The upper query is not a table-less SELECT ... FROM DUAL. We
- can't do materialization for SELECT .. FROM DUAL because it
- does not call setup_subquery_materialization(). We could make
- SELECT ... FROM DUAL call that function but that doesn't seem
- to be the case that is worth handling.
- 3. Either the subquery predicate is a top-level predicate, or at
- least one partial match strategy is enabled. If no partial match
- strategy is enabled, then materialization cannot be used for
- non-top-level queries because it cannot handle NULLs correctly.
- 4. Subquery is non-correlated
- TODO:
- This condition is too restrictive (limitation). It can be extended to:
- (Subquery is non-correlated ||
- Subquery is correlated to any query outer to IN predicate ||
- (Subquery is correlated to the immediate outer query &&
- Subquery !contains {GROUP BY, ORDER BY [LIMIT],
- aggregate functions}) && subquery predicate is not under "NOT IN"))
-
- (*) The subquery must be part of a SELECT statement. The current
- condition also excludes multi-table update statements.
- A note about prepared statements: we want the if-branch to be taken on
- PREPARE and each EXECUTE. The rewrites are only done once, but we need
- join->sj_subselects list to be populated for every EXECUTE.
-
- */
- if (optimizer_flag(thd, OPTIMIZER_SWITCH_MATERIALIZATION) && // 0
- !select_lex->is_part_of_union() && // 1
- parent_unit->first_select()->leaf_tables.elements && // 2
- thd->lex->sql_command == SQLCOM_SELECT && // *
- select_lex->outer_select()->leaf_tables.elements && // 2A
- subquery_types_allow_materialization(in_subs) &&
- (in_subs->is_top_level_item() || //3
- optimizer_flag(thd,
- OPTIMIZER_SWITCH_PARTIAL_MATCH_ROWID_MERGE) || //3
- optimizer_flag(thd,
- OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN)) && //3
- !in_subs->is_correlated) //4
- {
- in_subs->in_strategy|= SUBS_MATERIALIZATION;
+ if (is_materialization_applicable(thd, in_subs, select_lex))
+ {
+ in_subs->add_strategy(SUBS_MATERIALIZATION);
/*
If the subquery is an AND-part of WHERE register for being processed
with jtbm strategy
*/
- if (thd->thd_marker.emb_on_expr_nest == NO_JOIN_NEST &&
+ if (in_subs->emb_on_expr_nest == NO_JOIN_NEST &&
optimizer_flag(thd, OPTIMIZER_SWITCH_SEMIJOIN))
{
- in_subs->emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
in_subs->is_flattenable_semijoin= FALSE;
- select_lex->outer_select()->
- join->sj_subselects.append(thd->mem_root, in_subs);
+ if (!in_subs->is_registered_semijoin)
+ {
+ Query_arena *arena, backup;
+ arena= thd->activate_stmt_arena_if_needed(&backup);
+ select_lex->outer_select()->sj_subselects.push_back(in_subs);
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ in_subs->is_registered_semijoin= TRUE;
+ }
}
}
@@ -443,17 +479,18 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
possible.
*/
if (optimizer_flag(thd, OPTIMIZER_SWITCH_IN_TO_EXISTS) ||
- !in_subs->in_strategy)
- {
- in_subs->in_strategy|= SUBS_IN_TO_EXISTS;
- }
+ !in_subs->has_strategy())
+ in_subs->add_strategy(SUBS_IN_TO_EXISTS);
}
/* Check if max/min optimization applicable */
- if (allany_subs)
- allany_subs->in_strategy|= (allany_subs->is_maxmin_applicable(join) ?
- SUBS_MAXMIN :
- SUBS_IN_TO_EXISTS);
+ if (allany_subs && !allany_subs->is_set_strategy())
+ {
+ uchar strategy= (allany_subs->is_maxmin_applicable(join) ?
+ (SUBS_MAXMIN_INJECTED | SUBS_MAXMIN_ENGINE) :
+ SUBS_IN_TO_EXISTS);
+ allany_subs->add_strategy(strategy);
+ }
/*
Transform each subquery predicate according to its overloaded
@@ -547,6 +584,16 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs)
if (inner->field_type() == MYSQL_TYPE_BLOB ||
inner->field_type() == MYSQL_TYPE_GEOMETRY)
DBUG_RETURN(FALSE);
+ /*
+ Materialization also is unable to work when create_tmp_table() will
+ create a blob column because item->max_length is too big.
+ The following check is copied from Item::make_string_field():
+ */
+ if (inner->max_length / inner->collation.collation->mbmaxlen >
+ CONVERT_IF_BIGGER_TO_BLOB)
+ {
+ DBUG_RETURN(FALSE);
+ }
break;
case TIME_RESULT:
if (mysql_type_to_time_type(outer->field_type()) !=
@@ -731,21 +778,19 @@ bool check_for_outer_joins(List<TABLE_LIST> *join_list)
bool convert_join_subqueries_to_semijoins(JOIN *join)
{
Query_arena *arena, backup;
- Item_in_subselect **in_subq;
- Item_in_subselect **in_subq_end;
+ Item_in_subselect *in_subq;
THD *thd= join->thd;
List_iterator<TABLE_LIST> ti(join->select_lex->leaf_tables);
DBUG_ENTER("convert_join_subqueries_to_semijoins");
- if (join->sj_subselects.elements() == 0)
+ if (join->select_lex->sj_subselects.is_empty())
DBUG_RETURN(FALSE);
- for (in_subq= join->sj_subselects.front(),
- in_subq_end= join->sj_subselects.back();
- in_subq != in_subq_end;
- in_subq++)
+ List_iterator_fast<Item_in_subselect> li(join->select_lex->sj_subselects);
+
+ while ((in_subq= li++))
{
- SELECT_LEX *subq_sel= (*in_subq)->get_select_lex();
+ SELECT_LEX *subq_sel= in_subq->get_select_lex();
if (subq_sel->handle_derived(thd->lex, DT_OPTIMIZE))
DBUG_RETURN(1);
if (subq_sel->handle_derived(thd->lex, DT_MERGE))
@@ -753,13 +798,11 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
subq_sel->update_used_tables();
}
+ li.rewind();
/* First, convert child join's subqueries. We proceed bottom-up here */
- for (in_subq= join->sj_subselects.front(),
- in_subq_end= join->sj_subselects.back();
- in_subq != in_subq_end;
- in_subq++)
+ while ((in_subq= li++))
{
- st_select_lex *child_select= (*in_subq)->get_select_lex();
+ st_select_lex *child_select= in_subq->get_select_lex();
JOIN *child_join= child_select->join;
child_join->outer_tables = child_join->table_count;
@@ -773,19 +816,21 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
if (convert_join_subqueries_to_semijoins(child_join))
DBUG_RETURN(TRUE);
- (*in_subq)->sj_convert_priority=
- (*in_subq)->is_correlated * MAX_TABLES + child_join->outer_tables;
+ in_subq->sj_convert_priority=
+ test(in_subq->emb_on_expr_nest != NO_JOIN_NEST) * MAX_TABLES * 2 +
+ in_subq->is_correlated * MAX_TABLES + child_join->outer_tables;
}
// Temporary measure: disable semi-joins when they are together with outer
// joins.
+#if 0
if (check_for_outer_joins(join->join_list))
{
- in_subq= join->sj_subselects.front();
+ in_subq= join->select_lex->sj_subselects.head();
arena= thd->activate_stmt_arena_if_needed(&backup);
goto skip_conversion;
}
-
+#endif
//dump_TABLE_LIST_struct(select_lex, select_lex->leaf_tables);
/*
2. Pick which subqueries to convert:
@@ -793,75 +838,79 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
- prefer correlated subqueries over uncorrelated;
- prefer subqueries that have greater number of outer tables;
*/
- join->sj_subselects.sort(subq_sj_candidate_cmp);
+ bubble_sort<Item_in_subselect>(&join->select_lex->sj_subselects,
+ subq_sj_candidate_cmp, NULL);
// #tables-in-parent-query + #tables-in-subquery < MAX_TABLES
/* Replace all subqueries to be flattened with Item_int(1) */
arena= thd->activate_stmt_arena_if_needed(&backup);
- for (in_subq= join->sj_subselects.front();
- in_subq != in_subq_end;
- in_subq++)
+ li.rewind();
+ while ((in_subq= li++))
{
bool remove_item= TRUE;
- if ((*in_subq)->is_flattenable_semijoin)
+
+ /* Stop processing if we've reached a subquery that's attached to the ON clause */
+ if (in_subq->emb_on_expr_nest != NO_JOIN_NEST)
+ break;
+
+ if (in_subq->is_flattenable_semijoin)
{
if (join->table_count +
- (*in_subq)->unit->first_select()->join->table_count >= MAX_TABLES)
+ in_subq->unit->first_select()->join->table_count >= MAX_TABLES)
break;
- if (convert_subq_to_sj(join, *in_subq))
- DBUG_RETURN(TRUE);
+ if (convert_subq_to_sj(join, in_subq))
+ goto restore_arena_and_fail;
}
else
{
if (join->table_count + 1 >= MAX_TABLES)
break;
- if (convert_subq_to_jtbm(join, *in_subq, &remove_item))
- DBUG_RETURN(TRUE);
+ if (convert_subq_to_jtbm(join, in_subq, &remove_item))
+ goto restore_arena_and_fail;
}
if (remove_item)
{
- Item **tree= ((*in_subq)->emb_on_expr_nest == NO_JOIN_NEST)?
- &join->conds : &((*in_subq)->emb_on_expr_nest->on_expr);
- Item *replace_me= (*in_subq)->original_item();
+ Item **tree= (in_subq->emb_on_expr_nest == NO_JOIN_NEST)?
+ &join->conds : &(in_subq->emb_on_expr_nest->on_expr);
+ Item *replace_me= in_subq->original_item();
if (replace_where_subcondition(join, tree, replace_me, new Item_int(1),
FALSE))
- DBUG_RETURN(TRUE); /* purecov: inspected */
+ goto restore_arena_and_fail;
}
}
-skip_conversion:
+//skip_conversion:
/*
3. Finalize (perform IN->EXISTS rewrite) the subqueries that we didn't
convert:
*/
- for (; in_subq!= in_subq_end; in_subq++)
+ while (in_subq)
{
- JOIN *child_join= (*in_subq)->unit->first_select()->join;
- (*in_subq)->changed= 0;
- (*in_subq)->fixed= 0;
+ JOIN *child_join= in_subq->unit->first_select()->join;
+ in_subq->changed= 0;
+ in_subq->fixed= 0;
SELECT_LEX *save_select_lex= thd->lex->current_select;
- thd->lex->current_select= (*in_subq)->unit->first_select();
+ thd->lex->current_select= in_subq->unit->first_select();
- bool res= (*in_subq)->select_transformer(child_join);
+ bool res= in_subq->select_transformer(child_join);
thd->lex->current_select= save_select_lex;
if (res)
DBUG_RETURN(TRUE);
- (*in_subq)->changed= 1;
- (*in_subq)->fixed= 1;
+ in_subq->changed= 1;
+ in_subq->fixed= 1;
- Item *substitute= (*in_subq)->substitution;
- bool do_fix_fields= !(*in_subq)->substitution->fixed;
- Item **tree= ((*in_subq)->emb_on_expr_nest == NO_JOIN_NEST)?
- &join->conds : &((*in_subq)->emb_on_expr_nest->on_expr);
- Item *replace_me= (*in_subq)->original_item();
+ Item *substitute= in_subq->substitution;
+ bool do_fix_fields= !in_subq->substitution->fixed;
+ Item **tree= (in_subq->emb_on_expr_nest == NO_JOIN_NEST)?
+ &join->conds : &(in_subq->emb_on_expr_nest->on_expr);
+ Item *replace_me= in_subq->original_item();
if (replace_where_subcondition(join, tree, replace_me, substitute,
do_fix_fields))
DBUG_RETURN(TRUE);
- (*in_subq)->substitution= NULL;
-
+ in_subq->substitution= NULL;
/*
If this is a prepared statement, repeat the above operation for
prep_where (or prep_on_expr). Subquery-to-semijoin conversion is
@@ -869,29 +918,41 @@ skip_conversion:
*/
if (!thd->stmt_arena->is_conventional())
{
- tree= ((*in_subq)->emb_on_expr_nest == NO_JOIN_NEST)?
+ tree= (in_subq->emb_on_expr_nest == NO_JOIN_NEST)?
&join->select_lex->prep_where :
- &((*in_subq)->emb_on_expr_nest->prep_on_expr);
-
- if (replace_where_subcondition(join, tree, replace_me, substitute,
+ &(in_subq->emb_on_expr_nest->prep_on_expr);
+ /*
+ prep_on_expr/ prep_where may be NULL in some cases.
+ If that is the case, do nothing - simplify_joins() will copy
+ ON/WHERE expression into prep_on_expr/prep_where.
+ */
+ if (*tree && replace_where_subcondition(join, tree, replace_me, substitute,
FALSE))
DBUG_RETURN(TRUE);
}
/*
Revert to the IN->EXISTS strategy in the rare case when the subquery could
not be flattened.
- TODO: This is a limitation done for simplicity. Such subqueries could also
- be executed via materialization. In order to determine this, we should
- re-run the test for materialization that was done in
- check_and_do_in_subquery_rewrites.
*/
- (*in_subq)->in_strategy= SUBS_IN_TO_EXISTS;
+ in_subq->reset_strategy(SUBS_IN_TO_EXISTS);
+ if (is_materialization_applicable(thd, in_subq,
+ in_subq->unit->first_select()))
+ {
+ in_subq->add_strategy(SUBS_MATERIALIZATION);
+ }
+
+ in_subq= li++;
}
if (arena)
thd->restore_active_arena(arena, &backup);
- join->sj_subselects.clear();
+ join->select_lex->sj_subselects.empty();
DBUG_RETURN(FALSE);
+
+restore_arena_and_fail:
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ DBUG_RETURN(TRUE);
}
@@ -962,7 +1023,6 @@ static bool replace_where_subcondition(JOIN *join, Item **expr,
Item *old_cond, Item *new_cond,
bool do_fix_fields)
{
- //Item **expr= (emb_nest == (TABLE_LIST*)1)? &join->conds : &emb_nest->on_expr;
if (*expr == old_cond)
{
*expr= new_cond;
@@ -986,16 +1046,22 @@ static bool replace_where_subcondition(JOIN *join, Item **expr,
}
}
}
- // If we came here it means there were an error during prerequisites check.
- DBUG_ASSERT(0);
- return TRUE;
+ /*
+ We can come to here when
+ - we're doing replace operations on both on_expr and prep_on_expr
+ - on_expr is the same as prep_on_expr, or they share a sub-tree
+ (so, when we do replace in on_expr, we replace in prep_on_expr, too,
+ and when we try doing a replace in prep_on_expr, the item we wanted
+ to replace there has already been replaced)
+ */
+ return FALSE;
}
-static int subq_sj_candidate_cmp(Item_in_subselect* const *el1,
- Item_in_subselect* const *el2)
+static int subq_sj_candidate_cmp(Item_in_subselect* el1, Item_in_subselect* el2,
+ void *arg)
{
- return ((*el1)->sj_convert_priority < (*el2)->sj_convert_priority) ? 1 :
- ( ((*el1)->sj_convert_priority == (*el2)->sj_convert_priority)? 0 : -1);
+ return (el1->sj_convert_priority > el2->sj_convert_priority) ? 1 :
+ ( (el1->sj_convert_priority == el2->sj_convert_priority)? 0 : -1);
}
@@ -1191,7 +1257,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
/* 3. Remove the original subquery predicate from the WHERE/ON */
// The subqueries were replaced for Item_int(1) earlier
- subq_pred->in_strategy= SUBS_SEMI_JOIN; // for subsequent executions
+ subq_pred->reset_strategy(SUBS_SEMI_JOIN); // for subsequent executions
/*TODO: also reset the 'with_subselect' there. */
/* n. Adjust the parent_join->table_count counter */
@@ -1202,6 +1268,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
{
tl->table->tablenr= table_no;
tl->table->map= ((table_map)1) << table_no;
+ if (tl->is_jtbm())
+ tl->jtbm_table_no= tl->table->tablenr;
SELECT_LEX *old_sl= tl->select_lex;
tl->select_lex= parent_join->select_lex;
for (TABLE_LIST *emb= tl->embedding;
@@ -1211,6 +1279,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
table_no++;
}
parent_join->table_count += subq_lex->join->table_count;
+ //parent_join->table_count += subq_lex->leaf_tables.elements;
/*
Put the subquery's WHERE into semi-join's sj_on_expr
@@ -1290,6 +1359,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
{
emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr,
sj_nest->sj_on_expr);
+ emb_tbl_nest->on_expr->top_level_item();
if (!emb_tbl_nest->on_expr->fixed)
emb_tbl_nest->on_expr->fix_fields(parent_join->thd,
&emb_tbl_nest->on_expr);
@@ -1298,6 +1368,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
{
/* Inject into the WHERE */
parent_join->conds= and_items(parent_join->conds, sj_nest->sj_on_expr);
+ parent_join->conds->top_level_item();
/*
fix_fields must update the properties (e.g. st_select_lex::cond_count of
the correct select_lex.
@@ -1360,8 +1431,9 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
double read_time;
DBUG_ENTER("convert_subq_to_jtbm");
- subq_pred->in_strategy &= ~SUBS_IN_TO_EXISTS;
- subq_pred->optimize(&rows, &read_time);
+ subq_pred->set_strategy(SUBS_MATERIALIZATION);
+ if (subq_pred->optimize(&rows, &read_time))
+ DBUG_RETURN(TRUE);
subq_pred->jtbm_read_time= read_time;
subq_pred->jtbm_record_count=rows;
@@ -1479,6 +1551,25 @@ void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist)
}
+static void set_emb_join_nest(List<TABLE_LIST> *tables, TABLE_LIST *emb_sj_nest)
+{
+ List_iterator<TABLE_LIST> it(*tables);
+ TABLE_LIST *tbl;
+ while ((tbl= it++))
+ {
+ /*
+ Note: check for nested_join first.
+ derived-merged tables have tbl->table!=NULL &&
+ tbl->table->reginfo==NULL.
+ */
+ if (tbl->nested_join)
+ set_emb_join_nest(&tbl->nested_join->join_list, emb_sj_nest);
+ else if (tbl->table)
+ tbl->table->reginfo.join_tab->emb_sj_nest= emb_sj_nest;
+
+ }
+}
+
/*
Pull tables out of semi-join nests, if possible
@@ -1534,10 +1625,34 @@ int pull_out_semijoin_tables(JOIN *join)
/* Try pulling out of the each of the semi-joins */
while ((sj_nest= sj_list_it++))
{
- /* Action #1: Mark the constant tables to be pulled out */
- table_map pulled_tables= 0;
List_iterator<TABLE_LIST> child_li(sj_nest->nested_join->join_list);
TABLE_LIST *tbl;
+
+ /*
+ Don't do table pull-out for nested joins (if we get nested joins here, it
+ means these are outer joins. It is theoretically possible to do pull-out
+ for some of the outer tables but we dont support this currently.
+ */
+ bool have_join_nest_children= FALSE;
+
+ set_emb_join_nest(&sj_nest->nested_join->join_list, sj_nest);
+
+ while ((tbl= child_li++))
+ {
+ if (tbl->nested_join)
+ {
+ have_join_nest_children= TRUE;
+ break;
+ }
+ }
+
+
+ table_map pulled_tables= 0;
+ if (have_join_nest_children)
+ goto skip;
+
+ /* Action #1: Mark the constant tables to be pulled out */
+ child_li.rewind();
while ((tbl= child_li++))
{
if (tbl->table)
@@ -1609,6 +1724,7 @@ int pull_out_semijoin_tables(JOIN *join)
} while (pulled_a_table);
child_li.rewind();
+ skip:
/*
Action #3: Move the pulled out TABLE_LIST elements to the parents.
*/
@@ -1688,6 +1804,9 @@ int pull_out_semijoin_tables(JOIN *join)
All obtained information is saved and will be used by the main join
optimization pass.
+
+ NOTES
+ Because of Join::reoptimize(), this function may be called multiple times.
RETURN
FALSE Ok
@@ -1745,9 +1864,12 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map)
sjm->materialization_cost.convert_from_cost(subjoin_read_time);
sjm->rows= subjoin_out_rows;
-
- List<Item> &right_expr_list=
- sj_nest->sj_subq_pred->unit->first_select()->item_list;
+
+ // Don't use the following list because it has "stale" items. use
+ // ref_pointer_array instead:
+ //
+ //List<Item> &right_expr_list=
+ // sj_nest->sj_subq_pred->unit->first_select()->item_list;
/*
Adjust output cardinality estimates. If the subquery has form
@@ -1765,17 +1887,20 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map)
See also get_post_group_estimate().
*/
+ SELECT_LEX *subq_select= sj_nest->sj_subq_pred->unit->first_select();
{
for (uint i=0 ; i < join->const_tables + sjm->tables ; i++)
{
JOIN_TAB *tab= join->best_positions[i].table;
join->map2table[tab->table->tablenr]= tab;
}
- List_iterator<Item> it(right_expr_list);
- Item *item;
+ //List_iterator<Item> it(right_expr_list);
+ Item **ref_array= subq_select->ref_pointer_array;
+ Item **ref_array_end= ref_array + subq_select->item_list.elements;
table_map map= 0;
- while ((item= it++))
- map |= item->used_tables();
+ //while ((item= it++))
+ for (;ref_array < ref_array_end; ref_array++)
+ map |= (*ref_array)->used_tables();
map= map & ~PSEUDO_TABLE_BITS;
Table_map_iterator tm_it(map);
int tableno;
@@ -1790,7 +1915,8 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map)
/*
Calculate temporary table parameters and usage costs
*/
- uint rowlen= get_tmp_table_rec_length(right_expr_list);
+ uint rowlen= get_tmp_table_rec_length(subq_select->ref_pointer_array,
+ subq_select->item_list.elements);
double lookup_cost= get_tmp_table_lookup_cost(join->thd,
subjoin_out_rows, rowlen);
double write_cost= get_tmp_table_write_cost(join->thd,
@@ -1837,13 +1963,15 @@ bool optimize_semijoin_nests(JOIN *join, table_map all_table_map)
Length of the temptable record, in bytes
*/
-static uint get_tmp_table_rec_length(List<Item> &items)
+static uint get_tmp_table_rec_length(Item **p_items, uint elements)
{
uint len= 0;
Item *item;
- List_iterator<Item> it(items);
- while ((item= it++))
+ //List_iterator<Item> it(items);
+ Item **p_item;
+ for (p_item= p_items; p_item < p_items + elements ; p_item++)
{
+ item = *p_item;
switch (item->result_type()) {
case REAL_RESULT:
len += sizeof(double);
@@ -2053,6 +2181,17 @@ void advance_sj_state(JOIN *join, table_map remaining_tables,
pos->sj_strategy= SJ_OPT_NONE;
pos->prefix_dups_producing_tables= join->cur_dups_producing_tables;
+
+ /* We're performing optimization inside SJ-Materialization nest */
+ if (join->emb_sjm_nest)
+ {
+ pos->invalidate_firstmatch_prefix();
+ pos->first_loosescan_table= MAX_TABLES;
+ pos->dupsweedout_tables= 0;
+ pos->sjm_scan_need_tables= 0;
+ return;
+ }
+
/* Initialize the state or copy it from prev. tables */
if (idx == join->const_tables)
{
@@ -2091,7 +2230,8 @@ void advance_sj_state(JOIN *join, table_map remaining_tables,
table_map handled_by_fm_or_ls= 0;
/* FirstMatch Strategy */
if (new_join_tab->emb_sj_nest &&
- optimizer_flag(join->thd, OPTIMIZER_SWITCH_FIRSTMATCH))
+ optimizer_flag(join->thd, OPTIMIZER_SWITCH_FIRSTMATCH) &&
+ !join->outer_join)
{
const table_map outer_corr_tables=
new_join_tab->emb_sj_nest->nested_join->sj_corr_tables |
@@ -2186,7 +2326,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables,
If we got an option to use LooseScan for the current table, start
considering using LooseScan strategy
*/
- if (loose_scan_pos->read_time != DBL_MAX)
+ if (loose_scan_pos->read_time != DBL_MAX && !join->outer_join)
{
pos->first_loosescan_table= idx;
pos->loosescan_need_tables=
@@ -2394,6 +2534,15 @@ void advance_sj_state(JOIN *join, table_map remaining_tables,
nest->nested_join->sj_depends_on |
nest->nested_join->sj_corr_tables;
}
+
+ if (pos->dupsweedout_tables)
+ {
+ /* we're in the process of constructing a DuplicateWeedout range */
+ TABLE_LIST *emb= new_join_tab->table->pos_in_table_list->embedding;
+ /* and we've entered an inner side of an outer join*/
+ if (emb && emb->on_expr)
+ pos->dupsweedout_tables |= emb->nested_join->used_tables;
+ }
if (pos->dupsweedout_tables &&
!(remaining_tables &
@@ -2549,6 +2698,7 @@ ulonglong get_bound_sj_equalities(TABLE_LIST *sj_nest,
{
res |= 1ULL << i;
}
+ i++;
}
return res;
}
@@ -2840,27 +2990,36 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
TRUE Error
*/
-bool setup_sj_materialization(JOIN_TAB *sjm_tab)
+bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
{
- uint i;
DBUG_ENTER("setup_sj_materialization");
JOIN_TAB *tab= sjm_tab->bush_children->start;
TABLE_LIST *emb_sj_nest= tab->table->pos_in_table_list->embedding;
+
+ /* Walk out of outer join nests until we reach the semi-join nest we're in */
+ while (!emb_sj_nest->sj_mat_info)
+ emb_sj_nest= emb_sj_nest->embedding;
+
SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
THD *thd= tab->join->thd;
/* First the calls come to the materialization function */
- List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list;
-
+ //List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list;
+
+ DBUG_ASSERT(sjm->is_used);
/*
Set up the table to write to, do as select_union::create_result_table does
*/
sjm->sjm_table_param.init();
- sjm->sjm_table_param.field_count= item_list.elements;
sjm->sjm_table_param.bit_fields_as_long= TRUE;
- List_iterator<Item> it(item_list);
- Item *right_expr;
- while((right_expr= it++))
- sjm->sjm_table_cols.push_back(right_expr);
+ //List_iterator<Item> it(item_list);
+ SELECT_LEX *subq_select= emb_sj_nest->sj_subq_pred->unit->first_select();
+ Item **p_item= subq_select->ref_pointer_array;
+ Item **p_end= p_item + subq_select->item_list.elements;
+ //while((right_expr= it++))
+ for(;p_item != p_end; p_item++)
+ sjm->sjm_table_cols.push_back(*p_item);
+
+ sjm->sjm_table_param.field_count= subq_select->item_list.elements;
if (!(sjm->table= create_tmp_table(thd, &sjm->sjm_table_param,
sjm->sjm_table_cols, (ORDER*) 0,
@@ -2878,6 +3037,25 @@ bool setup_sj_materialization(JOIN_TAB *sjm_tab)
sjm->materialized= FALSE;
sjm_tab->table= sjm->table;
+ sjm->table->pos_in_table_list= emb_sj_nest;
+
+ DBUG_RETURN(FALSE);
+}
+
+
+bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab)
+{
+ DBUG_ENTER("setup_sj_materialization_part2");
+ JOIN_TAB *tab= sjm_tab->bush_children->start;
+ TABLE_LIST *emb_sj_nest= tab->table->pos_in_table_list->embedding;
+ /* Walk out of outer join nests until we reach the semi-join nest we're in */
+ while (!emb_sj_nest->sj_mat_info)
+ emb_sj_nest= emb_sj_nest->embedding;
+ SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
+ THD *thd= tab->join->thd;
+ uint i;
+ //List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list;
+ //List_iterator<Item> it(item_list);
if (!sjm->is_sj_scan)
{
@@ -2992,12 +3170,14 @@ bool setup_sj_materialization(JOIN_TAB *sjm_tab)
in the record buffers for the source tables.
*/
sjm->copy_field= new Copy_field[sjm->sjm_table_cols.elements];
- it.rewind();
+ //it.rewind();
+ Item **p_item= emb_sj_nest->sj_subq_pred->unit->first_select()->ref_pointer_array;
for (uint i=0; i < sjm->sjm_table_cols.elements; i++)
{
bool dummy;
Item_equal *item_eq;
- Item *item= (it++)->real_item();
+ //Item *item= (it++)->real_item();
+ Item *item= (*(p_item++))->real_item();
DBUG_ASSERT(item->type() == Item::FIELD_ITEM);
Field *copy_to= ((Item_field*)item)->field;
/*
@@ -3032,11 +3212,15 @@ bool setup_sj_materialization(JOIN_TAB *sjm_tab)
if (item_eq)
{
List_iterator<Item> it(item_eq->equal_items);
+ /* We're interested in field items only */
+ if (item_eq->get_const())
+ it++;
Item *item;
while ((item= it++))
{
if (!(item->used_tables() & ~emb_sj_nest->sj_inner_tables))
{
+ DBUG_ASSERT(item->real_item()->type() == Item::FIELD_ITEM);
copy_to= ((Item_field *) (item->real_item()))->field;
break;
}
@@ -3203,7 +3387,7 @@ TABLE *create_duplicate_weedout_tmp_table(THD *thd,
bool using_unique_constraint=FALSE;
bool use_packed_rows= FALSE;
Field *field, *key_field;
- uint blob_count, null_pack_length, null_count;
+ uint null_pack_length, null_count;
uchar *null_flags;
uchar *pos;
DBUG_ENTER("create_duplicate_weedout_tmp_table");
@@ -3284,8 +3468,6 @@ TABLE *create_duplicate_weedout_tmp_table(THD *thd,
share->keys_for_keyread.init();
share->keys_in_use.init();
- blob_count= 0;
-
/* Create the field */
{
/*
@@ -3702,6 +3884,8 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
{
/* We jump from the last table to the first one */
tab->loosescan_match_tab= tab + pos->n_sj_tables - 1;
+ for (uint j= i; j < i + pos->n_sj_tables; j++)
+ join->join_tab[j].inside_loosescan_range= TRUE;
/* Calculate key length */
keylen= 0;
@@ -4216,6 +4400,8 @@ bool JOIN::optimize_unflattened_subqueries()
Currently there are only two possible startup functions, so we have them
both here inside if (...) branches. In future we could switch to function
pointers.
+
+ TODO: consider moving this together with JOIN_TAB::preread_init
RETURN
NESTED_LOOP_OK - OK
@@ -4325,8 +4511,8 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
}
else
return false;
-
- DBUG_ASSERT(in_subs->in_strategy); /* A strategy must be chosen earlier. */
+ /* A strategy must be chosen earlier. */
+ DBUG_ASSERT(in_subs->has_strategy());
DBUG_ASSERT(in_to_exists_where || in_to_exists_having);
DBUG_ASSERT(!in_to_exists_where || in_to_exists_where->fixed);
DBUG_ASSERT(!in_to_exists_having || in_to_exists_having->fixed);
@@ -4336,13 +4522,11 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
strategies are possible and allowed by the user (checked during the prepare
phase.
*/
- if (in_subs->in_strategy & SUBS_MATERIALIZATION &&
- in_subs->in_strategy & SUBS_IN_TO_EXISTS)
+ if (in_subs->test_strategy(SUBS_MATERIALIZATION) &&
+ in_subs->test_strategy(SUBS_IN_TO_EXISTS))
{
JOIN *outer_join;
JOIN *inner_join= this;
- /* Number of (partial) rows of the outer JOIN filtered by the IN predicate. */
- double outer_record_count;
/* Number of unique value combinations filtered by the IN predicate. */
double outer_lookup_keys;
/* Cost and row count of the unmodified subquery. */
@@ -4360,40 +4544,24 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
by the IN predicate.
*/
outer_join= unit->outer_select() ? unit->outer_select()->join : NULL;
- if (outer_join)
+ if (outer_join && outer_join->table_count > 0)
{
- uint outer_partial_plan_len;
/*
- Make_cond_for_table is called for predicates only in the WHERE/ON
- clauses. In all other cases, predicates are not pushed to any
- JOIN_TAB, and their joi_tab_idx remains MAX_TABLES. Such predicates
- are evaluated for each complete row of the outer join.
+ TODO:
+ Currently outer_lookup_keys is computed as the number of rows in
+ the partial join including the JOIN_TAB where the IN predicate is
+ pushed to. In the general case this is a gross overestimate because
+ due to caching we are interested only in the number of unique keys.
+ The search key may be formed by columns from much fewer than all
+ tables in the partial join. Example:
+ select * from t1, t2 where t1.c1 = t2.key AND t2.c2 IN (select ...);
+ If the join order: t1, t2, the number of unique lookup keys is ~ to
+ the number of unique values t2.c2 in the partial join t1 join t2.
*/
- outer_partial_plan_len= (in_subs->get_join_tab_idx() == MAX_TABLES) ?
- outer_join->table_count :
- in_subs->get_join_tab_idx() + 1;
- outer_join->get_partial_cost_and_fanout(outer_partial_plan_len,
+ outer_join->get_partial_cost_and_fanout(in_subs->get_join_tab_idx(),
table_map(-1),
&dummy,
- &outer_record_count);
-
- if (outer_join->table_count > outer_join->const_tables)
- {
- outer_join->get_partial_cost_and_fanout(outer_partial_plan_len,
- in_subs->used_tables(),
- &dummy,
- &outer_lookup_keys);
- /*
- outer_lookup_keys= prev_record_reads(outer_join->best_positions,
- outer_partial_plan_len,
- in_subs->used_tables());
- */
- }
- else
- {
- /* If all tables are constant, positions is undefined. */
- outer_lookup_keys= 1;
- }
+ &outer_lookup_keys);
}
else
{
@@ -4401,17 +4569,8 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
TODO: outer_join can be NULL for DELETE statements.
How to compute its cost?
*/
- outer_record_count= 1;
- outer_lookup_keys=1;
+ outer_lookup_keys= 1;
}
- /*
- There cannot be more lookup keys than the total number of records.
- TODO: this a temporary solution until we find a better way to compute
- get_partial_join_cost() and prev_record_reads() in a consitent manner,
- where it is guaranteed that (outer_lookup_keys <= outer_record_count).
- */
- if (outer_lookup_keys > outer_record_count)
- outer_lookup_keys= outer_record_count;
/*
B. Estimate the cost and number of records of the subquery both
@@ -4444,7 +4603,9 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
C. Compute execution costs.
*/
/* C.1 Compute the cost of the materialization strategy. */
- uint rowlen= get_tmp_table_rec_length(unit->first_select()->item_list);
+ //uint rowlen= get_tmp_table_rec_length(unit->first_select()->item_list);
+ uint rowlen= get_tmp_table_rec_length(ref_pointer_array,
+ select_lex->item_list.elements);
/* The cost of writing one row into the temporary table. */
double write_cost= get_tmp_table_write_cost(thd, inner_record_count_1,
rowlen);
@@ -4459,16 +4620,24 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
write_cost * inner_record_count_1;
materialize_strategy_cost= materialization_cost +
- outer_record_count * lookup_cost;
+ outer_lookup_keys * lookup_cost;
/* C.2 Compute the cost of the IN=>EXISTS strategy. */
in_exists_strategy_cost= outer_lookup_keys * inner_read_time_2;
/* C.3 Compare the costs and choose the cheaper strategy. */
if (materialize_strategy_cost >= in_exists_strategy_cost)
- in_subs->in_strategy&= ~SUBS_MATERIALIZATION;
+ in_subs->set_strategy(SUBS_IN_TO_EXISTS);
else
- in_subs->in_strategy&= ~SUBS_IN_TO_EXISTS;
+ in_subs->set_strategy(SUBS_MATERIALIZATION);
+
+ DBUG_PRINT("info",
+ ("mat_strategy_cost: %.2f, mat_cost: %.2f, write_cost: %.2f, lookup_cost: %.2f",
+ materialize_strategy_cost, materialization_cost, write_cost, lookup_cost));
+ DBUG_PRINT("info",
+ ("inx_strategy_cost: %.2f, inner_read_time_2: %.2f",
+ in_exists_strategy_cost, inner_read_time_2));
+ DBUG_PRINT("info",("outer_lookup_keys: %.2f", outer_lookup_keys));
}
/*
@@ -4481,7 +4650,7 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
otherwise
use materialization.
*/
- if (in_subs->in_strategy & SUBS_MATERIALIZATION &&
+ if (in_subs->test_strategy(SUBS_MATERIALIZATION) &&
in_subs->setup_mat_engine())
{
/*
@@ -4489,11 +4658,10 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
but it is not possible to execute it due to limitations in the
implementation, fall back to IN-TO-EXISTS.
*/
- in_subs->in_strategy&= ~SUBS_MATERIALIZATION;
- in_subs->in_strategy|= SUBS_IN_TO_EXISTS;
+ in_subs->set_strategy(SUBS_IN_TO_EXISTS);
}
- if (in_subs->in_strategy & SUBS_MATERIALIZATION)
+ if (in_subs->test_strategy(SUBS_MATERIALIZATION))
{
/* Restore the original query plan used for materialization. */
if (reopt_result == REOPT_NEW_PLAN)
@@ -4518,23 +4686,18 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
*/
select_limit= in_subs->unit->select_limit_cnt;
}
- else if (in_subs->in_strategy & SUBS_IN_TO_EXISTS)
+ else if (in_subs->test_strategy(SUBS_IN_TO_EXISTS))
{
if (reopt_result == REOPT_NONE && in_to_exists_where &&
const_tables != table_count)
{
/*
- The subquery was not reoptimized either because the user allowed only the
- IN-EXISTS strategy, or because materialization was not possible based on
- semantic analysis. Clenup the original plan and reoptimize.
+ The subquery was not reoptimized with the newly injected IN-EXISTS
+ conditions either because the user allowed only the IN-EXISTS strategy,
+ or because materialization was not possible based on semantic analysis.
*/
- for (uint i= 0; i < table_count; i++)
- {
- join_tab[i].keyuse= NULL;
- join_tab[i].checked_keys.clear_all();
- }
- if ((reopt_result= reoptimize(in_to_exists_where, join_tables, NULL)) ==
- REOPT_ERROR)
+ reopt_result= reoptimize(in_to_exists_where, join_tables, NULL);
+ if (reopt_result == REOPT_ERROR)
return TRUE;
}
@@ -4604,7 +4767,7 @@ bool JOIN::choose_tableless_subquery_plan()
{
Item_in_subselect *in_subs;
in_subs= (Item_in_subselect*) subs_predicate;
- in_subs->in_strategy= SUBS_IN_TO_EXISTS;
+ in_subs->set_strategy(SUBS_IN_TO_EXISTS);
if (in_subs->create_in_to_exists_cond(this) ||
in_subs->inject_in_to_exists_cond(this))
return TRUE;
diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h
index 4d89609e1a8..571fcbaa935 100644
--- a/sql/opt_subselect.h
+++ b/sql/opt_subselect.h
@@ -285,7 +285,9 @@ void restore_prev_sj_state(const table_map remaining_tables,
const JOIN_TAB *tab, uint idx);
void fix_semijoin_strategies_for_picked_join_order(JOIN *join);
-bool setup_sj_materialization(JOIN_TAB *tab);
+
+bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab);
+bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab);
TABLE *create_duplicate_weedout_tmp_table(THD *thd, uint uniq_tuple_length_arg,
SJ_TMP_TABLE *sjtbl);
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 965eb853471..7b4c48497fa 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -494,28 +494,30 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
/* MULT_EQUAL_FUNC */
{
Item_equal *item_equal= (Item_equal *) func_item;
+ if (!(args[1]= item_equal->get_const()))
+ return 0;
Item_equal_fields_iterator it(*item_equal);
- args[0]= it++;
- if (it++)
+ if (!(item= it++))
return 0;
- if (!(args[1]= item_equal->get_const()))
+ args[0]= item->real_item();
+ if (it++)
return 0;
}
break;
case 1:
/* field IS NULL */
- item= func_item->arguments()[0];
+ item= func_item->arguments()[0]->real_item();
if (item->type() != Item::FIELD_ITEM)
return 0;
args[0]= item;
break;
case 2:
/* 'field op const' or 'const op field' */
- item= func_item->arguments()[0];
+ item= func_item->arguments()[0]->real_item();
if (item->type() == Item::FIELD_ITEM)
{
args[0]= item;
- item= func_item->arguments()[1];
+ item= func_item->arguments()[1]->real_item();
if (!item->const_item())
return 0;
args[1]= item;
@@ -523,7 +525,7 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
else if (item->const_item())
{
args[1]= item;
- item= func_item->arguments()[1];
+ item= func_item->arguments()[1]->real_item();
if (item->type() != Item::FIELD_ITEM)
return 0;
args[0]= item;
@@ -534,13 +536,13 @@ bool simple_pred(Item_func *func_item, Item **args, bool *inv_order)
break;
case 3:
/* field BETWEEN const AND const */
- item= func_item->arguments()[0];
+ item= func_item->arguments()[0]->real_item();
if (item->type() == Item::FIELD_ITEM)
{
args[0]= item;
for (int i= 1 ; i <= 2; i++)
{
- item= func_item->arguments()[i];
+ item= func_item->arguments()[i]->real_item();
if (!item->const_item())
return 0;
args[i]= item;
@@ -621,8 +623,10 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
if (!(cond->used_tables() & field->table->map))
{
/* Condition doesn't restrict the used table */
- DBUG_RETURN(TRUE);
+ DBUG_RETURN(!cond->const_item());
}
+ else if (cond->is_expensive())
+ DBUG_RETURN(FALSE);
if (cond->type() == Item::COND_ITEM)
{
if (((Item_cond*) cond)->functype() == Item_func::COND_OR_FUNC)
@@ -669,6 +673,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
case Item_func::GE_FUNC:
break;
case Item_func::BETWEEN:
+ if (((Item_func_between*) cond)->negated)
+ DBUG_RETURN(FALSE);
between= 1;
break;
case Item_func::MULT_EQUAL_FUNC:
diff --git a/sql/opt_table_elimination.cc b/sql/opt_table_elimination.cc
index c8c61720068..56396181619 100644
--- a/sql/opt_table_elimination.cc
+++ b/sql/opt_table_elimination.cc
@@ -588,10 +588,8 @@ void eliminate_tables(JOIN *join)
if (!join->outer_join)
DBUG_VOID_RETURN;
-#ifndef DBUG_OFF
if (!optimizer_flag(thd, OPTIMIZER_SWITCH_TABLE_ELIMINATION))
DBUG_VOID_RETURN; /* purecov: inspected */
-#endif
/* Find the tables that are referred to from WHERE/HAVING */
used_tables= (join->conds? join->conds->used_tables() : 0) |
diff --git a/sql/parse_file.cc b/sql/parse_file.cc
index 5bc16e55ec0..3ccbfba5aff 100644
--- a/sql/parse_file.cc
+++ b/sql/parse_file.cc
@@ -381,7 +381,7 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root,
DBUG_RETURN(0);
}
- if (!(parser->buff= (char*) alloc_root(mem_root, stat_info.st_size+1)))
+ if (!(parser->buff= (char*) alloc_root(mem_root, (size_t)(stat_info.st_size+1))))
{
DBUG_RETURN(0);
}
@@ -392,7 +392,7 @@ sql_parse_prepare(const LEX_STRING *file_name, MEM_ROOT *mem_root,
}
if ((len= my_read(file, (uchar *)parser->buff,
- stat_info.st_size, MYF(MY_WME))) ==
+ (size_t) stat_info.st_size, MYF(MY_WME))) ==
MY_FILE_ERROR)
{
my_close(file, MYF(MY_WME));
diff --git a/sql/protocol.cc b/sql/protocol.cc
index a0e14423b73..af4324b4166 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -515,6 +515,56 @@ void net_end_statement(THD *thd)
}
+/**
+ Send a progress report to the client
+
+ What we send is:
+ header (255,255,255,1)
+ stage, max_stage as on byte integers
+ percentage withing the stage as percentage*1000
+ (that is, ratio*100000) as a 3 byte integer
+ proc_info as a string
+*/
+
+const uchar progress_header[2]= {(uchar) 255, (uchar) 255 };
+
+void net_send_progress_packet(THD *thd)
+{
+ uchar buff[200], *pos;
+ const char *proc_info= thd->proc_info ? thd->proc_info : "";
+ uint length= strlen(proc_info);
+ ulonglong progress;
+ DBUG_ENTER("net_send_progress_packet");
+
+ if (unlikely(!thd->net.vio))
+ DBUG_VOID_RETURN; // Socket is closed
+
+ pos= buff;
+ /*
+ Store number of strings first. This allows us to later expand the
+ progress indicator if needed.
+ */
+ *pos++= (uchar) 1; // Number of strings
+ *pos++= (uchar) thd->progress.stage + 1;
+ /*
+ We have the max() here to avoid problems if max_stage is not set,
+ which may happen during automatic repair of table
+ */
+ *pos++= (uchar) max(thd->progress.max_stage, thd->progress.stage + 1);
+ progress= 0;
+ if (thd->progress.max_counter)
+ progress= 100000ULL * thd->progress.counter / thd->progress.max_counter;
+ int3store(pos, progress); // Between 0 & 100000
+ pos+= 3;
+ pos= net_store_data(pos, (const uchar*) proc_info,
+ min(length, sizeof(buff)-7));
+ net_write_command(&thd->net, (uchar) 255, progress_header,
+ sizeof(progress_header), (uchar*) buff,
+ (uint) (pos - buff));
+ DBUG_VOID_RETURN;
+}
+
+
/****************************************************************************
Functions used by the protocol functions (like net_send_ok) to store
strings and numbers in the header result packet.
diff --git a/sql/protocol.h b/sql/protocol.h
index 4ab5c169928..e07af5208db 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -177,6 +177,7 @@ public:
void send_warning(THD *thd, uint sql_errno, const char *err=0);
bool net_send_error(THD *thd, uint sql_errno=0, const char *err=0);
void net_end_statement(THD *thd);
+void net_send_progress_packet(THD *thd);
uchar *net_store_data(uchar *to,const uchar *from, size_t length);
uchar *net_store_data(uchar *to,int32 from);
uchar *net_store_data(uchar *to,longlong from);
diff --git a/sql/records.cc b/sql/records.cc
index 5ce7d8660e9..b125c201621 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -59,7 +59,6 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
bzero((char*) info,sizeof(*info));
info->thd= thd;
info->table= table;
- info->file= table->file;
info->record= table->record[0];
info->print_error= print_error;
info->unlock_row= rr_unlock_row;
@@ -169,7 +168,6 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
bzero((char*) info,sizeof(*info));
info->thd=thd;
info->table=table;
- info->file= table->file;
info->forms= &info->table; /* Only one table */
if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE &&
@@ -195,15 +193,6 @@ bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
if (select && my_b_inited(&select->file))
tempfile= &select->file;
- else if (select && select->quick && select->quick->clustered_pk_range())
- {
- /*
- In case of QUICK_INDEX_MERGE_SELECT with clustered pk range we have to
- use its own access method(i.e QUICK_INDEX_MERGE_SELECT::get_next()) as
- sort file does not contain rowids which satisfy clustered pk range.
- */
- tempfile= 0;
- }
else
tempfile= table->sort.io_cache;
if (tempfile && my_b_inited(tempfile) &&
@@ -300,9 +289,9 @@ void end_read_record(READ_RECORD *info)
{
filesort_free_buffers(info->table,0);
if (info->table->created)
- (void) info->file->extra(HA_EXTRA_NO_CACHE);
+ (void) info->table->file->extra(HA_EXTRA_NO_CACHE);
if (info->read_record != rr_quick) // otherwise quick_range does it
- (void) info->file->ha_index_or_rnd_end();
+ (void) info->table->file->ha_index_or_rnd_end();
info->table=0;
}
}
@@ -361,7 +350,7 @@ static int rr_quick(READ_RECORD *info)
static int rr_index_first(READ_RECORD *info)
{
- int tmp= info->file->ha_index_first(info->record);
+ int tmp= info->table->file->ha_index_first(info->record);
info->read_record= rr_index;
if (tmp)
tmp= rr_handle_error(info, tmp);
@@ -387,7 +376,7 @@ static int rr_index_first(READ_RECORD *info)
static int rr_index(READ_RECORD *info)
{
- int tmp= info->file->ha_index_next(info->record);
+ int tmp= info->table->file->ha_index_next(info->record);
if (tmp)
tmp= rr_handle_error(info, tmp);
return tmp;
@@ -397,7 +386,7 @@ static int rr_index(READ_RECORD *info)
int rr_sequential(READ_RECORD *info)
{
int tmp;
- while ((tmp= info->file->ha_rnd_next(info->record)))
+ while ((tmp= info->table->file->ha_rnd_next(info->record)))
{
/*
rnd_next can return RECORD_DELETED for MyISAM when one thread is
@@ -422,7 +411,7 @@ static int rr_from_tempfile(READ_RECORD *info)
{
if (my_b_read(info->io_cache,info->ref_pos,info->ref_length))
return -1; /* End of file */
- if (!(tmp= info->file->ha_rnd_pos(info->record,info->ref_pos)))
+ if (!(tmp= info->table->file->ha_rnd_pos(info->record,info->ref_pos)))
break;
/* The following is extremely unlikely to happen */
if (tmp == HA_ERR_RECORD_DELETED ||
@@ -473,7 +462,7 @@ static int rr_from_pointers(READ_RECORD *info)
cache_pos= info->cache_pos;
info->cache_pos+= info->ref_length;
- if (!(tmp= info->file->ha_rnd_pos(info->record,cache_pos)))
+ if (!(tmp= info->table->file->ha_rnd_pos(info->record,cache_pos)))
break;
/* The following is extremely unlikely to happen */
@@ -606,7 +595,7 @@ static int rr_from_cache(READ_RECORD *info)
record=uint3korr(position);
position+=3;
record_pos=info->cache+record*info->reclength;
- if ((error=(int16) info->file->ha_rnd_pos(record_pos,info->ref_pos)))
+ if ((error=(int16) info->table->file->ha_rnd_pos(record_pos,info->ref_pos)))
{
record_pos[info->error_offset]=1;
shortstore(record_pos,error);
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index 0ea3c23bfd8..a143f5251af 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -425,14 +425,14 @@ public:
/**
Save pointer to Annotate_rows event and switch on the
- binlog_annotate_rows_events for this sql thread.
+ binlog_annotate_row_events for this sql thread.
To be called when sql thread recieves an Annotate_rows event.
*/
inline void set_annotate_event(Annotate_rows_log_event *event)
{
free_annotate_event();
m_annotate_event= event;
- sql_thd->variables.binlog_annotate_rows_events= 1;
+ sql_thd->variables.binlog_annotate_row_events= 1;
}
/**
@@ -446,7 +446,7 @@ public:
/**
Delete saved Annotate_rows event (if any) and switch off the
- binlog_annotate_rows_events for this sql thread.
+ binlog_annotate_row_events for this sql thread.
To be called when sql thread has applied the last (i.e. with
STMT_END_F flag) rbr event.
*/
@@ -454,7 +454,7 @@ public:
{
if (m_annotate_event)
{
- sql_thd->variables.binlog_annotate_rows_events= 0;
+ sql_thd->variables.binlog_annotate_row_events= 0;
delete m_annotate_event;
m_annotate_event= 0;
}
diff --git a/sql/scheduler.cc b/sql/scheduler.cc
index 5b8f834aecc..5b83bb4753e 100644
--- a/sql/scheduler.cc
+++ b/sql/scheduler.cc
@@ -376,7 +376,7 @@ void libevent_kill_thd_callback(int Fd, short, void*)
{
THD *thd= (THD*)list->data;
list= list_rest(list);
- if (thd->killed == THD::KILL_CONNECTION)
+ if ((int) thd->killed >= (int) KILL_CONNECTION)
{
/*
Delete from libevent and add to the processing queue.
@@ -510,7 +510,7 @@ static void libevent_connection_close(THD *thd)
DBUG_ENTER("libevent_connection_close");
DBUG_PRINT("enter", ("thd: %p", thd));
- thd->killed= THD::KILL_CONNECTION; // Avoid error messages
+ thd->killed= KILL_CONNECTION; // Avoid error messages
if (thd->net.vio->sd >= 0) // not already closed
{
@@ -531,9 +531,9 @@ static void libevent_connection_close(THD *thd)
static bool libevent_should_close_connection(THD* thd)
{
- return thd->net.error ||
- thd->net.vio == 0 ||
- thd->killed == THD::KILL_CONNECTION;
+ return (thd->net.error ||
+ thd->net.vio == 0 ||
+ (int) thd->killed >= (int) KILL_CONNECTION);
}
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 85722f3d64a..ed6bc60e3df 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -156,6 +156,7 @@ static bool sys_update_slow_log_path(THD *thd, set_var * var);
static void sys_default_slow_log_path(THD *thd, enum_var_type type);
static void fix_sys_log_slow_filter(THD *thd, enum_var_type);
static uchar *get_myisam_mmap_size(THD *thd);
+static uchar *in_transaction(THD *thd);
static int check_max_allowed_packet(THD *thd, set_var *var);
static int check_net_buffer_length(THD *thd, set_var *var);
@@ -188,8 +189,8 @@ static sys_var_const sys_back_log(&vars, "back_log",
(uchar*) &back_log);
static sys_var_const_os_str sys_basedir(&vars, "basedir", mysql_home);
static sys_var_thd_bool
-sys_binlog_annotate_rows_events(&vars, "binlog_annotate_rows_events",
- &SV::binlog_annotate_rows_events);
+sys_binlog_annotate_row_events(&vars, "binlog_annotate_row_events",
+ &SV::binlog_annotate_row_events);
static sys_var_long_ptr sys_binlog_cache_size(&vars, "binlog_cache_size",
&binlog_cache_size);
static sys_var_thd_binlog_format sys_binlog_format(&vars, "binlog_format",
@@ -264,6 +265,9 @@ static sys_var_thd_ulong sys_deadlock_timeout_long(&vars,
&SV::wt_timeout_long);
#ifndef DBUG_OFF
static sys_var_thd_dbug sys_dbug(&vars, "debug");
+static sys_var_long_ptr sys_var_debug_binlog_fsync_sleep(&vars,
+ "debug_binlog_fsync_sleep",
+ &opt_binlog_dbug_fsync_sleep);
#endif
static sys_var_enum sys_delay_key_write(&vars, "delay_key_write",
&delay_key_write_options,
@@ -527,6 +531,10 @@ static sys_var_thd_ulong sys_optimizer_search_depth(&vars, "optimizer_sea
static sys_var_thd_optimizer_switch sys_optimizer_switch(&vars, "optimizer_switch",
&SV::optimizer_switch);
+static sys_var_thd_ulong sys_progress_report_time(&vars,
+ "progress_report_time",
+ &SV::progress_report_time);
+
static sys_var_const sys_pid_file(&vars, "pid_file",
OPT_GLOBAL, SHOW_CHAR,
(uchar*) pidfile_name);
@@ -997,6 +1005,12 @@ static sys_var_enum_const sys_plugin_maturity(&vars, "plugin_maturity",
&plugin_maturity,
&plugin_maturity_values);
+static sys_var_readonly sys_in_transaction(&vars, "in_transaction",
+ OPT_SESSION, SHOW_BOOL,
+ in_transaction);
+
+
+
bool sys_var::check(THD *thd, set_var *var)
{
var->save_result.ulonglong_value= var->value->val_int();
@@ -3071,7 +3085,19 @@ void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type)
bool sys_var_max_user_conn::check(THD *thd, set_var *var)
{
if (var->type == OPT_GLOBAL)
+ {
+ if (! max_user_connections_checking)
+ {
+ /*
+ We can't change the value of max_user_connections from 0 as then
+ connect counting would be wrong.
+ */
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0),
+ "--max-user-connections=0");
+ return TRUE;
+ }
return sys_var_thd::check(thd, var);
+ }
else
{
/*
@@ -3087,7 +3113,7 @@ bool sys_var_max_user_conn::update(THD *thd, set_var *var)
{
DBUG_ASSERT(var->type == OPT_GLOBAL);
pthread_mutex_lock(&LOCK_global_system_variables);
- max_user_connections= (uint)var->save_result.ulonglong_value;
+ max_user_connections= (int) var->save_result.ulonglong_value;
pthread_mutex_unlock(&LOCK_global_system_variables);
return 0;
}
@@ -3269,35 +3295,26 @@ static bool set_option_log_bin_bit(THD *thd, set_var *var)
static bool set_option_autocommit(THD *thd, set_var *var)
{
- /* The test is negative as the flag we use is NOT autocommit */
-
- ulonglong org_options= thd->options;
+ ulonglong new_options= thd->options;
- if (var->save_result.ulong_value != 0)
- thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
+ /* The test is negative as the flag we use is NOT autocommit */
+ if (var->save_result.ulong_value)
+ new_options&= ~OPTION_NOT_AUTOCOMMIT;
else
- thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag;
+ new_options|= OPTION_NOT_AUTOCOMMIT;
- if ((org_options ^ thd->options) & OPTION_NOT_AUTOCOMMIT)
+ if ((new_options ^ thd->options) & OPTION_NOT_AUTOCOMMIT)
{
- if ((org_options & OPTION_NOT_AUTOCOMMIT))
+ if ((thd->options & OPTION_NOT_AUTOCOMMIT))
{
- /* We changed to auto_commit mode */
- if (thd->transaction.xid_state.xa_state != XA_NOTR)
- {
- thd->options= org_options;
- my_error(ER_XAER_RMFAIL, MYF(0),
- xa_state_names[thd->transaction.xid_state.xa_state]);
+ if (end_active_trans(thd))
return 1;
- }
- thd->options&= ~(ulonglong) (OPTION_BEGIN | OPTION_KEEP_LOG);
- thd->transaction.all.modified_non_trans_table= FALSE;
thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
- if (ha_commit(thd))
- return 1;
+ thd->options= new_options;
}
else
{
+ thd->options= new_options;
thd->transaction.all.modified_non_trans_table= FALSE;
thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
}
@@ -3399,6 +3416,12 @@ static uchar *get_myisam_mmap_size(THD *thd)
return (uchar *)&myisam_mmap_size;
}
+static uchar *in_transaction(THD *thd)
+{
+ thd->sys_var_tmp.my_bool_value=
+ test(thd->server_status & SERVER_STATUS_IN_TRANS);
+ return (uchar*) &thd->sys_var_tmp.my_bool_value;
+}
/****************************************************************************
Main handling of variables:
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index eb5d7ed935d..ac0c2653ee0 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -6290,3 +6290,11 @@ ER_QUERY_CACHE_IS_GLOBALY_DISABLED
eng "Query cache is globally disabled and you can't enable it only for this session"
ER_SPATIAL_MUST_HAVE_GEOM_COL 42000
eng "A SPATIAL index may only contain a geometrical type column"
+ER_VIEW_ORDERBY_IGNORED
+ eng "View '%-.192s'.'%-.192s' ORDER BY clause ignored because there is other ORDER BY clause already."
+ER_CONNECTION_KILLED 70100
+ eng "Connection was killed"
+ER_INTERNAL_ERROR
+ eng "Internal error: '%-.192s'"
+
+
diff --git a/sql/slave.cc b/sql/slave.cc
index cfa6c9fdc56..fa7fabb5d99 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -524,7 +524,7 @@ terminate_slave_thread(THD *thd,
IF_DBUG(int err= ) pthread_kill(thd->real_id, thr_client_alarm);
DBUG_ASSERT(err != EINVAL);
#endif
- thd->awake(THD::NOT_KILLED);
+ thd->awake(KILL_CONNECTION);
pthread_mutex_unlock(&thd->LOCK_thd_data);
/*
@@ -837,6 +837,8 @@ bool is_network_error(uint errorno)
errorno == CR_SERVER_GONE_ERROR ||
errorno == CR_SERVER_LOST ||
errorno == ER_CON_COUNT_ERROR ||
+ errorno == ER_CONNECTION_KILLED ||
+ errorno == ER_NEW_ABORTING_CONNECTION ||
errorno == ER_SERVER_SHUTDOWN)
return TRUE;
@@ -2012,7 +2014,7 @@ static int request_dump(MYSQL* mysql, Master_info* mi,
*suppress_warnings= FALSE;
- if (opt_log_slave_updates && opt_replicate_annotate_rows_events)
+ if (opt_log_slave_updates && opt_replicate_annotate_row_events)
binlog_flags|= BINLOG_SEND_ANNOTATE_ROWS_EVENT;
// TODO if big log files: Change next to int8store()
@@ -3076,11 +3078,11 @@ pthread_handler_t handle_slave_sql(void *arg)
thd->temporary_tables = rli->save_temporary_tables; // restore temp tables
set_thd_in_use_temporary_tables(rli); // (re)set sql_thd in use for saved temp tables
/*
- binlog_annotate_rows_events must be TRUE only after an Annotate_rows event
+ binlog_annotate_row_events must be TRUE only after an Annotate_rows event
has been recieved and only till the last corresponding rbr event has been
applied. In all other cases it must be FALSE.
*/
- thd->variables.binlog_annotate_rows_events= 0;
+ thd->variables.binlog_annotate_row_events= 0;
pthread_mutex_lock(&LOCK_thread_count);
threads.append(thd);
pthread_mutex_unlock(&LOCK_thread_count);
diff --git a/sql/slave.h b/sql/slave.h
index 3333e583559..bd4302ff3a1 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -106,7 +106,7 @@ extern MYSQL_PLUGIN_IMPORT char *relay_log_info_file;
extern char *opt_relay_logname, *opt_relaylog_index_name;
extern my_bool opt_skip_slave_start, opt_reckless_slave;
extern my_bool opt_log_slave_updates;
-extern my_bool opt_replicate_annotate_rows_events;
+extern my_bool opt_replicate_annotate_row_events;
extern ulonglong relay_log_space_limit;
/*
diff --git a/sql/sp.cc b/sql/sp.cc
index d2c732c2100..57dbc04be4e 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -14,8 +14,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysql_priv.h"
-#include "sp.h"
#include "sp_head.h"
+#include "sp.h"
#include "sp_cache.h"
#include "sql_trigger.h"
@@ -23,7 +23,7 @@
static bool
create_string(THD *thd, String *buf,
- int sp_type,
+ stored_procedure_type sp_type,
const char *db, ulong dblen,
const char *name, ulong namelen,
const char *params, ulong paramslen,
@@ -33,7 +33,8 @@ create_string(THD *thd, String *buf,
const LEX_STRING *definer_user,
const LEX_STRING *definer_host);
static int
-db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
+db_load_routine(THD *thd, stored_procedure_type type, sp_name *name,
+ sp_head **sphp,
ulong sql_mode, const char *params, const char *returns,
const char *body, st_sp_chistics &chistics,
const char *definer, longlong created, longlong modified,
@@ -490,7 +491,8 @@ static TABLE *open_proc_table_for_update(THD *thd)
*/
static int
-db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table)
+db_find_routine_aux(THD *thd, stored_procedure_type type, sp_name *name,
+ TABLE *table)
{
uchar key[MAX_KEY_LENGTH]; // db, name, optional key length type
DBUG_ENTER("db_find_routine_aux");
@@ -543,7 +545,8 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table)
*/
static int
-db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
+db_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
+ sp_head **sphp)
{
TABLE *table;
const char *params, *returns, *body;
@@ -711,7 +714,8 @@ Silence_deprecated_warning::handle_error(uint sql_errno, const char *message,
static int
-db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
+db_load_routine(THD *thd, stored_procedure_type type,
+ sp_name *name, sp_head **sphp,
ulong sql_mode, const char *params, const char *returns,
const char *body, st_sp_chistics &chistics,
const char *definer, longlong created, longlong modified,
@@ -890,7 +894,7 @@ sp_returns_type(THD *thd, String &result, sp_head *sp)
*/
int
-sp_create_routine(THD *thd, int type, sp_head *sp)
+sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
{
int ret;
TABLE *table;
@@ -906,7 +910,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
bool save_binlog_row_based;
DBUG_ENTER("sp_create_routine");
- DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length,
+ DBUG_PRINT("enter", ("type: %d name: %.*s", (int) type,
+ (int) sp->m_name.length,
sp->m_name.str));
String retstr(64);
retstr.set_charset(system_charset_info);
@@ -1151,7 +1156,7 @@ done:
*/
int
-sp_drop_routine(THD *thd, int type, sp_name *name)
+sp_drop_routine(THD *thd, stored_procedure_type type, sp_name *name)
{
TABLE *table;
int ret;
@@ -1211,14 +1216,16 @@ sp_drop_routine(THD *thd, int type, sp_name *name)
*/
int
-sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
+sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name,
+ st_sp_chistics *chistics)
{
TABLE *table;
int ret;
bool save_binlog_row_based;
DBUG_ENTER("sp_update_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",
- type, (int) name->m_name.length, name->m_name.str));
+ (int) type,
+ (int) name->m_name.length, name->m_name.str));
DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
type == TYPE_ENUM_FUNCTION);
@@ -1346,7 +1353,7 @@ err:
*/
bool
-sp_show_create_routine(THD *thd, int type, sp_name *name)
+sp_show_create_routine(THD *thd, stored_procedure_type type, sp_name *name)
{
bool err_status= TRUE;
sp_head *sp;
@@ -1404,8 +1411,8 @@ sp_show_create_routine(THD *thd, int type, sp_name *name)
*/
sp_head *
-sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
- bool cache_only)
+sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
+ sp_cache **cp, bool cache_only)
{
sp_head *sp;
ulong depth= (type == TYPE_ENUM_PROCEDURE ?
@@ -1562,7 +1569,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any)
*/
int
-sp_routine_exists_in_table(THD *thd, int type, sp_name *name)
+sp_routine_exists_in_table(THD *thd, stored_procedure_type type, sp_name *name)
{
TABLE *table;
int ret;
@@ -1729,7 +1736,7 @@ static bool add_used_routine(LEX *lex, Query_arena *arena,
*/
void sp_add_used_routine(LEX *lex, Query_arena *arena,
- sp_name *rt, char rt_type)
+ sp_name *rt, enum stored_procedure_type rt_type)
{
rt->set_routine_type(rt_type);
(void)add_used_routine(lex, arena, &rt->m_sroutines_key, 0);
@@ -1885,9 +1892,11 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
for (Sroutine_hash_entry *rt= start; rt; rt= rt->next)
{
sp_name name(thd, rt->key.str, rt->key.length);
- int type= rt->key.str[0];
+ stored_procedure_type type= (stored_procedure_type) rt->key.str[0];
sp_head *sp;
+ if (type == TYPE_ENUM_TRIGGER)
+ continue;
if (!(sp= sp_cache_lookup((type == TYPE_ENUM_FUNCTION ?
&thd->sp_func_cache : &thd->sp_proc_cache),
&name)))
@@ -2076,7 +2085,7 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
*/
static bool
create_string(THD *thd, String *buf,
- int type,
+ stored_procedure_type type,
const char *db, ulong dblen,
const char *name, ulong namelen,
const char *params, ulong paramslen,
diff --git a/sql/sp.h b/sql/sp.h
index 876287d9704..4e3252392f7 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -39,26 +39,28 @@ int
sp_drop_db_routines(THD *thd, char *db);
sp_head *
-sp_find_routine(THD *thd, int type, sp_name *name,
+sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
sp_cache **cp, bool cache_only);
bool
sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any);
int
-sp_routine_exists_in_table(THD *thd, int type, sp_name *name);
+sp_routine_exists_in_table(THD *thd, stored_procedure_type type,
+ sp_name *name);
bool
-sp_show_create_routine(THD *thd, int type, sp_name *name);
+sp_show_create_routine(THD *thd, stored_procedure_type type, sp_name *name);
int
-sp_create_routine(THD *thd, int type, sp_head *sp);
+sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp);
int
-sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics);
+sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name,
+ st_sp_chistics *chistics);
int
-sp_drop_routine(THD *thd, int type, sp_name *name);
+sp_drop_routine(THD *thd, stored_procedure_type type, sp_name *name);
/*
Procedures for pre-caching of stored routines and building table list
@@ -67,7 +69,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name);
void sp_get_prelocking_info(THD *thd, bool *need_prelocking,
bool *first_no_prelocking);
void sp_add_used_routine(LEX *lex, Query_arena *arena,
- sp_name *rt, char rt_type);
+ sp_name *rt, stored_procedure_type rt_type);
void sp_remove_not_own_routines(LEX *lex);
bool sp_update_sp_used_routines(HASH *dst, HASH *src);
int sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index bd2dcfd8653..fda922f91ae 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -374,8 +374,8 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
thd->abort_on_warning=
- thd->variables.sql_mode &
- (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES);
+ test(thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
thd->transaction.stmt.modified_non_trans_table= FALSE;
/* Save the value in the field. Convert the value if needed. */
@@ -1312,7 +1312,7 @@ sp_head::execute(THD *thd)
ctx->enter_handler(hip);
thd->clear_error();
thd->is_fatal_error= 0;
- thd->killed= THD::NOT_KILLED;
+ thd->killed= NOT_KILLED;
thd->mysys_var->abort= 0;
continue;
}
@@ -1362,7 +1362,7 @@ sp_head::execute(THD *thd)
If the DB has changed, the pointer has changed too, but the
original thd->db will then have been freed
*/
- if (cur_db_changed && thd->killed != THD::KILL_CONNECTION)
+ if (cur_db_changed && thd->killed < KILL_CONNECTION)
{
/*
Force switching back to the saved current database, because it may be
@@ -1796,7 +1796,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
thd->options= binlog_save_options;
if (thd->binlog_evt_union.unioned_events)
{
- int errcode = query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode = query_error_code(thd, thd->killed == NOT_KILLED);
Query_log_event qinfo(thd, binlog_buf.ptr(), binlog_buf.length(),
thd->binlog_evt_union.unioned_events_trans, FALSE, errcode);
if (mysql_bin_log.write(&qinfo) &&
diff --git a/sql/sp_head.h b/sql/sp_head.h
index d422adc8927..dc237163716 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -28,11 +28,16 @@
@ingroup Runtime_Environment
@{
*/
-// Values for the type enum. This reflects the order of the enum declaration
-// in the CREATE TABLE command.
-#define TYPE_ENUM_FUNCTION 1
-#define TYPE_ENUM_PROCEDURE 2
-#define TYPE_ENUM_TRIGGER 3
+/*
+ Values for the type enum. This reflects the order of the enum declaration
+ in the CREATE TABLE command.
+*/
+enum stored_procedure_type
+{
+ TYPE_ENUM_FUNCTION=1,
+ TYPE_ENUM_PROCEDURE=2,
+ TYPE_ENUM_TRIGGER=3
+};
Item_result
sp_map_result_type(enum enum_field_types type);
@@ -134,9 +139,9 @@ public:
// Init. the qualified name from the db and name.
void init_qname(THD *thd); // thd for memroot allocation
- void set_routine_type(char type)
+ void set_routine_type(stored_procedure_type type)
{
- m_sroutines_key.str[0]= type;
+ m_sroutines_key.str[0]= (char) type;
}
~sp_name()
@@ -170,8 +175,7 @@ public:
HAS_SQLCOM_FLUSH= 4096
};
- /** TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */
- int m_type;
+ stored_procedure_type m_type;
uint m_flags; // Boolean attributes of a stored routine
Create_field m_return_field_def; /**< This is used for FUNCTIONs only. */
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index b133e1e4d68..ae286878cea 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -2089,7 +2089,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
table->field[next_field+2]->store((longlong) mqh.conn_per_hour, TRUE);
if (table->s->fields >= 36 &&
(mqh.specified_limits & USER_RESOURCES::USER_CONNECTIONS))
- table->field[next_field+3]->store((longlong) mqh.user_conn, TRUE);
+ table->field[next_field+3]->store((longlong) mqh.user_conn, FALSE);
mqh_used= mqh_used || mqh.questions || mqh.updates || mqh.conn_per_hour;
next_field+=4;
@@ -4578,7 +4578,8 @@ ulong get_column_grant(THD *thd, GRANT_INFO *grant,
/* Help function for mysql_show_grants */
-static void add_user_option(String *grant, ulong value, const char *name)
+static void add_user_option(String *grant, long value, const char *name,
+ my_bool is_signed)
{
if (value)
{
@@ -4586,7 +4587,7 @@ static void add_user_option(String *grant, ulong value, const char *name)
grant->append(' ');
grant->append(name, strlen(name));
grant->append(' ');
- p=int10_to_str(value, buff, 10);
+ p=int10_to_str(value, buff, is_signed ? -10 : 10);
grant->append(buff,p-buff);
}
}
@@ -4768,13 +4769,13 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (want_access & GRANT_ACL)
global.append(STRING_WITH_LEN(" GRANT OPTION"));
add_user_option(&global, acl_user->user_resource.questions,
- "MAX_QUERIES_PER_HOUR");
+ "MAX_QUERIES_PER_HOUR", 0);
add_user_option(&global, acl_user->user_resource.updates,
- "MAX_UPDATES_PER_HOUR");
+ "MAX_UPDATES_PER_HOUR", 0);
add_user_option(&global, acl_user->user_resource.conn_per_hour,
- "MAX_CONNECTIONS_PER_HOUR");
+ "MAX_CONNECTIONS_PER_HOUR", 0);
add_user_option(&global, acl_user->user_resource.user_conn,
- "MAX_USER_CONNECTIONS");
+ "MAX_USER_CONNECTIONS", 1);
}
protocol->prepare_for_resend();
protocol->store(global.ptr(),global.length(),global.charset());
@@ -6978,7 +6979,6 @@ bool check_routine_level_acl(THD *thd, const char *db, const char *name,
#undef HAVE_OPENSSL
#ifdef NO_EMBEDDED_ACCESS_CHECKS
#define initialized 0
-#define decrease_user_connections(X) /* nothing */
#define check_for_max_user_connections(X,Y) 0
#define get_or_create_user_conn(A,B,C,D) 0
#endif
@@ -7478,7 +7478,6 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
THD *thd= mpvio->thd;
NET *net= &thd->net;
char *end;
-
DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
if (pkt_len < MIN_HANDSHAKE_SIZE)
@@ -7490,7 +7489,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
ulong client_capabilities= uint2korr(net->read_pos);
if (client_capabilities & CLIENT_PROTOCOL_41)
{
- client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
+ client_capabilities|= ((ulonglong) uint2korr(net->read_pos+2)) << 16;
thd->max_client_packet_length= uint4korr(net->read_pos+4);
DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
if (thd_init_client_charset(thd, (uint) net->read_pos[8]))
@@ -7566,21 +7565,15 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
(uchar)(*passwd++) : strlen(passwd);
- if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
- {
- db= db + passwd_len + 1;
- /* strlen() can't be easily deleted without changing protocol */
- db_len= strlen(db);
- }
- else
- {
- db= 0;
- db_len= 0;
- }
+ db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
+ db + passwd_len + 1 : 0;
- if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
+ if (passwd + passwd_len + test(db) > (char *)net->read_pos + pkt_len)
return packet_error;
+ /* strlen() can't be easily deleted without changing protocol */
+ db_len= db ? strlen(db) : 0;
+
char *client_plugin= passwd + passwd_len + (db ? db_len + 1 : 0);
/* Since 4.1 all database names are stored in utf8 */
@@ -7647,8 +7640,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
if (thd->client_capabilities & CLIENT_PLUGIN_AUTH)
{
- if ((client_plugin + strlen(client_plugin)) >
- (char *)net->read_pos + pkt_len)
+ if (client_plugin >= (char *)net->read_pos + pkt_len)
return packet_error;
client_plugin= fix_plugin_ptr(client_plugin);
}
@@ -8156,10 +8148,16 @@ bool acl_authenticate(THD *thd, uint connect_errors,
DBUG_RETURN(1);
}
- /* Don't allow the user to connect if he has done too many queries */
- if ((acl_user->user_resource.questions || acl_user->user_resource.updates ||
+ /*
+ Don't allow the user to connect if he has done too many queries.
+ As we are testing max_user_connections == 0 here, it means that we
+ can't let the user change max_user_connections from 0 in the server
+ without a restart as it would lead to wrong connect counting.
+ */
+ if ((acl_user->user_resource.questions ||
+ acl_user->user_resource.updates ||
acl_user->user_resource.conn_per_hour ||
- acl_user->user_resource.user_conn || max_user_connections) &&
+ acl_user->user_resource.user_conn || max_user_connections_checking) &&
get_or_create_user_conn(thd,
(opt_old_style_user_limits ? sctx->user : sctx->priv_user),
(opt_old_style_user_limits ? sctx->host_or_ip : sctx->priv_host),
@@ -8172,9 +8170,11 @@ bool acl_authenticate(THD *thd, uint connect_errors,
if (thd->user_connect &&
(thd->user_connect->user_resources.conn_per_hour ||
thd->user_connect->user_resources.user_conn ||
- max_user_connections) &&
+ max_user_connections_checking) &&
check_for_max_user_connections(thd, thd->user_connect))
{
+ /* Ensure we don't decrement thd->user_connections->connections twice */
+ thd->user_connect= 0;
status_var_increment(denied_connections);
DBUG_RETURN(1); // The error is set in check_for_max_user_connections()
}
@@ -8215,12 +8215,7 @@ bool acl_authenticate(THD *thd, uint connect_errors,
if (mysql_change_db(thd, &mpvio.db, FALSE))
{
/* mysql_change_db() has pushed the error message. */
- if (thd->user_connect)
- {
- status_var_increment(thd->status_var.access_denied_errors);
- decrease_user_connections(thd->user_connect);
- thd->user_connect= 0;
- }
+ status_var_increment(thd->status_var.access_denied_errors);
DBUG_RETURN(1);
}
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index c42551100ae..3e27355cc26 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -62,7 +62,7 @@ private:
bool
Prelock_error_handler::handle_error(uint sql_errno,
const char * /* message */,
- MYSQL_ERROR::enum_warning_level /* level */,
+ MYSQL_ERROR::enum_warning_level level,
THD * /* thd */)
{
if (sql_errno == ER_NO_SUCH_TABLE)
@@ -71,7 +71,8 @@ Prelock_error_handler::handle_error(uint sql_errno,
return TRUE;
}
- m_unhandled_errors++;
+ if (level == MYSQL_ERROR::WARN_LEVEL_ERROR)
+ m_unhandled_errors++;
return FALSE;
}
@@ -675,7 +676,7 @@ void close_handle_and_leave_table_as_lock(TABLE *table)
*/
if (table->child_l || table->parent)
detach_merge_children(table, FALSE);
- table->file->close();
+ table->file->ha_close();
table->db_stat= 0; // Mark file closed
release_table_share(table->s, RELEASE_NORMAL);
table->s= share;
@@ -3708,7 +3709,7 @@ TABLE *drop_locked_tables(THD *thd,const char *db, const char *table_name)
if (table->db_stat)
{
table->db_stat= 0;
- table->file->close();
+ table->file->ha_close();
}
}
else
@@ -5861,10 +5862,15 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list,
*/
if (*ref && !(*ref)->is_autogenerated_name)
{
+ if (register_tree_change &&
+ thd->stmt_arena->is_stmt_prepare_or_first_stmt_execute())
+ arena= thd->activate_stmt_arena_if_needed(&backup);
item->set_name((*ref)->name, (*ref)->name_length,
system_charset_info);
item->real_item()->set_name((*ref)->name, (*ref)->name_length,
system_charset_info);
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
}
if (register_tree_change)
thd->change_item_tree(ref, item);
@@ -6441,19 +6447,28 @@ find_field_in_tables(THD *thd, Item_ident *item,
{
SELECT_LEX *current_sel= thd->lex->current_select;
SELECT_LEX *last_select= table_ref->select_lex;
+ bool all_merged= TRUE;
+ for (SELECT_LEX *sl= current_sel; sl && sl!=last_select;
+ sl=sl->outer_select())
+ {
+ Item *subs= sl->master_unit()->item;
+ if (subs->type() == Item::SUBSELECT_ITEM &&
+ ((Item_subselect*)subs)->substype() == Item_subselect::IN_SUBS &&
+ ((Item_in_subselect*)subs)->test_strategy(SUBS_SEMI_JOIN))
+ {
+ continue;
+ }
+ all_merged= FALSE;
+ break;
+ }
/*
If the field was an outer referencee, mark all selects using this
sub query as dependent on the outer query
*/
- if (current_sel != last_select)
+ if (!all_merged && current_sel != last_select)
{
mark_select_range_as_dependent(thd, last_select, current_sel,
found, *ref, item);
- if (item->can_be_depended)
- {
- DBUG_ASSERT((*ref) == (Item*)item);
- current_sel->register_dependency_item(last_select, ref);
- }
}
}
return found;
@@ -7789,9 +7804,18 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
if (select_lex->first_cond_optimization)
{
leaves.empty();
- select_lex->leaf_tables_exec.empty();
- make_leaves_list(leaves, tables, full_table_list, first_select_table);
-
+ if (!select_lex->is_prep_leaf_list_saved)
+ {
+ make_leaves_list(leaves, tables, full_table_list, first_select_table);
+ select_lex->leaf_tables_exec.empty();
+ }
+ else
+ {
+ List_iterator_fast <TABLE_LIST> ti(select_lex->leaf_tables_prep);
+ while ((table_list= ti++))
+ leaves.push_back(table_list);
+ }
+
while ((table_list= ti++))
{
TABLE *table= table_list->table;
@@ -7830,9 +7854,17 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
select_lex->leaf_tables.empty();
while ((table_list= ti++))
{
- table_list->table->tablenr= table_list->tablenr_exec;
- table_list->table->map= table_list->map_exec;
- table_list->table->pos_in_table_list= table_list;
+ if(table_list->jtbm_subselect)
+ {
+ table_list->jtbm_table_no= table_list->tablenr_exec;
+ }
+ else
+ {
+ table_list->table->tablenr= table_list->tablenr_exec;
+ table_list->table->map= table_list->map_exec;
+ table_list->table->maybe_null= table_list->maybe_null_exec;
+ table_list->table->pos_in_table_list= table_list;
+ }
select_lex->leaf_tables.push_back(table_list);
}
}
@@ -8259,7 +8291,6 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
SELECT_LEX *select_lex= thd->lex->current_select;
Query_arena *arena= thd->stmt_arena, backup;
TABLE_LIST *table= NULL; // For HP compilers
- TABLE_LIST *save_emb_on_expr_nest= thd->thd_marker.emb_on_expr_nest;
List_iterator<TABLE_LIST> ti(leaves);
/*
it_is_update set to TRUE when tables of primary SELECT_LEX (SELECT_LEX
@@ -8300,7 +8331,6 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
goto err_no_arena;
}
- thd->thd_marker.emb_on_expr_nest= NO_JOIN_NEST;
if (*conds)
{
thd->where="where clause";
@@ -8314,11 +8344,11 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
*/
if ((*conds)->type() == Item::FIELD_ITEM && !derived)
wrap_ident(thd, conds);
+ (*conds)->mark_as_condition_AND_part(NO_JOIN_NEST);
if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) ||
(*conds)->check_cols(1))
goto err_no_arena;
}
- thd->thd_marker.emb_on_expr_nest= save_emb_on_expr_nest;
/*
Apply fix_fields() to all ON clauses at all levels of nesting,
@@ -8334,8 +8364,8 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
if (embedded->on_expr)
{
/* Make a join an a expression */
- thd->thd_marker.emb_on_expr_nest= embedded;
thd->where="on clause";
+ embedded->on_expr->mark_as_condition_AND_part(embedded);
if ((!embedded->on_expr->fixed &&
embedded->on_expr->fix_fields(thd, &embedded->on_expr)) ||
embedded->on_expr->check_cols(1))
@@ -8359,7 +8389,6 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
}
}
}
- thd->thd_marker.emb_on_expr_nest= save_emb_on_expr_nest;
if (!thd->stmt_arena->is_conventional())
{
@@ -8881,7 +8910,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name,
{
if (!in_use->killed)
{
- in_use->killed= THD::KILL_CONNECTION;
+ in_use->killed= KILL_SYSTEM_THREAD;
pthread_mutex_lock(&in_use->mysys_var->mutex);
if (in_use->mysys_var->current_cond)
{
@@ -9215,7 +9244,7 @@ void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table
if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
! in_use->killed)
{
- in_use->killed= THD::KILL_CONNECTION;
+ in_use->killed= KILL_SYSTEM_THREAD;
pthread_mutex_lock(&in_use->mysys_var->mutex);
if (in_use->mysys_var->current_cond)
{
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index d7040a825fb..8631a13eae7 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -391,7 +391,7 @@ static void debug_wait_for_kill(const char *info)
sql_print_information("%s", info);
while(!thd->killed)
my_sleep(1000);
- thd->killed= THD::NOT_KILLED;
+ thd->killed= NOT_KILLED;
/*
Remove the set debug variable, to ensure we don't get stuck on it again
This is needed as for MyISAM, invalidate_table() may be called twice
@@ -491,11 +491,12 @@ static void make_base_query(String *new_query,
continue; // Continue with next symbol
case '/': // Start of comment ?
/*
- Comment of format /#!number #/, must be skipped.
+ Comment of format /#!number #/ or /#M!number #/, must be skipped.
These may include '"' and other comments, but it should
be safe to parse the content as a normal string.
*/
- if (query[0] != '*' || query[1] == '!')
+ if (query[0] != '*' || query[1] == '!' ||
+ (query[1] == 'M' && query[2] == '!'))
break;
query++; // skip "/"
@@ -4438,7 +4439,7 @@ void Query_cache::wreck(uint line, const char *message)
DBUG_PRINT("warning", ("%5d QUERY CACHE WRECK => DISABLED",line));
DBUG_PRINT("warning", ("=================================="));
if (thd)
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_CONNECTION;
cache_dump();
/* check_integrity(0); */ /* Can't call it here because of locks */
bins_dump();
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 97a33b4fe1a..39edcdca3de 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -664,7 +664,7 @@ THD::THD()
Open_tables_state(refresh_version), rli_fake(0),
lock_id(&main_lock_id),
in_sub_stmt(0),
- sql_log_bin_toplevel(false),
+ sql_log_bin_toplevel(false), log_all_errors(0),
binlog_table_maps(0), binlog_flags(0UL),
table_map_for_update(0),
arg_of_last_insert_id_function(FALSE),
@@ -725,6 +725,8 @@ THD::THD()
user_time.val= start_time= start_time_sec_part= 0;
start_utime= prior_thr_create_utime= 0L;
utime_after_lock= 0L;
+ progress.report_to_client= 0;
+ progress.max_counter= 0;
current_linfo = 0;
slave_thread = 0;
bzero(&variables, sizeof(variables));
@@ -814,6 +816,8 @@ THD::THD()
memset(&invoker_user, 0, sizeof(invoker_user));
memset(&invoker_host, 0, sizeof(invoker_host));
prepare_derived_at_open= FALSE;
+ create_tmp_table_for_derived= FALSE;
+ save_prep_leaf_list= FALSE;
}
@@ -990,6 +994,11 @@ void THD::update_all_stats()
ulonglong end_cpu_time, end_utime;
double busy_time, cpu_time;
+ /* Reset status variables used by information_schema.processlist */
+ progress.max_counter= 0;
+ progress.max_stage= 0;
+ progress.report= 0;
+
/* This is set at start of query if opt_userstat_running was set */
if (!userstat_running)
return;
@@ -1086,6 +1095,11 @@ void THD::cleanup(void)
lock=locked_tables; locked_tables=0;
close_thread_tables(this);
}
+ if (user_connect)
+ {
+ decrease_user_connections(user_connect);
+ user_connect= 0; // Safety
+ }
wt_thd_destroy(&transaction.wt);
#if defined(ENABLED_DEBUG_SYNC)
@@ -1200,6 +1214,7 @@ void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var)
to_var->bytes_sent+= from_var->bytes_sent;
to_var->rows_read+= from_var->rows_read;
to_var->rows_sent+= from_var->rows_sent;
+ to_var->rows_tmp_read+= from_var->rows_tmp_read;
to_var->binlog_bytes_written+= from_var->binlog_bytes_written;
to_var->cpu_time+= from_var->cpu_time;
to_var->busy_time+= from_var->busy_time;
@@ -1235,6 +1250,7 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
to_var->bytes_sent+= from_var->bytes_sent - dec_var->bytes_sent;
to_var->rows_read+= from_var->rows_read - dec_var->rows_read;
to_var->rows_sent+= from_var->rows_sent - dec_var->rows_sent;
+ to_var->rows_tmp_read+= from_var->rows_tmp_read - dec_var->rows_tmp_read;
to_var->binlog_bytes_written+= from_var->binlog_bytes_written -
dec_var->binlog_bytes_written;
to_var->cpu_time+= from_var->cpu_time - dec_var->cpu_time;
@@ -1250,15 +1266,24 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
#endif
-void THD::awake(THD::killed_state state_to_set)
+void THD::awake(killed_state state_to_set)
{
DBUG_ENTER("THD::awake");
DBUG_PRINT("enter", ("this: 0x%lx", (long) this));
THD_CHECK_SENTRY(this);
safe_mutex_assert_owner(&LOCK_thd_data);
+ if (global_system_variables.log_warnings > 3)
+ {
+ Security_context *sctx= security_ctx;
+ sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
+ thread_id,(db ? db : "unconnected"),
+ sctx->user ? sctx->user : "unauthenticated",
+ sctx->host_or_ip,
+ "KILLED");
+ }
killed= state_to_set;
- if (state_to_set != THD::KILL_QUERY)
+ if (state_to_set >= KILL_CONNECTION)
{
thr_alarm_kill(thread_id);
if (!slave_thread)
@@ -1338,6 +1363,38 @@ void THD::awake(THD::killed_state state_to_set)
DBUG_VOID_RETURN;
}
+
+/*
+ Get error number for killed state
+ Note that the error message can't have any parameters.
+ See thd::kill_message()
+*/
+
+int killed_errno(killed_state killed)
+{
+ switch (killed) {
+ case NOT_KILLED:
+ case KILL_HARD_BIT:
+ return 0; // Probably wrong usage
+ case KILL_BAD_DATA:
+ case KILL_BAD_DATA_HARD:
+ return 0; // Not a real error
+ case KILL_CONNECTION:
+ case KILL_CONNECTION_HARD:
+ case KILL_SYSTEM_THREAD:
+ case KILL_SYSTEM_THREAD_HARD:
+ return ER_CONNECTION_KILLED;
+ case KILL_QUERY:
+ case KILL_QUERY_HARD:
+ return ER_QUERY_INTERRUPTED;
+ case KILL_SERVER:
+ case KILL_SERVER_HARD:
+ return ER_SERVER_SHUTDOWN;
+ }
+ return 0; // Keep compiler happy
+}
+
+
/*
Remember the location of thread info, the structure needed for
sql_alloc() and the structure for the net buffer
@@ -2583,26 +2640,32 @@ bool select_max_min_finder_subselect::cmp_real()
{
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
double val1= cache->val_real(), val2= maxmin->val_real();
+
+ /* Ignore NULLs for ANY and keep them for ALL subqueries */
+ if (cache->null_value)
+ return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value);
+ if (maxmin->null_value)
+ return !is_all;
+
if (fmax)
- return (cache->null_value && !maxmin->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- val1 > val2);
- return (maxmin->null_value && !cache->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- val1 < val2);
+ return(val1 > val2);
+ return (val1 < val2);
}
bool select_max_min_finder_subselect::cmp_int()
{
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
longlong val1= cache->val_int(), val2= maxmin->val_int();
+
+ /* Ignore NULLs for ANY and keep them for ALL subqueries */
+ if (cache->null_value)
+ return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value);
+ if (maxmin->null_value)
+ return !is_all;
+
if (fmax)
- return (cache->null_value && !maxmin->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- val1 > val2);
- return (maxmin->null_value && !cache->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- val1 < val2);
+ return(val1 > val2);
+ return (val1 < val2);
}
bool select_max_min_finder_subselect::cmp_decimal()
@@ -2610,13 +2673,16 @@ bool select_max_min_finder_subselect::cmp_decimal()
Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0);
my_decimal cval, *cvalue= cache->val_decimal(&cval);
my_decimal mval, *mvalue= maxmin->val_decimal(&mval);
+
+ /* Ignore NULLs for ANY and keep them for ALL subqueries */
+ if (cache->null_value)
+ return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value);
+ if (maxmin->null_value)
+ return !is_all;
+
if (fmax)
- return (cache->null_value && !maxmin->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- my_decimal_cmp(cvalue, mvalue) > 0) ;
- return (maxmin->null_value && !cache->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- my_decimal_cmp(cvalue,mvalue) < 0);
+ return (my_decimal_cmp(cvalue, mvalue) > 0) ;
+ return (my_decimal_cmp(cvalue,mvalue) < 0);
}
bool select_max_min_finder_subselect::cmp_str()
@@ -2629,13 +2695,16 @@ bool select_max_min_finder_subselect::cmp_str()
*/
val1= cache->val_str(&buf1);
val2= maxmin->val_str(&buf1);
+
+ /* Ignore NULLs for ANY and keep them for ALL subqueries */
+ if (cache->null_value)
+ return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value);
+ if (maxmin->null_value)
+ return !is_all;
+
if (fmax)
- return (cache->null_value && !maxmin->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- sortcmp(val1, val2, cache->collation.collation) > 0) ;
- return (maxmin->null_value && !cache->null_value) ||
- (!cache->null_value && !maxmin->null_value &&
- sortcmp(val1, val2, cache->collation.collation) < 0);
+ return (sortcmp(val1, val2, cache->collation.collation) > 0) ;
+ return (sortcmp(val1, val2, cache->collation.collation) < 0);
}
int select_exists_subselect::send_data(List<Item> &items)
@@ -3360,12 +3429,128 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
@param thd user thread
@retval 0 the user thread is active
@retval 1 the user thread has been killed
+
+ This is used to signal a storage engine if it should be killed.
*/
+
extern "C" int thd_killed(const MYSQL_THD thd)
{
- return(thd->killed);
+ if (!(thd->killed & KILL_HARD_BIT))
+ return 0;
+ return thd->killed;
+}
+
+
+/**
+ Send an out-of-band progress report to the client
+
+ The report is sent every 'thd->...progress_report_time' second,
+ however not more often than global.progress_report_time.
+ If global.progress_report_time is 0, then don't send progress reports, but
+ check every second if the value has changed
+*/
+
+static void thd_send_progress(THD *thd)
+{
+ /* Check if we should send the client a progress report */
+ ulonglong report_time= my_interval_timer();
+ if (report_time > thd->progress.next_report_time)
+ {
+ uint seconds_to_next= max(thd->variables.progress_report_time,
+ global_system_variables.progress_report_time);
+ if (seconds_to_next == 0) // Turned off
+ seconds_to_next= 1; // Check again after 1 second
+
+ thd->progress.next_report_time= (report_time +
+ seconds_to_next * 1000000000ULL);
+ if (global_system_variables.progress_report_time &&
+ thd->variables.progress_report_time)
+ net_send_progress_packet(thd);
+ }
}
+
+/** Initialize progress report handling **/
+
+extern "C" void thd_progress_init(MYSQL_THD thd, uint max_stage)
+{
+ /*
+ Send progress reports to clients that supports it, if the command
+ is a high level command (like ALTER TABLE) and we are not in a
+ stored procedure
+ */
+ thd->progress.report= ((thd->client_capabilities & CLIENT_PROGRESS) &&
+ thd->progress.report_to_client &&
+ !thd->in_sub_stmt);
+ thd->progress.next_report_time= 0;
+ thd->progress.stage= 0;
+ thd->progress.counter= thd->progress.max_counter= 0;
+ thd->progress.max_stage= max_stage;
+}
+
+
+/* Inform processlist and the client that some progress has been made */
+
+extern "C" void thd_progress_report(MYSQL_THD thd,
+ ulonglong progress, ulonglong max_progress)
+{
+ if (thd->progress.max_counter != max_progress) // Simple optimization
+ {
+ pthread_mutex_lock(&thd->LOCK_thd_data);
+ thd->progress.counter= progress;
+ thd->progress.max_counter= max_progress;
+ pthread_mutex_unlock(&thd->LOCK_thd_data);
+ }
+ else
+ thd->progress.counter= progress;
+
+ if (thd->progress.report)
+ thd_send_progress(thd);
+}
+
+/**
+ Move to next stage in process list handling
+
+ This will reset the timer to ensure the progress is sent to the client
+ if client progress reports are activated.
+*/
+
+extern "C" void thd_progress_next_stage(MYSQL_THD thd)
+{
+ pthread_mutex_lock(&thd->LOCK_thd_data);
+ thd->progress.stage++;
+ thd->progress.counter= 0;
+ DBUG_ASSERT(thd->progress.stage < thd->progress.max_stage);
+ pthread_mutex_unlock(&thd->LOCK_thd_data);
+ if (thd->progress.report)
+ {
+ thd->progress.next_report_time= 0; // Send new stage info
+ thd_send_progress(thd);
+ }
+}
+
+/**
+ Disable reporting of progress in process list.
+
+ @note
+ This function is safe to call even if one has not called thd_progress_init.
+
+ This function should be called by all parts that does progress
+ reporting to ensure that progress list doesn't contain 100 % done
+ forever.
+*/
+
+
+extern "C" void thd_progress_end(MYSQL_THD thd)
+{
+ /*
+ It's enough to reset max_counter to set disable progress indicator
+ in processlist.
+ */
+ thd->progress.max_counter= 0;
+}
+
+
/**
Return the thread id of a user thread
@param thd user thread
diff --git a/sql/sql_class.h b/sql/sql_class.h
index fe9288c0e52..0085e982abb 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -74,6 +74,22 @@ public:
/**
+ Item iterator over List_iterator_fast for Items
+*/
+
+class Item_iterator_list: public Item_iterator
+{
+ List_iterator<Item> list;
+public:
+ Item_iterator_list(List_iterator<Item> &arg_list):
+ list(arg_list) {}
+ void open() { list.rewind(); }
+ Item *next() { return (list++); }
+ void close() {}
+};
+
+
+/**
Item iterator over Item interface for rows
*/
@@ -346,6 +362,38 @@ public:
LEX_COLUMN (const String& x,const uint& y ): column (x),rights (y) {}
};
+
+/* Note: these states are actually bit coded with HARD */
+enum killed_state
+{
+ NOT_KILLED= 0,
+ KILL_HARD_BIT= 1, /* Bit for HARD KILL */
+ KILL_BAD_DATA= 2,
+ KILL_BAD_DATA_HARD= 3,
+ KILL_QUERY= 4,
+ KILL_QUERY_HARD= 5,
+ /*
+ All of the following killed states will kill the connection
+ KILL_CONNECTION must be the first of these!
+ */
+ KILL_CONNECTION= 6,
+ KILL_CONNECTION_HARD= 7,
+ KILL_SYSTEM_THREAD= 8,
+ KILL_SYSTEM_THREAD_HARD= 9,
+ KILL_SERVER= 10,
+ KILL_SERVER_HARD= 11
+};
+
+extern int killed_errno(killed_state killed);
+#define killed_mask_hard(killed) ((killed_state) ((killed) & ~KILL_HARD_BIT))
+
+enum killed_type
+{
+ KILL_TYPE_ID,
+ KILL_TYPE_USER
+};
+
+
#include "sql_lex.h" /* Must be here */
class Delayed_insert;
@@ -443,7 +491,8 @@ struct system_variables
ulong ndb_index_stat_cache_entries;
ulong ndb_index_stat_update_freq;
ulong binlog_format; // binlog format for this thd (see enum_binlog_format)
- my_bool binlog_annotate_rows_events;
+ ulong progress_report_time;
+ my_bool binlog_annotate_row_events;
my_bool binlog_direct_non_trans_update;
/*
In slave thread we need to know in behalf of which
@@ -530,6 +579,9 @@ typedef struct system_status_var
ulong ha_rollback_count;
ulong ha_update_count;
ulong ha_write_count;
+ /* The following are for internal temporary tables */
+ ulong ha_tmp_update_count;
+ ulong ha_tmp_write_count;
ulong ha_prepare_count;
ulong ha_discover_count;
ulong ha_savepoint_count;
@@ -582,6 +634,7 @@ typedef struct system_status_var
ulonglong bytes_sent;
ulonglong rows_read;
ulonglong rows_sent;
+ ulonglong rows_tmp_read;
ulonglong binlog_bytes_written;
double last_query_cost;
double cpu_time, busy_time;
@@ -1547,6 +1600,25 @@ public:
ulonglong prior_thr_create_utime, thr_create_utime;
ulonglong start_utime, utime_after_lock;
+ // Process indicator
+ struct {
+ /*
+ true, if the currently running command can send progress report
+ packets to a client. Set by mysql_execute_command() for safe commands
+ See CF_REPORT_PROGRESS
+ */
+ bool report_to_client;
+ /*
+ true, if we will send progress report packets to a client
+ (client has requested them, see CLIENT_PROGRESS; report_to_client
+ is true; not in sub-statement)
+ */
+ bool report;
+ uint stage, max_stage;
+ ulonglong counter, max_counter;
+ ulonglong next_report_time;
+ } progress;
+
thr_lock_type update_lock_default;
Delayed_insert *di;
@@ -1556,21 +1628,22 @@ public:
bool sql_log_bin_toplevel;
/* True when opt_userstat_running is set at start of query */
bool userstat_running;
+ /* True if we want to log all errors */
+ bool log_all_errors;
/* container for handler's private per-connection data */
Ha_data ha_data[MAX_HA];
- /* Place to store various things */
- union
- {
- /*
- Used by subquery optimizations, see Item_in_subselect::emb_on_expr_nest.
- */
- TABLE_LIST *emb_on_expr_nest;
- } thd_marker;
-
bool prepare_derived_at_open;
+ /*
+ To signal that the tmp table to be created is created for materialized
+ derived table or a view.
+ */
+ bool create_tmp_table_for_derived;
+
+ bool save_prep_leaf_list;
+
#ifndef MYSQL_CLIENT
int binlog_setup_trx_data();
@@ -1932,14 +2005,6 @@ public:
DYNAMIC_ARRAY user_var_events; /* For user variables replication */
MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
- enum killed_state
- {
- NOT_KILLED=0,
- KILL_BAD_DATA=1,
- KILL_CONNECTION=ER_SERVER_SHUTDOWN,
- KILL_QUERY=ER_QUERY_INTERRUPTED,
- KILLED_NO_VALUE /* means neither of the states */
- };
killed_state volatile killed;
/* scramble - random string sent to client on handshake */
@@ -2122,7 +2187,7 @@ public:
}
void close_active_vio();
#endif
- void awake(THD::killed_state state_to_set);
+ void awake(killed_state state_to_set);
#ifndef MYSQL_CLIENT
enum enum_binlog_query_type {
@@ -2356,18 +2421,13 @@ public:
void end_statement();
inline int killed_errno() const
{
- killed_state killed_val; /* to cache the volatile 'killed' */
- return (killed_val= killed) != KILL_BAD_DATA ? killed_val : 0;
+ return ::killed_errno(killed);
}
inline void send_kill_message() const
{
int err= killed_errno();
if (err)
- {
- if ((err == KILL_CONNECTION) && !shutdown_in_progress)
- err = KILL_QUERY;
my_message(err, ER(err), MYF(0));
- }
}
/* return TRUE if we will abort query if we make a warning now */
inline bool really_abort_on_warning()
@@ -3179,9 +3239,11 @@ class select_max_min_finder_subselect :public select_subselect
Item_cache *cache;
bool (select_max_min_finder_subselect::*op)();
bool fmax;
+ bool is_all;
public:
- select_max_min_finder_subselect(Item_subselect *item_arg, bool mx)
- :select_subselect(item_arg), cache(0), fmax(mx)
+ select_max_min_finder_subselect(Item_subselect *item_arg, bool mx,
+ bool all)
+ :select_subselect(item_arg), cache(0), fmax(mx), is_all(all)
{}
void cleanup();
int send_data(List<Item> &items);
@@ -3546,6 +3608,7 @@ public:
#define CF_STATUS_COMMAND 4
#define CF_SHOW_TABLE_COMMAND 8
#define CF_WRITE_LOGS_COMMAND 16
+
/**
Must be set for SQL statements that may contain
Item expressions and/or use joins and tables.
@@ -3560,6 +3623,7 @@ public:
joins are currently prohibited in these statements.
*/
#define CF_REEXECUTION_FRAGILE 32
+#define CF_REPORT_PROGRESS 64
/* Functions in sql_class.cc */
@@ -3595,16 +3659,24 @@ inline int handler::ha_index_read_map(uchar * buf, const uchar * key,
return error;
}
+
+/*
+ @note: Other index lookup/navigation functions require prior
+ handler->index_init() call. This function is different, it requires
+ that the scan is not initialized, and accepts "uint index" as an argument.
+*/
+
inline int handler::ha_index_read_idx_map(uchar * buf, uint index,
const uchar * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
+ DBUG_ASSERT(inited==NONE);
increment_statistics(&SSV::ha_read_key_count);
int error= index_read_idx_map(buf, index, key, keypart_map, find_flag);
if (!error)
{
- rows_read++;
+ update_rows_read();
index_rows_read[index]++;
}
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -3671,7 +3743,8 @@ inline int handler::ha_ft_read(uchar *buf)
{
int error= ft_read(buf);
if (!error)
- rows_read++;
+ update_rows_read();
+
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
@@ -3681,7 +3754,7 @@ inline int handler::ha_rnd_next(uchar *buf)
increment_statistics(&SSV::ha_read_rnd_next_count);
int error= rnd_next(buf);
if (!error)
- rows_read++;
+ update_rows_read();
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
@@ -3691,7 +3764,7 @@ inline int handler::ha_rnd_pos(uchar *buf, uchar *pos)
increment_statistics(&SSV::ha_read_rnd_count);
int error= rnd_pos(buf, pos);
if (!error)
- rows_read++;
+ update_rows_read();
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
@@ -3700,7 +3773,7 @@ inline int handler::ha_rnd_pos_by_record(uchar *buf)
{
int error= rnd_pos_by_record(buf);
if (!error)
- rows_read++;
+ update_rows_read();
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
@@ -3709,15 +3782,21 @@ inline int handler::ha_read_first_row(uchar *buf, uint primary_key)
{
int error= read_first_row(buf, primary_key);
if (!error)
- rows_read++;
+ update_rows_read();
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
inline int handler::ha_write_tmp_row(uchar *buf)
{
- increment_statistics(&SSV::ha_write_count);
+ increment_statistics(&SSV::ha_tmp_write_count);
return write_row(buf);
}
+inline int handler::ha_update_tmp_row(const uchar *old_data, uchar *new_data)
+{
+ increment_statistics(&SSV::ha_tmp_update_count);
+ return update_row(old_data, new_data);
+}
+
#endif /* MYSQL_SERVER */
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 05e33826da9..cd51fd25558 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -49,6 +49,7 @@ int get_or_create_user_conn(THD *thd, const char *user,
DBUG_ASSERT(user != 0);
DBUG_ASSERT(host != 0);
+ DBUG_ASSERT(thd->user_connect == 0);
user_len= strlen(user);
temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1;
@@ -108,15 +109,17 @@ end:
int check_for_max_user_connections(THD *thd, USER_CONN *uc)
{
- int error=0;
+ int error= 1;
DBUG_ENTER("check_for_max_user_connections");
(void) pthread_mutex_lock(&LOCK_user_conn);
+
+ /* Root is not affected by the value of max_user_connections */
if (max_user_connections && !uc->user_resources.user_conn &&
- max_user_connections < (uint) uc->connections)
+ max_user_connections < uc->connections &&
+ !(thd->security_ctx->master_access & SUPER_ACL))
{
my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user);
- error=1;
goto end;
}
time_out_user_resource_limits(thd, uc);
@@ -126,7 +129,6 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc)
my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user,
"max_user_connections",
(long) uc->user_resources.user_conn);
- error= 1;
goto end;
}
if (uc->user_resources.conn_per_hour &&
@@ -135,10 +137,10 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc)
my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user,
"max_connections_per_hour",
(long) uc->user_resources.conn_per_hour);
- error=1;
goto end;
}
uc->conn_per_hour++;
+ error= 0;
end:
if (error)
@@ -203,7 +205,7 @@ void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
/* If more than a hour since last check, reset resource checking */
if (check_time - uc->reset_utime >= LL(3600000000))
{
- uc->questions=1;
+ uc->questions=0;
uc->updates=0;
uc->conn_per_hour=0;
uc->reset_utime= check_time;
@@ -232,7 +234,7 @@ bool check_mqh(THD *thd, uint check_command)
if (uc->user_resources.questions &&
uc->questions++ >= uc->user_resources.questions)
{
- my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_questions",
+ my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_queries_per_hour",
(long) uc->user_resources.questions);
error=1;
goto end;
@@ -244,7 +246,7 @@ bool check_mqh(THD *thd, uint check_command)
(sql_command_flags[check_command] & CF_CHANGES_DATA) &&
uc->updates++ >= uc->user_resources.updates)
{
- my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_updates",
+ my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_updates_per_hour",
(long) uc->user_resources.updates);
error=1;
goto end;
@@ -690,6 +692,7 @@ static void update_global_user_stats_with_user(THD *thd,
user_stats->binlog_bytes_written+=
(thd->status_var.binlog_bytes_written -
thd->org_status_var.binlog_bytes_written);
+ /* We are not counting rows in internal temporary tables here ! */
user_stats->rows_read+= (thd->status_var.rows_read -
thd->org_status_var.rows_read);
user_stats->rows_sent+= (thd->status_var.rows_sent -
@@ -1027,8 +1030,17 @@ void end_connection(THD *thd)
{
NET *net= &thd->net;
plugin_thdvar_cleanup(thd);
+
if (thd->user_connect)
+ {
+ /*
+ We decrease this variable early to make it easy to log again quickly.
+ This code is not critical as we will in any case do this test
+ again in thd->cleanup()
+ */
decrease_user_connections(thd->user_connect);
+ thd->user_connect= 0;
+ }
if (thd->killed || (net->error && net->vio != 0))
{
@@ -1086,7 +1098,7 @@ void prepare_new_connection_state(THD* thd)
execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
if (thd->is_error())
{
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_CONNECTION;
sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
thd->thread_id,(thd->db ? thd->db : "unconnected"),
sctx->user ? sctx->user : "unauthenticated",
@@ -1122,6 +1134,8 @@ pthread_handler_t handle_one_connection(void *arg)
THD *thd= (THD*) arg;
thd->thr_create_utime= microsecond_interval_timer();
+ /* We need to set this because of time_out_user_resource_limits */
+ thd->start_utime= thd->thr_create_utime;
if (thread_scheduler.init_new_connection_thread())
{
@@ -1172,7 +1186,7 @@ pthread_handler_t handle_one_connection(void *arg)
prepare_new_connection_state(thd);
while (!net->error && net->vio != 0 &&
- !(thd->killed == THD::KILL_CONNECTION))
+ thd->killed < KILL_CONNECTION)
{
if (do_command(thd))
break;
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index c788d324743..d5579827d1e 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -18,6 +18,7 @@
#include "mysql_priv.h"
#include <mysys_err.h>
+#include "sp_head.h"
#include "sp.h"
#include "events.h"
#include "sql_handler.h"
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 6ace7ba8086..98d034a4d5c 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -49,7 +49,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
bool triggers_applicable;
uint usable_index= MAX_KEY;
SELECT_LEX *select_lex= &thd->lex->select_lex;
- THD::killed_state killed_status= THD::NOT_KILLED;
+ killed_state killed_status= NOT_KILLED;
DBUG_ENTER("mysql_delete");
bool save_binlog_row_based;
@@ -61,8 +61,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (open_and_lock_tables(thd, table_list))
DBUG_RETURN(TRUE);
- if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) ||
- mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
+ if (mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT))
+ DBUG_RETURN(TRUE);
+ if (mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
DBUG_RETURN(TRUE);
if (!table_list->updatable)
@@ -382,7 +383,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
table->file->unlock_row(); // Row failed selection, release lock on it
}
killed_status= thd->killed;
- if (killed_status != THD::NOT_KILLED || thd->is_error())
+ if (killed_status != NOT_KILLED || thd->is_error())
error= 1; // Aborted
if (will_batch && (loc_error= table->file->end_bulk_delete()))
{
@@ -449,7 +450,7 @@ cleanup:
if (error < 0)
thd->clear_error();
else
- errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ errcode= query_error_code(thd, killed_status == NOT_KILLED);
/*
[binlog]: If 'handler::delete_all_rows()' was called and the
@@ -550,7 +551,7 @@ int mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds)
fix_inner_refs(thd, all_fields, select_lex, select_lex->ref_pointer_array))
DBUG_RETURN(TRUE);
- select_lex->fix_prepare_information(thd, conds, &fake_conds);
+ select_lex->fix_prepare_information(thd, conds, &fake_conds);
DBUG_RETURN(FALSE);
}
@@ -586,10 +587,11 @@ int mysql_multi_delete_prepare(THD *thd)
TABLE_LIST *target_tbl;
DBUG_ENTER("mysql_multi_delete_prepare");
- TABLE_LIST *tables= lex->query_tables;
- if (mysql_handle_derived(lex, DT_INIT) ||
- mysql_handle_list_of_derived(lex, tables, DT_MERGE_FOR_INSERT) ||
- mysql_handle_list_of_derived(lex, tables, DT_PREPARE))
+ if (mysql_handle_derived(lex, DT_INIT))
+ DBUG_RETURN(TRUE);
+ if (mysql_handle_derived(lex, DT_MERGE_FOR_INSERT))
+ DBUG_RETURN(TRUE);
+ if (mysql_handle_derived(lex, DT_PREPARE))
DBUG_RETURN(TRUE);
/*
setup_tables() need for VIEWs. JOIN::prepare() will not do it second
@@ -601,9 +603,11 @@ int mysql_multi_delete_prepare(THD *thd)
&thd->lex->select_lex.top_join_list,
lex->query_tables,
lex->select_lex.leaf_tables, FALSE,
- DELETE_ACL, SELECT_ACL, TRUE))
+ DELETE_ACL, SELECT_ACL, FALSE))
DBUG_RETURN(TRUE);
+ if (lex->select_lex.handle_derived(thd->lex, DT_MERGE))
+ DBUG_RETURN(TRUE);
/*
Multi-delete can't be constructed over-union => we always have
@@ -616,7 +620,8 @@ int mysql_multi_delete_prepare(THD *thd)
target_tbl= target_tbl->next_local)
{
- if (!(target_tbl->table= target_tbl->correspondent_table->table))
+ target_tbl->table= target_tbl->correspondent_table->table;
+ if (target_tbl->correspondent_table->is_multitable())
{
my_error(ER_VIEW_DELETE_MERGE_VIEW, MYF(0),
target_tbl->correspondent_table->view_db.str,
@@ -651,6 +656,10 @@ int mysql_multi_delete_prepare(THD *thd)
with further calls to unique_table
*/
lex->select_lex.exclude_from_table_unique_test= FALSE;
+
+ if (lex->select_lex.save_prep_leaf_tables(thd))
+ DBUG_RETURN(TRUE);
+
DBUG_RETURN(FALSE);
}
@@ -907,7 +916,7 @@ void multi_delete::abort()
*/
if (mysql_bin_log.is_open())
{
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
/* possible error of writing binary log is ignored deliberately */
(void) thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
@@ -1057,7 +1066,7 @@ int multi_delete::do_table_deletes(TABLE *table, bool ignore)
bool multi_delete::send_eof()
{
- THD::killed_state killed_status= THD::NOT_KILLED;
+ killed_state killed_status= NOT_KILLED;
thd_proc_info(thd, "deleting from reference tables");
/* Does deletes for the last n - 1 tables, returns 0 if ok */
@@ -1065,7 +1074,7 @@ bool multi_delete::send_eof()
/* compute a total error to know if something failed */
local_error= local_error || error;
- killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
+ killed_status= (local_error == 0)? NOT_KILLED : thd->killed;
/* reset used flags */
thd_proc_info(thd, "end");
@@ -1085,7 +1094,7 @@ bool multi_delete::send_eof()
if (local_error == 0)
thd->clear_error();
else
- errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ errcode= query_error_code(thd, killed_status == NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode) &&
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 9bfa49c5f2d..e012c161945 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -85,15 +85,18 @@ mysql_handle_derived(LEX *lex, uint phases)
cursor && !res;
cursor= cursor->next_local)
{
+ if (!cursor->is_view_or_derived() && phases == DT_MERGE_FOR_INSERT)
+ continue;
uint8 allowed_phases= (cursor->is_merged_derived() ? DT_PHASES_MERGE :
- DT_PHASES_MATERIALIZE);
+ DT_PHASES_MATERIALIZE | DT_MERGE_FOR_INSERT);
/*
Skip derived tables to which the phase isn't applicable.
TODO: mark derived at the parse time, later set it's type
(merged or materialized)
*/
if ((phase_flag != DT_PREPARE && !(allowed_phases & phase_flag)) ||
- (cursor->merged_for_insert && phase_flag != DT_REINIT))
+ (cursor->merged_for_insert && phase_flag != DT_REINIT &&
+ phase_flag != DT_PREPARE))
continue;
res= (*processors[phase])(lex->thd, lex, cursor);
}
@@ -343,43 +346,52 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
if (derived->merged)
return FALSE;
+ if (thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
+ thd->lex->sql_command == SQLCOM_DELETE_MULTI)
+ thd->save_prep_leaf_list= TRUE;
+
arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
derived->merged= TRUE;
- /*
- Check whether there is enough free bits in table map to merge subquery.
- If not - materialize it. This check isn't cached so when there is a big
- and small subqueries, and the bigger one can't be merged it wouldn't
- block the smaller one.
- */
- if (parent_lex->get_free_table_map(&map, &tablenr))
- {
- /* There is no enough table bits, fall back to materialization. */
- derived->change_refs_to_fields();
- derived->set_materialized_derived();
- goto exit_merge;
- }
- if (dt_select->leaf_tables.elements + tablenr > MAX_TABLES)
+ if (!derived->merged_for_insert ||
+ (derived->is_multitable() &&
+ (thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
+ thd->lex->sql_command == SQLCOM_DELETE_MULTI)))
{
- /* There is no enough table bits, fall back to materialization. */
- derived->change_refs_to_fields();
- derived->set_materialized_derived();
- goto exit_merge;
- }
+ /*
+ Check whether there is enough free bits in table map to merge subquery.
+ If not - materialize it. This check isn't cached so when there is a big
+ and small subqueries, and the bigger one can't be merged it wouldn't
+ block the smaller one.
+ */
+ if (parent_lex->get_free_table_map(&map, &tablenr))
+ {
+ /* There is no enough table bits, fall back to materialization. */
+ derived->change_refs_to_fields();
+ derived->set_materialized_derived();
+ goto exit_merge;
+ }
+
+ if (dt_select->leaf_tables.elements + tablenr > MAX_TABLES)
+ {
+ /* There is no enough table bits, fall back to materialization. */
+ derived->change_refs_to_fields();
+ derived->set_materialized_derived();
+ goto exit_merge;
+ }
- if (dt_select->options & OPTION_SCHEMA_TABLE)
- parent_lex->options |= OPTION_SCHEMA_TABLE;
+ if (dt_select->options & OPTION_SCHEMA_TABLE)
+ parent_lex->options |= OPTION_SCHEMA_TABLE;
- parent_lex->cond_count+= dt_select->cond_count;
+ parent_lex->cond_count+= dt_select->cond_count;
- if (!derived->get_unit()->prepared)
- {
- dt_select->leaf_tables.empty();
- make_leaves_list(dt_select->leaf_tables, derived, TRUE, 0);
- }
+ if (!derived->get_unit()->prepared)
+ {
+ dt_select->leaf_tables.empty();
+ make_leaves_list(dt_select->leaf_tables, derived, TRUE, 0);
+ }
- if (!derived->merged_for_insert)
- { derived->nested_join= (NESTED_JOIN*) thd->calloc(sizeof(NESTED_JOIN));
+ derived->nested_join= (NESTED_JOIN*) thd->calloc(sizeof(NESTED_JOIN));
if (!derived->nested_join)
{
res= TRUE;
@@ -387,7 +399,7 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
}
/* Merge derived table's subquery in the parent select. */
- if (parent_lex->merge_subquery(derived, dt_select, tablenr, map))
+ if (parent_lex->merge_subquery(thd, derived, dt_select, tablenr, map))
{
res= TRUE;
goto exit_merge;
@@ -463,52 +475,21 @@ exit_merge:
bool mysql_derived_merge_for_insert(THD *thd, LEX *lex, TABLE_LIST *derived)
{
- SELECT_LEX *dt_select= derived->get_single_select();
-
if (derived->merged_for_insert)
return FALSE;
- /* It's a target view for an INSERT, create field translation only. */
- if (!derived->updatable || derived->is_materialized_derived())
- {
- bool res= derived->create_field_translation(thd);
- return res;
- }
+ if (derived->is_materialized_derived())
+ return mysql_derived_prepare(thd, lex, derived);
if (!derived->is_multitable())
{
- TABLE_LIST *tl=((TABLE_LIST*)dt_select->table_list.first);
- TABLE *table= tl->table;
- /* preserve old map & tablenr. */
- if (!derived->merged_for_insert && derived->table)
- table->set_table_map(derived->table->map, derived->table->tablenr);
-
- derived->table= table;
- derived->schema_table=
- ((TABLE_LIST*)dt_select->table_list.first)->schema_table;
- if (!derived->merged)
+ if (!derived->updatable)
+ return derived->create_field_translation(thd);
+ if (derived->merge_underlying_list)
{
- Query_arena *arena, backup;
- arena= thd->activate_stmt_arena_if_needed(&backup); // For easier test
- derived->select_lex->leaf_tables.push_back(tl);
- derived->nested_join= (NESTED_JOIN*) thd->calloc(sizeof(NESTED_JOIN));
- if (derived->nested_join)
- {
- derived->wrap_into_nested_join(tl->select_lex->top_join_list);
- derived->get_unit()->exclude_level();
- }
- if (arena)
- thd->restore_active_arena(arena, &backup);
- derived->merged= TRUE;
- if (!derived->nested_join)
- return TRUE;
- }
- }
- else
- {
- if (!derived->merged_for_insert && mysql_derived_merge(thd, lex, derived))
- return TRUE;
- }
- derived->merged_for_insert= TRUE;
-
+ derived->table= derived->merge_underlying_list->table;
+ derived->schema_table= derived->merge_underlying_list->schema_table;
+ derived->merged_for_insert= TRUE;
+ }
+ }
return FALSE;
}
@@ -609,7 +590,11 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
bool res= FALSE;
// Skip already prepared views/DT
- if (!unit || unit->prepared || derived->merged_for_insert)
+ if (!unit || unit->prepared ||
+ (derived->merged_for_insert &&
+ !(derived->is_multitable() &&
+ (thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
+ thd->lex->sql_command == SQLCOM_DELETE_MULTI))))
DBUG_RETURN(FALSE);
Query_arena *arena= thd->stmt_arena, backup;
@@ -659,13 +644,18 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
!unit->union_distinct->next_select() (i.e. it is union and last distinct
SELECT is last SELECT of UNION).
*/
+ thd->create_tmp_table_for_derived= TRUE;
if (derived->derived_result->create_result_table(thd, &unit->types, FALSE,
(first_select->options |
thd->options |
TMP_TABLE_ALL_COLUMNS),
derived->alias,
FALSE, FALSE))
+ {
+ thd->create_tmp_table_for_derived= FALSE;
goto exit;
+ }
+ thd->create_tmp_table_for_derived= FALSE;
derived->table= derived->derived_result->table;
if (derived->is_derived() && derived->is_merged_derived())
@@ -747,7 +737,7 @@ bool mysql_derived_optimize(THD *thd, LEX *lex, TABLE_LIST *derived)
bool res= FALSE;
- if (unit->optimized && !unit->uncacheable && !unit->describe)
+ if (unit->optimized)
return FALSE;
lex->current_select= first_select;
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 835e60cd6ba..1db4a110d01 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -131,7 +131,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
thd->no_warnings_for_error= 1;
thd->spcont= NULL;
- thd->killed= THD::KILL_BAD_DATA;
+ thd->killed= KILL_BAD_DATA;
my_message(code, msg, MYF(0));
thd->spcont= spcont;
diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc
index c3450884610..4174f72f080 100644
--- a/sql/sql_expression_cache.cc
+++ b/sql/sql_expression_cache.cc
@@ -16,6 +16,22 @@
#include "mysql_priv.h"
#include "sql_select.h"
+/**
+ Minimum hit ration to proceed on disk if in memory table overflowed.
+ hit_rate = hit / (miss + hit);
+*/
+#define EXPCACHE_MIN_HIT_RATE_FOR_DISK_TABLE 0.7
+/**
+ Minimum hit ratio to keep in memory table (do not switch cache off)
+ hit_rate = hit / (miss + hit);
+*/
+#define EXPCACHE_MIN_HIT_RATE_FOR_MEM_TABLE 0.2
+/**
+ Number of cache miss to check hit ratio (maximum cache performance
+ impact in the case when the cache is not applicable)
+*/
+#define EXPCACHE_CHECK_HIT_RATIO_AFTER 200
+
/*
Expression cache is used only for caching subqueries now, so its statistic
variables we call subquery_cache*.
@@ -23,10 +39,10 @@
ulong subquery_cache_miss, subquery_cache_hit;
Expression_cache_tmptable::Expression_cache_tmptable(THD *thd,
- List<Item*> &dependants,
- Item *value)
- :cache_table(NULL), table_thd(thd), list(&dependants), val(value),
- inited (0)
+ List<Item> &dependants,
+ Item *value)
+ :cache_table(NULL), table_thd(thd), items(dependants), val(value),
+ hit(0), miss(0), inited (0)
{
DBUG_ENTER("Expression_cache_tmptable::Expression_cache_tmptable");
DBUG_VOID_RETURN;
@@ -34,6 +50,17 @@ Expression_cache_tmptable::Expression_cache_tmptable(THD *thd,
/**
+ Disable cache
+*/
+
+void Expression_cache_tmptable::disable_cache()
+{
+ free_tmp_table(table_thd, cache_table);
+ cache_table= NULL;
+}
+
+
+/**
Field enumerator for TABLE::add_tmp_key
@param arg reference variable with current field number
@@ -60,50 +87,32 @@ static uint field_enumerator(uchar *arg)
void Expression_cache_tmptable::init()
{
- List_iterator<Item*> li(*list);
- Item_iterator_ref_list it(li);
- Item **item;
+ List_iterator<Item> li(items);
+ Item_iterator_list it(li);
uint field_counter;
DBUG_ENTER("Expression_cache_tmptable::init");
DBUG_ASSERT(!inited);
inited= TRUE;
cache_table= NULL;
- while ((item= li++))
- {
- DBUG_ASSERT(item);
- if (*item)
- {
- DBUG_ASSERT((*item)->fixed);
- items.push_back((*item));
- }
- else
- {
- /*
- This is possible when optimizer already executed this subquery and
- optimized out the condition predicate.
- */
- li.remove();
- }
- }
-
- if (list->elements == 0)
+ if (items.elements == 0)
{
DBUG_PRINT("info", ("All parameters were removed by optimizer."));
DBUG_VOID_RETURN;
}
+ /* add result field */
+ items.push_front(val);
+
cache_table_param.init();
/* dependent items and result */
- cache_table_param.field_count= list->elements + 1;
+ cache_table_param.field_count= items.elements;
/* postpone table creation to index description */
cache_table_param.skip_create_table= 1;
- items.push_front(val);
-
if (!(cache_table= create_tmp_table(table_thd, &cache_table_param,
items, (ORDER*) NULL,
- FALSE, FALSE,
+ FALSE, TRUE,
((table_thd->options |
TMP_TABLE_ALL_COLUMNS) &
~(OPTION_BIG_TABLES |
@@ -122,16 +131,13 @@ void Expression_cache_tmptable::init()
goto error;
}
- /* This list do not contain result field */
- it.open();
-
- field_counter=1;
+ field_counter= 1;
if (cache_table->alloc_keys(1) ||
cache_table->add_tmp_key(0, items.elements - 1, &field_enumerator,
(uchar*)&field_counter, TRUE) ||
ref.tmp_table_index_lookup_init(table_thd, cache_table->key_info, it,
- TRUE))
+ TRUE, 1 /* skip result field*/))
{
DBUG_PRINT("error", ("creating index failed"));
goto error;
@@ -158,17 +164,19 @@ void Expression_cache_tmptable::init()
DBUG_VOID_RETURN;
error:
- /* switch off cache */
- free_tmp_table(table_thd, cache_table);
- cache_table= NULL;
+ disable_cache();
DBUG_VOID_RETURN;
}
Expression_cache_tmptable::~Expression_cache_tmptable()
{
+ /* Add accumulated statistics */
+ statistic_add(subquery_cache_miss, miss, &LOCK_status);
+ statistic_add(subquery_cache_hit, hit, &LOCK_status);
+
if (cache_table)
- free_tmp_table(table_thd, cache_table);
+ disable_cache();
}
@@ -192,26 +200,28 @@ Expression_cache::result Expression_cache_tmptable::check_value(Item **value)
int res;
DBUG_ENTER("Expression_cache_tmptable::check_value");
- /*
- We defer cache initialization to get item references that are
- used at the execution phase.
- */
- if (!inited)
- init();
-
if (cache_table)
{
DBUG_PRINT("info", ("status: %u has_record %u",
(uint)cache_table->status, (uint)ref.has_record));
if ((res= join_read_key2(table_thd, NULL, cache_table, &ref)) == 1)
DBUG_RETURN(ERROR);
+
if (res)
{
- subquery_cache_miss++;
+ if (((++miss) == EXPCACHE_CHECK_HIT_RATIO_AFTER) &&
+ ((double)hit / ((double)hit + miss)) <
+ EXPCACHE_MIN_HIT_RATE_FOR_MEM_TABLE)
+ {
+ DBUG_PRINT("info",
+ ("Early check: hit rate is not so good to keep the cache"));
+ disable_cache();
+ }
+
DBUG_RETURN(MISS);
}
- subquery_cache_hit++;
+ hit++;
*value= cached_result;
DBUG_RETURN(Expression_cache::HIT);
}
@@ -249,15 +259,37 @@ my_bool Expression_cache_tmptable::put_value(Item *value)
if (table_thd->is_error())
goto err;;
- if ((error= cache_table->file->ha_write_row(cache_table->record[0])))
+ if ((error= cache_table->file->ha_write_tmp_row(cache_table->record[0])))
{
/* create_myisam_from_heap will generate error if needed */
- if (cache_table->file->is_fatal_error(error, HA_CHECK_DUP) &&
- create_internal_tmp_table_from_heap(table_thd, cache_table,
- cache_table_param.start_recinfo,
- &cache_table_param.recinfo,
- error, 1))
+ if (cache_table->file->is_fatal_error(error, HA_CHECK_DUP))
goto err;
+ else
+ {
+ double hit_rate= ((double)hit / ((double)hit + miss));
+ DBUG_ASSERT(miss > 0);
+ if (hit_rate < EXPCACHE_MIN_HIT_RATE_FOR_MEM_TABLE)
+ {
+ DBUG_PRINT("info", ("hit rate is not so good to keep the cache"));
+ disable_cache();
+ DBUG_RETURN(FALSE);
+ }
+ else if (hit_rate < EXPCACHE_MIN_HIT_RATE_FOR_DISK_TABLE)
+ {
+ DBUG_PRINT("info", ("hit rate is not so good to go to disk"));
+ if (cache_table->file->ha_delete_all_rows() ||
+ cache_table->file->ha_write_tmp_row(cache_table->record[0]))
+ goto err;
+ }
+ else
+ {
+ if (create_internal_tmp_table_from_heap(table_thd, cache_table,
+ cache_table_param.start_recinfo,
+ &cache_table_param.recinfo,
+ error, 1))
+ goto err;
+ }
+ }
}
cache_table->status= 0; /* cache_table->record contains an existed record */
ref.has_record= TRUE; /* the same as above */
@@ -266,24 +298,24 @@ my_bool Expression_cache_tmptable::put_value(Item *value)
DBUG_RETURN(FALSE);
err:
- free_tmp_table(table_thd, cache_table);
- cache_table= NULL;
+ disable_cache();
DBUG_RETURN(TRUE);
}
void Expression_cache_tmptable::print(String *str, enum_query_type query_type)
{
- List_iterator<Item*> li(*list);
- Item **item;
+ List_iterator<Item> li(items);
+ Item *item;
bool is_first= TRUE;
str->append('<');
+ li++; // skip result field
while ((item= li++))
{
if (!is_first)
str->append(',');
- (*item)->print(str, query_type);
+ item->print(str, query_type);
is_first= FALSE;
}
str->append('>');
diff --git a/sql/sql_expression_cache.h b/sql/sql_expression_cache.h
index 88f71e0cf32..32aecc61dc9 100644
--- a/sql/sql_expression_cache.h
+++ b/sql/sql_expression_cache.h
@@ -37,6 +37,15 @@ public:
Print cache parameters
*/
virtual void print(String *str, enum_query_type query_type)= 0;
+
+ /**
+ Is this cache initialized
+ */
+ virtual bool is_inited()= 0;
+ /**
+ Initialize this cache
+ */
+ virtual void init()= 0;
};
struct st_table_ref;
@@ -51,15 +60,17 @@ class Item_field;
class Expression_cache_tmptable :public Expression_cache
{
public:
- Expression_cache_tmptable(THD *thd, List<Item*> &dependants, Item *value);
+ Expression_cache_tmptable(THD *thd, List<Item> &dependants, Item *value);
virtual ~Expression_cache_tmptable();
virtual result check_value(Item **value);
virtual my_bool put_value(Item *value);
void print(String *str, enum_query_type query_type);
+ bool is_inited() { return inited; };
+ void init();
private:
- void init();
+ void disable_cache();
/* tmp table parameters */
TMP_TABLE_PARAM cache_table_param;
@@ -71,12 +82,12 @@ private:
struct st_table_ref ref;
/* Cached result */
Item_field *cached_result;
- /* List of references to the parameters of the expression */
- List<Item*> *list;
- /* List of items */
- List<Item> items;
+ /* List of parameter items */
+ List<Item> &items;
/* Value Item example */
Item *val;
+ /* hit/miss counters */
+ uint hit, miss;
/* Set on if the object has been succesfully initialized with init() */
bool inited;
};
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 72514d72dc1..cf199c27518 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -135,7 +135,7 @@ bool check_view_single_update(List<Item> &fields, List<Item> *values,
A buffer for the insert values was allocated for the merged view.
Use it.
*/
- //tbl->table->insert_values= view->table->insert_values;
+ tbl->table->insert_values= view->table->insert_values;
view->table= tbl->table;
*map= tables;
@@ -943,7 +943,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
thd->clear_error();
}
else
- errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ errcode= query_error_code(thd, thd->killed == NOT_KILLED);
/* bug#22725:
@@ -957,7 +957,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
routines did not result in any error due to the KILLED. In
such case the flag is ignored for constructing binlog event.
*/
- DBUG_ASSERT(thd->killed != THD::KILL_BAD_DATA || error > 0);
+ DBUG_ASSERT(thd->killed != KILL_BAD_DATA || error > 0);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
transactional_table, FALSE,
@@ -2010,7 +2010,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
/*
Annotating delayed inserts is not supported.
*/
- di->thd.variables.binlog_annotate_rows_events= 0;
+ di->thd.variables.binlog_annotate_row_events= 0;
di->thd.set_db(table_list->db, (uint) strlen(table_list->db));
di->thd.set_query(my_strdup(table_list->table_name, MYF(MY_WME)), 0);
@@ -2362,7 +2362,7 @@ void kill_delayed_threads(void)
Delayed_insert *di;
while ((di= it++))
{
- di->thd.killed= THD::KILL_CONNECTION;
+ di->thd.killed= KILL_SYSTEM_THREAD;
pthread_mutex_lock(&di->thd.LOCK_thd_data);
if (di->thd.mysys_var)
{
@@ -2447,7 +2447,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
for (;;)
{
- if (thd->killed == THD::KILL_CONNECTION)
+ if (thd->killed >= KILL_CONNECTION)
{
uint lock_count;
/*
@@ -2495,7 +2495,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
break;
if (error == ETIMEDOUT || error == ETIME)
{
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_SYSTEM_THREAD;
break;
}
}
@@ -2528,7 +2528,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
{
/* Fatal error */
di->dead= 1;
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_SYSTEM_THREAD;
}
pthread_cond_broadcast(&di->cond_client);
}
@@ -2538,7 +2538,7 @@ static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
{
/* Some fatal error */
di->dead= 1;
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_SYSTEM_THREAD;
}
}
di->status=0;
@@ -2598,7 +2598,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
thd->set_current_time();
threads.append(thd);
- thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED;
+ thd->killed=abort_loop ? KILL_SYSTEM_THREAD : NOT_KILLED;
pthread_mutex_unlock(&LOCK_thread_count);
/*
@@ -2632,7 +2632,7 @@ end:
di->table=0;
di->dead= 1; // If error
- thd->killed= THD::KILL_CONNECTION; // If error
+ thd->killed= KILL_SYSTEM_THREAD; // If error
pthread_mutex_unlock(&di->mutex);
close_thread_tables(thd); // Free the table
@@ -2711,7 +2711,7 @@ bool Delayed_insert::handle_inserts(void)
max_rows= delayed_insert_limit;
if (thd.killed || table->needs_reopen_or_name_lock())
{
- thd.killed= THD::KILL_CONNECTION;
+ thd.killed= KILL_SYSTEM_THREAD;
max_rows= ULONG_MAX; // Do as much as possible
}
@@ -2824,7 +2824,7 @@ bool Delayed_insert::handle_inserts(void)
/* if the delayed insert was killed, the killed status is
ignored while binlogging */
int errcode= 0;
- if (thd.killed == THD::NOT_KILLED)
+ if (thd.killed == NOT_KILLED)
errcode= query_error_code(&thd, TRUE);
/*
@@ -3015,6 +3015,7 @@ bool mysql_insert_select_prepare(THD *thd)
select_lex->leaf_tables_exec.push_back(table);
table->tablenr_exec= table->table->tablenr;
table->map_exec= table->table->map;
+ table->maybe_null_exec= table->table->maybe_null;
}
if (arena)
thd->restore_active_arena(arena, &backup);
@@ -3352,7 +3353,7 @@ bool select_insert::send_eof()
bool const trans_table= table->file->has_transactions();
ulonglong id;
bool changed;
- THD::killed_state killed_status= thd->killed;
+ killed_state killed_status= thd->killed;
DBUG_ENTER("select_insert::send_eof");
DBUG_PRINT("enter", ("trans_table=%d, table_type='%s'",
trans_table, table->file->table_type()));
@@ -3387,7 +3388,7 @@ bool select_insert::send_eof()
if (!error)
thd->clear_error();
else
- errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ errcode= query_error_code(thd, killed_status == NOT_KILLED);
if (write_to_binlog(trans_table, errcode))
{
@@ -3461,7 +3462,7 @@ void select_insert::abort() {
{
if (mysql_bin_log.is_open())
{
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
/* error of writing binary log is ignored */
write_to_binlog(transactional_table, errcode);
}
@@ -3822,7 +3823,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
!table->s->tmp_table &&
!ptr->get_create_info()->table_existed)
{
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
if (int error= ptr->binlog_show_create_table(tables, count, errcode))
return error;
}
@@ -3865,7 +3866,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
create_table->table_name);
if (thd->current_stmt_binlog_row_based)
{
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
binlog_show_create_table(&(create_table->table), 1, errcode);
}
table= create_table->table;
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
index 64b82efd8ff..f53bf738b86 100644
--- a/sql/sql_join_cache.cc
+++ b/sql/sql_join_cache.cc
@@ -225,8 +225,6 @@ void JOIN_CACHE::calc_record_fields()
flag_fields+= test(tab->table->maybe_null);
fields+= tab->used_fields;
blobs+= tab->used_blobs;
-
- fields+= tab->check_rowid_field();
}
if ((with_match_flag= join_tab->use_match_flag()))
flag_fields++;
@@ -609,11 +607,23 @@ void JOIN_CACHE::create_remaining_fields()
if (tab->keep_current_rowid)
{
copy->str= table->file->ref;
- copy->length= table->file->ref_length;
- copy->type= 0;
+ if (copy->str)
+ copy->length= table->file->ref_length;
+ else
+ {
+ /* This may happen only for materialized derived tables and views */
+ copy->length= 0;
+ copy->str= (uchar *) table;
+ }
+ copy->type= CACHE_ROWID;
copy->field= 0;
copy->referenced_field_no= 0;
- length+= copy->length;
+ /*
+ Note: this may seem odd, but at this point we have
+ table->file->ref==NULL while table->file->ref_length is already set
+ to correct value.
+ */
+ length += table->file->ref_length;
data_field_count++;
copy++;
}
@@ -1290,6 +1300,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
if (with_length)
{
rec_len_ptr= cp;
+ DBUG_ASSERT(cp + size_of_rec_len <= buff + buff_size);
cp+= size_of_rec_len;
}
@@ -1299,6 +1310,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
*/
if (prev_cache)
{
+ DBUG_ASSERT(cp + prev_cache->get_size_of_rec_offset() <= buff + buff_size);
cp+= prev_cache->get_size_of_rec_offset();
prev_cache->store_rec_ref(cp, link);
}
@@ -1315,6 +1327,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
flags_pos= cp;
for ( ; copy < copy_end; copy++)
{
+ DBUG_ASSERT(cp + copy->length <= buff + buff_size);
memcpy(cp, copy->str, copy->length);
cp+= copy->length;
}
@@ -1325,8 +1338,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
{
Field *field= copy->field;
if (field && field->maybe_null() && field->is_null())
- {
- /* Do not copy a field if its value is null */
+ {
if (copy->referenced_field_no)
copy->offset= 0;
continue;
@@ -1342,6 +1354,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
{
last_rec_blob_data_is_in_rec_buff= 1;
/* Put down the length of the blob and the pointer to the data */
+ DBUG_ASSERT(cp + copy->length + sizeof(char*) <= buff + buff_size);
blob_field->get_image(cp, copy->length+sizeof(char*),
blob_field->charset());
cp+= copy->length+sizeof(char*);
@@ -1351,6 +1364,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
/* First put down the length of the blob and then copy the data */
blob_field->get_image(cp, copy->length,
blob_field->charset());
+ DBUG_ASSERT(cp + copy->length + copy->blob_length <= buff + buff_size);
memcpy(cp+copy->length, copy->str, copy->blob_length);
cp+= copy->length+copy->blob_length;
}
@@ -1361,12 +1375,14 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
case CACHE_VARSTR1:
/* Copy the significant part of the short varstring field */
len= (uint) copy->str[0] + 1;
+ DBUG_ASSERT(cp + len <= buff + buff_size);
memcpy(cp, copy->str, len);
cp+= len;
break;
case CACHE_VARSTR2:
/* Copy the significant part of the long varstring field */
len= uint2korr(copy->str) + 2;
+ DBUG_ASSERT(cp + len <= buff + buff_size);
memcpy(cp, copy->str, len);
cp+= len;
break;
@@ -1381,14 +1397,38 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
end > str && end[-1] == ' ';
end--) ;
len=(uint) (end-str);
+ DBUG_ASSERT(cp + len + 2 <= buff + buff_size);
int2store(cp, len);
memcpy(cp+2, str, len);
cp+= len+2;
break;
}
+ case CACHE_ROWID:
+ if (!copy->length)
+ {
+ /*
+ This may happen only for ROWID fields of materialized
+ derived tables and views.
+ */
+ TABLE *table= (TABLE *) copy->str;
+ copy->str= table->file->ref;
+ copy->length= table->file->ref_length;
+ if (!copy->str)
+ {
+ /*
+ If table is an empty inner table of an outer join and it is
+ a materialized derived table then table->file->ref == NULL.
+ */
+ cp+= copy->length;
+ break;
+ }
+ }
+ /* fall through */
default:
/* Copy the entire image of the field from the record buffer */
- memcpy(cp, copy->str, copy->length);
+ DBUG_ASSERT(cp + copy->length <= buff + buff_size);
+ if (copy->str)
+ memcpy(cp, copy->str, copy->length);
cp+= copy->length;
}
}
@@ -1407,6 +1447,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
cnt++;
}
}
+ DBUG_ASSERT(cp + size_of_fld_ofs*cnt <= buff + buff_size);
cp+= size_of_fld_ofs*cnt;
}
@@ -1455,7 +1496,6 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
RETURN VALUE
none
*/
-
void JOIN_CACHE::reset(bool for_writing)
{
pos= buff;
@@ -1781,6 +1821,13 @@ uint JOIN_CACHE::read_record_field(CACHE_FIELD *copy, bool blob_in_rec_buff)
memset(copy->str+len, ' ', copy->length-len);
len+= 2;
break;
+ case CACHE_ROWID:
+ if (!copy->str)
+ {
+ len= copy->length;
+ break;
+ }
+ /* fall through */
default:
/* Copy the entire image of the field from the record buffer */
len= copy->length;
@@ -2004,6 +2051,7 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last)
JOIN_TAB *tab;
enum_nested_loop_state rc= NESTED_LOOP_OK;
bool outer_join_first_inner= join_tab->is_first_inner_for_outer_join();
+ DBUG_ENTER("JOIN_CACHE::join_records");
if (outer_join_first_inner && !join_tab->first_unmatched)
join_tab->not_null_compl= TRUE;
@@ -2085,7 +2133,8 @@ enum_nested_loop_state JOIN_CACHE::join_records(bool skip_last)
finish:
restore_last_record();
reset(TRUE);
- return rc;
+ DBUG_PRINT("exit", ("rc: %d", rc));
+ DBUG_RETURN(rc);
}
@@ -2147,10 +2196,11 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last)
join_tab->table->null_row= 0;
bool check_only_first_match= join_tab->check_only_first_match();
bool outer_join_first_inner= join_tab->is_first_inner_for_outer_join();
+ DBUG_ENTER("JOIN_CACHE::join_matching_records");
/* Return at once if there are no records in the join buffer */
if (!records)
- return NESTED_LOOP_OK;
+ DBUG_RETURN(NESTED_LOOP_OK);
/*
When joining we read records from the join buffer back into record buffers.
@@ -2224,7 +2274,7 @@ finish:
rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
finish2:
join_tab_scan->close();
- return rc;
+ DBUG_RETURN(rc);
}
@@ -2306,6 +2356,7 @@ bool JOIN_CACHE::set_match_flag_if_none(JOIN_TAB *first_inner,
enum_nested_loop_state JOIN_CACHE::generate_full_extensions(uchar *rec_ptr)
{
enum_nested_loop_state rc= NESTED_LOOP_OK;
+ DBUG_ENTER("JOIN_CACHE::generate_full_extensions");
/*
Check whether the extended partial join record meets
@@ -2323,16 +2374,18 @@ enum_nested_loop_state JOIN_CACHE::generate_full_extensions(uchar *rec_ptr)
if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
{
reset(TRUE);
- return rc;
+ DBUG_RETURN(rc);
}
}
if (res == -1)
{
rc= NESTED_LOOP_ERROR;
- return rc;
+ DBUG_RETURN(rc);
}
}
- return rc;
+ else if (join->thd->is_error())
+ rc= NESTED_LOOP_ERROR;
+ DBUG_RETURN(rc);
}
@@ -2357,16 +2410,20 @@ enum_nested_loop_state JOIN_CACHE::generate_full_extensions(uchar *rec_ptr)
RETURN VALUE
TRUE there is a match
FALSE there is no match
+ In this case the caller must also check thd->is_error() to see
+ if there was a fatal error for the query.
*/
inline bool JOIN_CACHE::check_match(uchar *rec_ptr)
{
/* Check whether pushdown conditions are satisfied */
+ DBUG_ENTER("JOIN_CACHE:check_match");
+
if (join_tab->select && join_tab->select->skip_record(join->thd) <= 0)
- return FALSE;
+ DBUG_RETURN(FALSE);
if (!join_tab->is_last_inner_table())
- return TRUE;
+ DBUG_RETURN(TRUE);
/*
This is the last inner table of an outer join,
@@ -2379,7 +2436,7 @@ inline bool JOIN_CACHE::check_match(uchar *rec_ptr)
set_match_flag_if_none(first_inner, rec_ptr);
if (first_inner->check_only_first_match() &&
!join_tab->first_inner)
- return TRUE;
+ DBUG_RETURN(TRUE);
/*
This is the first match for the outer table row.
The function set_match_flag_if_none has turned the flag
@@ -2393,13 +2450,12 @@ inline bool JOIN_CACHE::check_match(uchar *rec_ptr)
for (JOIN_TAB *tab= first_inner; tab <= join_tab; tab++)
{
if (tab->select && tab->select->skip_record(join->thd) <= 0)
- return FALSE;
+ DBUG_RETURN(FALSE);
}
}
while ((first_inner= first_inner->first_upper) &&
first_inner->last_inner == join_tab);
-
- return TRUE;
+ DBUG_RETURN(TRUE);
}
@@ -2434,10 +2490,11 @@ enum_nested_loop_state JOIN_CACHE::join_null_complements(bool skip_last)
ulonglong cnt;
enum_nested_loop_state rc= NESTED_LOOP_OK;
bool is_first_inner= join_tab == join_tab->first_unmatched;
+ DBUG_ENTER("JOIN_CACHE::join_null_complements");
/* Return at once if there are no records in the join buffer */
if (!records)
- return NESTED_LOOP_OK;
+ DBUG_RETURN(NESTED_LOOP_OK);
cnt= records - (is_key_access() ? 0 : test(skip_last));
@@ -2467,7 +2524,7 @@ enum_nested_loop_state JOIN_CACHE::join_null_complements(bool skip_last)
}
finish:
- return rc;
+ DBUG_RETURN(rc);
}
diff --git a/sql/sql_join_cache.h b/sql/sql_join_cache.h
index f87cdcec649..f5d64d5530a 100644
--- a/sql/sql_join_cache.h
+++ b/sql/sql_join_cache.h
@@ -16,6 +16,7 @@
#define CACHE_STRIPPED 2 /* field stripped of trailing spaces */
#define CACHE_VARSTR1 3 /* short string value (length takes 1 byte) */
#define CACHE_VARSTR2 4 /* long string value (length takes 2 bytes) */
+#define CACHE_ROWID 5 /* ROWID field */
/*
The CACHE_FIELD structure used to describe fields of records that
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index d3613d0d660..117a866555c 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -21,8 +21,8 @@
#include "item_create.h"
#include <m_ctype.h>
#include <hash.h>
-#include "sp.h"
#include "sp_head.h"
+#include "sp.h"
#include "sql_select.h"
/*
@@ -339,6 +339,7 @@ void lex_start(THD *thd)
lex->event_parse_data= NULL;
lex->profile_options= PROFILE_NONE;
lex->nest_level=0 ;
+ lex->select_lex.nest_level_base= &lex->unit;
lex->allow_sum_func= 0;
lex->in_sum_func= NULL;
lex->protect_against_global_read_lock= FALSE;
@@ -1272,39 +1273,39 @@ int MYSQLlex(void *arg, void *yythd)
lip->save_in_comment_state();
+ if (lip->yyPeekn(2) == 'M' && lip->yyPeekn(3) == '!')
+ {
+ /* Skip MariaDB unique marker */
+ lip->set_echo(FALSE);
+ lip->yySkip();
+ /* The following if will be true */
+ }
if (lip->yyPeekn(2) == '!')
{
lip->in_comment= DISCARD_COMMENT;
/* Accept '/' '*' '!', but do not keep this marker. */
lip->set_echo(FALSE);
- lip->yySkip();
- lip->yySkip();
- lip->yySkip();
+ lip->yySkipn(3);
/*
The special comment format is very strict:
- '/' '*' '!', followed by exactly
+ '/' '*' '!', followed by an optional 'M' and exactly
1 digit (major), 2 digits (minor), then 2 digits (dot).
32302 -> 3.23.02
50032 -> 5.0.32
50114 -> 5.1.14
*/
- char version_str[6];
- version_str[0]= lip->yyPeekn(0);
- version_str[1]= lip->yyPeekn(1);
- version_str[2]= lip->yyPeekn(2);
- version_str[3]= lip->yyPeekn(3);
- version_str[4]= lip->yyPeekn(4);
- version_str[5]= 0;
- if ( my_isdigit(cs, version_str[0])
- && my_isdigit(cs, version_str[1])
- && my_isdigit(cs, version_str[2])
- && my_isdigit(cs, version_str[3])
- && my_isdigit(cs, version_str[4])
+ if ( my_isdigit(cs, lip->yyPeekn(0))
+ && my_isdigit(cs, lip->yyPeekn(1))
+ && my_isdigit(cs, lip->yyPeekn(2))
+ && my_isdigit(cs, lip->yyPeekn(3))
+ && my_isdigit(cs, lip->yyPeekn(4))
)
{
ulong version;
- version=strtol(version_str, NULL, 10);
+ char *end_ptr= (char*) lip->get_ptr()+5;
+ int error;
+ version= (ulong) my_strtoll10(lip->get_ptr(), &end_ptr, &error);
if (version <= MYSQL_VERSION_ID)
{
@@ -1604,6 +1605,7 @@ void st_select_lex::init_query()
top_join_list.empty();
join_list= &top_join_list;
embedding= 0;
+ leaf_tables_prep.empty();
leaf_tables.empty();
item_list.empty();
join= 0;
@@ -1638,6 +1640,7 @@ void st_select_lex::init_query()
nest_level= 0;
link_next= 0;
lock_option= TL_READ_DEFAULT;
+ is_prep_leaf_list_saved= FALSE;
bzero((char*) expr_cache_may_be_used, sizeof(expr_cache_may_be_used));
}
@@ -1646,6 +1649,7 @@ void st_select_lex::init_select()
{
st_select_lex_node::init_select();
sj_nests.empty();
+ sj_subselects.empty();
group_list.empty();
type= db= 0;
having= 0;
@@ -1876,55 +1880,6 @@ void st_select_lex_unit::exclude_tree()
}
-/**
- Register reference to an item which the subqueries depends on
-
- @param def_sel select against which the item is resolved
- @param dependency reference to the item
-
- @details
- This function puts the reference dependency to an item that is either an
- outer field or an aggregate function resolved against an outer select into
- the list 'depends_on'. It adds it to the 'depends_on' lists for each
- subquery between this one and 'def_sel' - the subquery against which the
- item is resolved.
-*/
-
-void st_select_lex::register_dependency_item(st_select_lex *def_sel,
- Item **dependency)
-{
- SELECT_LEX *s= this;
- DBUG_ENTER("st_select_lex::register_dependency_item");
- DBUG_ASSERT(this != def_sel);
- DBUG_ASSERT(*dependency);
- do
- {
- /* check duplicates */
- List_iterator_fast<Item*> li(s->master_unit()->item->depends_on);
- Item **dep;
- while ((dep= li++))
- {
- if ((*dep)->eq(*dependency, FALSE))
- {
- DBUG_PRINT("info", ("dependency %s already present",
- ((*dependency)->name ?
- (*dependency)->name :
- "<no name>")));
- DBUG_VOID_RETURN;
- }
- }
-
- s->master_unit()->item->depends_on.push_back(dependency);
- DBUG_PRINT("info", ("depends_on: Select: %d added: %s",
- s->select_number,
- ((*dependency)->name ?
- (*dependency)->name :
- "<no name>")));
- } while ((s= s->outer_select()) != def_sel);
- DBUG_VOID_RETURN;
-}
-
-
/*
st_select_lex_node::mark_as_dependent mark all st_select_lex struct from
this to 'last' as dependent
@@ -3229,12 +3184,6 @@ bool st_select_lex::get_free_table_map(table_map *map, uint *tablenr)
*map= 0;
*tablenr= 0;
TABLE_LIST *tl;
- if (!join)
- {
- (*map)= 1<<1;
- (*tablenr)++;
- return FALSE;
- }
List_iterator<TABLE_LIST> ti(leaf_tables);
while ((tl= ti++))
{
@@ -3272,18 +3221,19 @@ void st_select_lex::append_table_to_list(TABLE_LIST *TABLE_LIST::*link,
tl->*link= table;
}
+
/*
@brief
- Remove given table from the leaf_tables list.
+ Replace given table from the leaf_tables list for a list of tables
- @param link Offset to which list in table structure to use
- @param table Table to remove
+ @param table Table to replace
+ @param list List to substititute the table for
@details
- Remove 'table' from the leaf_tables list using the 'link' offset.
+ Replace 'table' from the leaf_tables list for a list of tables 'tbl_list'.
*/
-void st_select_lex::remove_table_from_list(TABLE_LIST *table)
+void st_select_lex::replace_leaf_table(TABLE_LIST *table, List<TABLE_LIST> &tbl_list)
{
TABLE_LIST *tl;
List_iterator<TABLE_LIST> ti(leaf_tables);
@@ -3291,7 +3241,7 @@ void st_select_lex::remove_table_from_list(TABLE_LIST *table)
{
if (tl == table)
{
- ti.remove();
+ ti.replace(tbl_list);
break;
}
}
@@ -3391,39 +3341,34 @@ void st_select_lex::remap_tables(TABLE_LIST *derived, table_map map,
@return FALSE ok
*/
-bool SELECT_LEX::merge_subquery(TABLE_LIST *derived, SELECT_LEX *subq_select,
+bool SELECT_LEX::merge_subquery(THD *thd, TABLE_LIST *derived,
+ SELECT_LEX *subq_select,
uint table_no, table_map map)
{
derived->wrap_into_nested_join(subq_select->top_join_list);
- /* Reconnect the next_leaf chain. */
- leaf_tables.concat(&subq_select->leaf_tables);
ftfunc_list->concat(subq_select->ftfunc_list);
- if (join)
- {
- Item_in_subselect **in_subq;
- Item_in_subselect **in_subq_end;
- for (in_subq= subq_select->join->sj_subselects.front(),
- in_subq_end= subq_select->join->sj_subselects.back();
- in_subq != in_subq_end;
- in_subq++)
+ if (join ||
+ thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
+ thd->lex->sql_command == SQLCOM_DELETE_MULTI)
+ {
+ List_iterator_fast<Item_in_subselect> li(subq_select->sj_subselects);
+ Item_in_subselect *in_subq;
+ while ((in_subq= li++))
{
- join->sj_subselects.append(join->thd->mem_root, *in_subq);
- (*in_subq)->emb_on_expr_nest= derived;
+ sj_subselects.push_back(in_subq);
+ if (in_subq->emb_on_expr_nest == NO_JOIN_NEST)
+ in_subq->emb_on_expr_nest= derived;
}
}
- /*
- Remove merged table from chain.
- When merge_subquery is called at a subquery-to-semijoin transformation
- the derived isn't in the leaf_tables list, so in this case the call of
- remove_table_from_list does not cause any actions.
- */
- remove_table_from_list(derived);
/* Walk through child's tables and adjust table map, tablenr,
* parent_lex */
subq_select->remap_tables(derived, map, table_no, this);
subq_select->merged_into= this;
+
+ replace_leaf_table(derived, subq_select->leaf_tables);
+
return FALSE;
}
@@ -3464,14 +3409,49 @@ void SELECT_LEX::update_used_tables()
{
TABLE_LIST *tl;
List_iterator<TABLE_LIST> ti(leaf_tables);
+
while ((tl= ti++))
{
+ if (tl->table && !tl->is_view_or_derived())
+ {
+ TABLE_LIST *embedding= tl->embedding;
+ for (embedding= tl->embedding; embedding; embedding=embedding->embedding)
+ {
+ if (embedding->is_view_or_derived())
+ {
+ DBUG_ASSERT(embedding->is_merged_derived());
+ TABLE *tab= tl->table;
+ tab->covering_keys= tab->s->keys_for_keyread;
+ tab->covering_keys.intersect(tab->keys_in_use_for_query);
+ tab->merge_keys.clear_all();
+ bitmap_clear_all(tab->read_set);
+ bitmap_clear_all(tab->vcol_set);
+ break;
+ }
+ }
+ }
+ }
+
+ ti.rewind();
+ while ((tl= ti++))
+ {
+ TABLE_LIST *embedding= tl;
+ do
+ {
+ bool maybe_null;
+ if ((maybe_null= test(embedding->outer_join)))
+ {
+ tl->table->maybe_null= maybe_null;
+ break;
+ }
+ }
+ while ((embedding= embedding->embedding));
if (tl->on_expr)
{
tl->on_expr->update_used_tables();
tl->on_expr->walk(&Item::eval_not_null_tables, 0, NULL);
}
- TABLE_LIST *embedding= tl->embedding;
+ embedding= tl->embedding;
while (embedding)
{
if (embedding->on_expr &&
@@ -3484,11 +3464,37 @@ void SELECT_LEX::update_used_tables()
embedding= tl->embedding;
}
}
+
if (join->conds)
{
join->conds->update_used_tables();
join->conds->walk(&Item::eval_not_null_tables, 0, NULL);
}
+ if (join->having)
+ {
+ join->having->update_used_tables();
+ }
+
+ Item *item;
+ List_iterator_fast<Item> it(join->fields_list);
+ while ((item= it++))
+ {
+ item->update_used_tables();
+ }
+ Item_outer_ref *ref;
+ List_iterator_fast<Item_outer_ref> ref_it(inner_refs_list);
+ while ((ref= ref_it++))
+ {
+ item= ref->outer_ref;
+ item->update_used_tables();
+ }
+ for (ORDER *order= group_list.first; order; order= order->next)
+ (*order->item)->update_used_tables();
+ if (!master_unit()->is_union())
+ {
+ for (ORDER *order= order_list.first; order; order= order->next)
+ (*order->item)->update_used_tables();
+ }
}
@@ -3585,6 +3591,7 @@ void SELECT_LEX::mark_const_derived(bool empty)
}
}
+
bool st_select_lex::save_leaf_tables(THD *thd)
{
Query_arena *arena= thd->stmt_arena, backup;
@@ -3601,7 +3608,38 @@ bool st_select_lex::save_leaf_tables(THD *thd)
return 1;
table->tablenr_exec= table->table->tablenr;
table->map_exec= table->table->map;
+ if (join && (join->select_options & SELECT_DESCRIBE))
+ table->maybe_null_exec= 0;
+ else
+ table->maybe_null_exec= table->table->maybe_null;
+ }
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+
+ return 0;
+}
+
+
+bool st_select_lex::save_prep_leaf_tables(THD *thd)
+{
+ if (!thd->save_prep_leaf_list)
+ return 0;
+
+ Query_arena *arena= thd->stmt_arena, backup;
+ if (arena->is_conventional())
+ arena= 0;
+ else
+ thd->set_n_backup_active_arena(arena, &backup);
+
+ List_iterator_fast<TABLE_LIST> li(leaf_tables);
+ TABLE_LIST *table;
+ while ((table= li++))
+ {
+ if (leaf_tables_prep.push_back(table))
+ return 1;
}
+ thd->lex->select_lex.is_prep_leaf_list_saved= TRUE;
+ thd->save_prep_leaf_list= FALSE;
if (arena)
thd->restore_active_arena(arena, &backup);
@@ -3609,6 +3647,47 @@ bool st_select_lex::save_leaf_tables(THD *thd)
}
+/*
+ Return true if this select_lex has been converted into a semi-join nest
+ within 'ancestor'.
+
+ We need a loop to check this because there could be several nested
+ subselects, like
+
+ SELECT ... FROM grand_parent
+ WHERE expr1 IN (SELECT ... FROM parent
+ WHERE expr2 IN ( SELECT ... FROM child)
+
+ which were converted into:
+
+ SELECT ...
+ FROM grand_parent SEMI_JOIN (parent JOIN child)
+ WHERE
+ expr1 AND expr2
+
+ In this case, both parent and child selects were merged into the parent.
+*/
+
+bool st_select_lex::is_merged_child_of(st_select_lex *ancestor)
+{
+ bool all_merged= TRUE;
+ for (SELECT_LEX *sl= this; sl && sl!=ancestor;
+ sl=sl->outer_select())
+ {
+ Item *subs= sl->master_unit()->item;
+ if (subs && subs->type() == Item::SUBSELECT_ITEM &&
+ ((Item_subselect*)subs)->substype() == Item_subselect::IN_SUBS &&
+ ((Item_in_subselect*)subs)->test_strategy(SUBS_SEMI_JOIN))
+ {
+ continue;
+ }
+ all_merged= FALSE;
+ break;
+ }
+ return all_merged;
+}
+
+
/**
A routine used by the parser to decide whether we are specifying a full
partitioning or if only partitions to add or to split.
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 5a8b5a5f361..4caf2a1dbb3 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -637,8 +637,16 @@ public:
tables. Unlike 'next_local', this in this list views are *not*
leaves. Created in setup_tables() -> make_leaves_list().
*/
+ /*
+ Subqueries that will need to be converted to semi-join nests, including
+ those converted to jtbm nests. The list is emptied when conversion is done.
+ */
+ List<Item_in_subselect> sj_subselects;
+
List<TABLE_LIST> leaf_tables;
List<TABLE_LIST> leaf_tables_exec;
+ List<TABLE_LIST> leaf_tables_prep;
+ bool is_prep_leaf_list_saved;
uint insert_tables;
st_select_lex *merged_into; /* select which this select is merged into */
/* (not 0 only for views/derived tables) */
@@ -676,6 +684,13 @@ public:
ulong table_join_options;
uint in_sum_expr;
uint select_number; /* number of select (used for EXPLAIN) */
+
+ /*
+ nest_levels are local to the query or VIEW,
+ and that view merge procedure does not re-calculate them.
+ So we also have to remember unit against which we count levels.
+ */
+ SELECT_LEX_UNIT *nest_level_base;
int nest_level; /* nesting level of select */
Item_sum *inner_sum_func_list; /* list of sum func in nested selects */
uint with_wild; /* item list contain '*' */
@@ -785,7 +800,6 @@ public:
inline bool is_subquery_function() { return master_unit()->item != 0; }
bool mark_as_dependent(THD *thd, st_select_lex *last, Item *dependency);
- void register_dependency_item(st_select_lex *last, Item **dependency);
bool set_braces(bool value);
bool inc_in_sum_expr();
@@ -881,10 +895,10 @@ public:
bool handle_derived(struct st_lex *lex, uint phases);
void append_table_to_list(TABLE_LIST *TABLE_LIST::*link, TABLE_LIST *table);
bool get_free_table_map(table_map *map, uint *tablenr);
- void remove_table_from_list(TABLE_LIST *table);
+ void replace_leaf_table(TABLE_LIST *table, List<TABLE_LIST> &tbl_list);
void remap_tables(TABLE_LIST *derived, table_map map,
uint tablenr, st_select_lex *parent_lex);
- bool merge_subquery(TABLE_LIST *derived, st_select_lex *subq_lex,
+ bool merge_subquery(THD *thd, TABLE_LIST *derived, st_select_lex *subq_lex,
uint tablenr, table_map map);
inline bool is_mergeable()
{
@@ -899,7 +913,8 @@ public:
void mark_const_derived(bool empty);
bool save_leaf_tables(THD *thd);
-
+ bool save_prep_leaf_tables(THD *thd);
+ bool is_merged_child_of(st_select_lex *ancestor);
private:
/* current index hint kind. used in filling up index_hints */
enum index_hint_type current_index_hint_type;
@@ -1727,6 +1742,9 @@ typedef struct st_lex : public Query_tables_list
LEX_SERVER_OPTIONS server_options;
USER_RESOURCES mqh;
ulong type;
+ /* The following is used by KILL */
+ killed_state kill_signal;
+ killed_type kill_type;
/*
This variable is used in post-parse stage to declare that sum-functions,
or functions which have sense only if GROUP BY is present, are allowed.
diff --git a/sql/sql_list.h b/sql/sql_list.h
index 38235a10c18..4655b4e3577 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -152,6 +152,7 @@ struct list_node :public Sql_alloc
}
};
+typedef bool List_eq(void *a, void *b);
extern MYSQL_PLUGIN_IMPORT list_node end_of_list;
@@ -295,10 +296,40 @@ public:
inline void **head_ref() { return first != &end_of_list ? &first->info : 0; }
inline bool is_empty() { return first == &end_of_list ; }
inline list_node *last_ref() { return &end_of_list; }
+ inline bool add_unique(void *info, List_eq *eq)
+ {
+ list_node *node= first;
+ for (;
+ node != &end_of_list && (!(*eq)(node->info, info));
+ node= node->next) ;
+ if (node == &end_of_list)
+ return push_back(info);
+ return 1;
+ }
friend class base_list_iterator;
friend class error_list;
friend class error_list_iterator;
+ /*
+ Debugging help: return N-th element in the list, or NULL if the list has
+ less than N elements.
+ */
+ inline void *nth_element(int n)
+ {
+ list_node *node= first;
+ void *data= NULL;
+ for (int i=0; i <= n; i++)
+ {
+ if (node == &end_of_list)
+ {
+ data= NULL;
+ break;
+ }
+ data= node->info;
+ node= node->next;
+ }
+ return data;
+ }
#ifdef LIST_EXTRA_DEBUG
/*
Check list invariants and print results into trace. Invariants are:
@@ -465,6 +496,8 @@ public:
inline void concat(List<T> *list) { base_list::concat(list); }
inline void disjoin(List<T> *list) { base_list::disjoin(list); }
inline void prepand(List<T> *list) { base_list::prepand(list); }
+ inline bool add_unique(T *a, bool (*eq)(T *a, T *b))
+ { return base_list::add_unique(a, (List_eq *)eq); }
void delete_elements(void)
{
list_node *element,*next;
@@ -475,6 +508,7 @@ public:
}
empty();
}
+ inline T *nth_element(int n) { return (T*)base_list::nth_element(n); }
};
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 089c148778e..3df6305f620 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -63,6 +63,8 @@ public:
::end_io_cache(&cache);
need_end_io_cache = 0;
}
+ my_off_t file_length() { return cache.end_of_file; }
+ my_off_t position() { return my_b_tell(&cache); }
/*
Either this method, or we need to make cache public
@@ -128,7 +130,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
bool is_fifo=0;
#ifndef EMBEDDED_LIBRARY
LOAD_FILE_INFO lf_info;
- THD::killed_state killed_status;
+ killed_state killed_status;
#endif
char *db = table_list->db; // This is never null
/*
@@ -416,9 +418,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
}
}
+ thd_proc_info(thd, "reading file");
if (!(error=test(read_info.error)))
{
-
table->next_number_field=table->found_next_number_field;
if (ignore ||
handle_duplicates == DUP_REPLACE)
@@ -436,6 +438,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
(MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES)));
+ thd_progress_init(thd, 2);
if (!field_term->length() && !enclosed->length())
error= read_fixed_length(thd, info, table_list, fields_vars,
set_fields, set_values, read_info,
@@ -444,6 +447,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
error= read_sep_field(thd, info, table_list, fields_vars,
set_fields, set_values, read_info,
*enclosed, skip_lines, ignore);
+
+ thd_proc_info(thd, "End bulk insert");
+ thd_progress_next_stage(thd);
if (!thd->prelocked_mode && table->file->ha_end_bulk_insert() && !error)
{
table->file->print_error(my_errno, MYF(0));
@@ -465,11 +471,11 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
DBUG_EXECUTE_IF("simulate_kill_bug27571",
{
error=1;
- thd->killed= THD::KILL_QUERY;
+ thd->killed= KILL_QUERY;
};);
#ifndef EMBEDDED_LIBRARY
- killed_status= (error == 0) ? THD::NOT_KILLED : thd->killed;
+ killed_status= (error == 0) ? NOT_KILLED : thd->killed;
#endif
/*
@@ -513,7 +519,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
/* If the file was not empty, wrote_create_file is true */
if (lf_info.wrote_create_file)
{
- int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, killed_status == NOT_KILLED);
/* since there is already an error, the possible error of
writing binary log will be ignored */
@@ -564,7 +570,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
read_info.end_io_cache();
if (lf_info.wrote_create_file)
{
- int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, killed_status == NOT_KILLED);
error= write_execute_load_query_log_event(thd, ex,
table_list->db, table_list->table_name,
handle_duplicates, ignore,
@@ -736,9 +742,16 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List_iterator_fast<Item> it(fields_vars);
Item_field *sql_field;
TABLE *table= table_list->table;
- bool err;
+ bool err, progress_reports;
+ ulonglong counter, time_to_report_progress;
DBUG_ENTER("read_fixed_length");
+ counter= 0;
+ time_to_report_progress= MY_HOW_OFTEN_TO_WRITE/10;
+ progress_reports= 1;
+ if ((thd->progress.max_counter= read_info.file_length()) == ~(my_off_t) 0)
+ progress_reports= 0;
+
while (!read_info.read_fixed_length())
{
if (thd->killed)
@@ -746,6 +759,16 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
thd->send_kill_message();
DBUG_RETURN(1);
}
+ if (progress_reports)
+ {
+ thd->progress.counter= read_info.position();
+ if (++counter >= time_to_report_progress)
+ {
+ time_to_report_progress+= MY_HOW_OFTEN_TO_WRITE/10;
+ thd_progress_report(thd, thd->progress.counter,
+ thd->progress.max_counter);
+ }
+ }
if (skip_lines)
{
/*
@@ -864,11 +887,18 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
Item *item;
TABLE *table= table_list->table;
uint enclosed_length;
- bool err;
+ bool err, progress_reports;
+ ulonglong counter, time_to_report_progress;
DBUG_ENTER("read_sep_field");
enclosed_length=enclosed.length();
+ counter= 0;
+ time_to_report_progress= MY_HOW_OFTEN_TO_WRITE/10;
+ progress_reports= 1;
+ if ((thd->progress.max_counter= read_info.file_length()) == ~(my_off_t) 0)
+ progress_reports= 0;
+
for (;;it.rewind())
{
if (thd->killed)
@@ -877,6 +907,16 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(1);
}
+ if (progress_reports)
+ {
+ thd->progress.counter= read_info.position();
+ if (++counter >= time_to_report_progress)
+ {
+ time_to_report_progress+= MY_HOW_OFTEN_TO_WRITE/10;
+ thd_progress_report(thd, thd->progress.counter,
+ thd->progress.max_counter);
+ }
+ }
restore_record(table, s->default_values);
while ((item= it++))
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index f219c8d6876..a1c373ce426 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -265,17 +265,17 @@ void init_update_queries(void)
bzero((uchar*) &sql_command_flags, sizeof(sql_command_flags));
sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
- sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA;
- sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
+ sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND | CF_REPORT_PROGRESS;
sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA;
- sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
+ sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE | CF_REPORT_PROGRESS;
sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_BACKUP_TABLE]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_RESTORE_TABLE]= CF_CHANGES_DATA;
- sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
+ sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA | CF_REPORT_PROGRESS;
sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
sql_command_flags[SQLCOM_DROP_VIEW]= CF_CHANGES_DATA;
sql_command_flags[SQLCOM_CREATE_EVENT]= CF_CHANGES_DATA;
@@ -368,9 +368,11 @@ void init_update_queries(void)
The following admin table operations are allowed
on log tables.
*/
- sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND;
- sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND;
- sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND;
+ sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND | CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND | CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND | CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_CHECK]= CF_REPORT_PROGRESS;
+ sql_command_flags[SQLCOM_CHECKSUM]= CF_REPORT_PROGRESS;
}
@@ -790,7 +792,17 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
if (res < 0)
my_error(thd->killed_errno(), MYF(0));
else if ((res == 0) && do_release)
- thd->killed= THD::KILL_CONNECTION;
+ {
+ thd->killed= KILL_CONNECTION;
+ if (global_system_variables.log_warnings > 3)
+ {
+ Security_context *sctx= &thd->main_security_ctx;
+ sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
+ thd->thread_id,(thd->db ? thd->db : "unconnected"),
+ sctx->user ? sctx->user : "unauthenticated",
+ sctx->host_or_ip, "RELEASE");
+ }
+ }
DBUG_RETURN(res);
}
@@ -1130,12 +1142,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* Ensure we don't free security_ctx->user in case we have to revert */
thd->security_ctx->user= 0;
+ thd->user_connect= 0;
if (acl_authenticate(thd, 0, packet_length))
{
/* Free user if allocated by acl_authenticate */
x_free(thd->security_ctx->user);
*thd->security_ctx= save_security_ctx;
+ if (thd->user_connect)
+ decrease_user_connections(thd->user_connect);
thd->user_connect= save_user_connect;
thd->reset_db(save_db, save_db_length);
thd->variables.character_set_client= save_character_set_client;
@@ -1482,7 +1497,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
char *end= buff + length;
length+= my_snprintf(end, buff_len - length - 1,
- end," Memory in use: %ldK Max memory used: %ldK",
+ " Memory in use: %ldK Max memory used: %ldK",
(sf_malloc_cur_memory+1023L)/1024L,
(sf_malloc_max_memory+1023L)/1024L);
}
@@ -1515,7 +1530,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
{
status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]);
ulong id=(ulong) uint4korr(packet);
- sql_kill(thd,id,false);
+ sql_kill(thd,id, KILL_CONNECTION_HARD);
break;
}
case COM_SET_OPTION:
@@ -1557,15 +1572,18 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
/* report error issued during command execution */
- if (thd->killed_errno())
- {
- if (! thd->main_da.is_set())
- thd->send_kill_message();
- }
- if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
+ if (thd->killed)
{
- thd->killed= THD::NOT_KILLED;
- thd->mysys_var->abort= 0;
+ if (thd->killed_errno())
+ {
+ if (! thd->main_da.is_set())
+ thd->send_kill_message();
+ }
+ if (thd->killed < KILL_CONNECTION)
+ {
+ thd->killed= NOT_KILLED;
+ thd->mysys_var->abort= 0;
+ }
}
/* If commit fails, we should be able to reset the OK status. */
@@ -1609,6 +1627,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd_proc_info(thd, 0);
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
+
+ /* Check that some variables are reset properly */
+ DBUG_ASSERT(thd->abort_on_warning == 0);
DBUG_RETURN(error);
}
@@ -2166,6 +2187,8 @@ mysql_execute_command(THD *thd)
} /* endif unlikely slave */
#endif
status_var_increment(thd->status_var.com_stat[lex->sql_command]);
+ thd->progress.report_to_client= test(sql_command_flags[lex->sql_command] &
+ CF_REPORT_PROGRESS);
DBUG_ASSERT(thd->transaction.stmt.modified_non_trans_table == FALSE);
@@ -2995,6 +3018,7 @@ end_with_restore_list:
thd->enable_slow_log= opt_log_slow_admin_statements;
thd->query_plan_flags|= QPLAN_ADMIN;
res= mysql_analyze_table(thd, first_table, &lex->check_opt);
+
/* ! we write after unlocking the table */
if (!res && !lex->no_write_to_binlog)
{
@@ -4017,8 +4041,6 @@ end_with_restore_list:
}
case SQLCOM_KILL:
{
- Item *it= (Item *)lex->value_list.head();
-
if (lex->table_or_sp_used())
{
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
@@ -4026,13 +4048,20 @@ end_with_restore_list:
break;
}
- if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
+ if (lex->kill_type == KILL_TYPE_ID)
{
- my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
- MYF(0));
- goto error;
+ Item *it= (Item *)lex->value_list.head();
+ if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
+ {
+ my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
+ MYF(0));
+ goto error;
+ }
+ sql_kill(thd, (ulong) it->val_int(), lex->kill_signal);
}
- sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
+ else
+ sql_kill_user(thd, get_current_user(thd, lex->users_list.head()),
+ lex->kill_signal);
break;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -4486,9 +4515,10 @@ create_sp_error:
*/
/* Conditionally writes to binlog */
- int type= lex->sql_command == SQLCOM_ALTER_PROCEDURE ?
- TYPE_ENUM_PROCEDURE :
- TYPE_ENUM_FUNCTION;
+ stored_procedure_type type;
+ type= (lex->sql_command == SQLCOM_ALTER_PROCEDURE ?
+ TYPE_ENUM_PROCEDURE :
+ TYPE_ENUM_FUNCTION);
sp_result= sp_update_routine(thd,
type,
@@ -4516,8 +4546,8 @@ create_sp_error:
case SQLCOM_DROP_FUNCTION:
{
int sp_result;
- int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
- TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
+ stored_procedure_type type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
+ TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
sp_result= sp_routine_exists_in_table(thd, type, lex->spname);
mysql_reset_errors(thd, 0);
@@ -4544,9 +4574,10 @@ create_sp_error:
#endif
/* Conditionally writes to binlog */
- int type= lex->sql_command == SQLCOM_DROP_PROCEDURE ?
- TYPE_ENUM_PROCEDURE :
- TYPE_ENUM_FUNCTION;
+ stored_procedure_type type;
+ type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
+ TYPE_ENUM_PROCEDURE :
+ TYPE_ENUM_FUNCTION);
sp_result= sp_drop_routine(thd, type, lex->spname);
}
@@ -5044,7 +5075,6 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
param->select_limit=
new Item_int((ulonglong) thd->variables.select_limit);
}
- thd->thd_marker.emb_on_expr_nest= NULL;
if (!(res= open_and_lock_tables(thd, all_tables)))
{
if (lex->describe)
@@ -5818,7 +5848,6 @@ void mysql_reset_thd_for_next_command(THD *thd, my_bool calculate_userstat)
thd->query_plan_flags= QPLAN_INIT;
thd->query_plan_fsort_passes= 0;
- thd->thd_marker.emb_on_expr_nest= NULL;
/*
Because we come here only for start of top-statements, binlog format is
@@ -5888,6 +5917,7 @@ mysql_new_select(LEX *lex, bool move_down)
DBUG_RETURN(1);
}
select_lex->nest_level= lex->nest_level;
+ select_lex->nest_level_base= &thd->lex->unit;
if (move_down)
{
SELECT_LEX_UNIT *unit;
@@ -6790,6 +6820,28 @@ push_new_name_resolution_context(THD *thd,
/**
+ Fix condition which contains only field (f turns to f <> 0 )
+
+ @param cond The condition to fix
+
+ @return fixed condition
+*/
+
+Item *normalize_cond(Item *cond)
+{
+ if (cond)
+ {
+ Item::Type type= cond->type();
+ if (type == Item::FIELD_ITEM || type == Item::REF_ITEM)
+ {
+ cond= new Item_func_ne(cond, new Item_int(0));
+ }
+ }
+ return cond;
+}
+
+
+/**
Add an ON condition to the second operand of a JOIN ... ON.
Add an ON condition to the right operand of a JOIN ... ON clause.
@@ -6807,6 +6859,7 @@ void add_join_on(TABLE_LIST *b, Item *expr)
{
if (expr)
{
+ expr= normalize_cond(expr);
if (!b->on_expr)
b->on_expr= expr;
else
@@ -7132,12 +7185,13 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
This is written such that we have a short lock on LOCK_thread_count
*/
-uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
+uint kill_one_thread(THD *thd, ulong id, killed_state kill_signal)
{
THD *tmp;
uint error=ER_NO_SUCH_THREAD;
DBUG_ENTER("kill_one_thread");
- DBUG_PRINT("enter", ("id=%lu only_kill=%d", id, only_kill_query));
+ DBUG_PRINT("enter", ("id: %lu signal: %u", id, (uint) kill_signal));
+
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
I_List_iterator<THD> it(threads);
while ((tmp=it++))
@@ -7168,12 +7222,16 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
If user of both killer and killee are non-NULL, proceed with
slayage if both are string-equal.
+
+ It's ok to also kill DELAYED threads with KILL_CONNECTION instead of
+ KILL_SYSTEM_THREAD; The difference is that KILL_CONNECTION may be
+ faster and do a harder kill than KILL_SYSTEM_THREAD;
*/
if ((thd->security_ctx->master_access & SUPER_ACL) ||
thd->security_ctx->user_matches(tmp->security_ctx))
{
- tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
+ tmp->awake(kill_signal);
error=0;
}
else
@@ -7185,6 +7243,76 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
}
+/**
+ kill all threads from one user
+
+ @param thd Thread class
+ @param user_name User name for threads we should kill
+ @param only_kill_query Should it kill the query or the connection
+
+ @note
+ This is written such that we have a short lock on LOCK_thread_count
+
+ If we can't kill all threads because of security issues, no threads
+ are killed.
+*/
+
+static uint kill_threads_for_user(THD *thd, LEX_USER *user,
+ killed_state kill_signal, ha_rows *rows)
+{
+ THD *tmp;
+ List<THD> threads_to_kill;
+ DBUG_ENTER("kill_threads_for_user");
+
+ *rows= 0;
+
+ if (thd->is_fatal_error) // If we run out of memory
+ DBUG_RETURN(ER_OUT_OF_RESOURCES);
+
+ DBUG_PRINT("enter", ("user: %s signal: %u", user->user.str,
+ (uint) kill_signal));
+
+ VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
+ I_List_iterator<THD> it(threads);
+ while ((tmp=it++))
+ {
+ if (tmp->command == COM_DAEMON)
+ continue;
+ /*
+ Check that hostname (if given) and user name matches.
+
+ host.str[0] == '%' means that host name was not given. See sql_yacc.yy
+ */
+ if (((user->host.str[0] == '%' && !user->host.str[1]) ||
+ !strcmp(tmp->security_ctx->host, user->host.str)) &&
+ !strcmp(tmp->security_ctx->user, user->user.str))
+ {
+ if (!(thd->security_ctx->master_access & SUPER_ACL) &&
+ !thd->security_ctx->user_matches(tmp->security_ctx))
+ {
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ DBUG_RETURN(ER_KILL_DENIED_ERROR);
+ }
+ if (!threads_to_kill.push_back(tmp, tmp->mem_root))
+ pthread_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
+ }
+ }
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+ if (!threads_to_kill.is_empty())
+ {
+ List_iterator_fast<THD> it(threads_to_kill);
+ THD *ptr;
+ while ((ptr= it++))
+ {
+ ptr->awake(kill_signal);
+ pthread_mutex_unlock(&ptr->LOCK_thd_data);
+ (*rows)++;
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
/*
kills a thread and sends response
@@ -7195,16 +7323,33 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
only_kill_query Should it kill the query or the connection
*/
-void sql_kill(THD *thd, ulong id, bool only_kill_query)
+void sql_kill(THD *thd, ulong id, killed_state state)
{
uint error;
- if (!(error= kill_one_thread(thd, id, only_kill_query)))
+ if (!(error= kill_one_thread(thd, id, state)))
my_ok(thd);
else
my_error(error, MYF(0), id);
}
+void sql_kill_user(THD *thd, LEX_USER *user, killed_state state)
+{
+ uint error;
+ ha_rows rows;
+ if (!(error= kill_threads_for_user(thd, user, state, &rows)))
+ my_ok(thd, rows);
+ else
+ {
+ /*
+ This is probably ER_OUT_OF_RESOURCES, but in the future we may
+ want to write the name of the user we tried to kill
+ */
+ my_error(error, MYF(0), user->host.str, user->user.str);
+ }
+}
+
+
/** If pointer is not a null pointer, append filename to it. */
bool append_file_to_dir(THD *thd, const char **filename_ptr,
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index a83990d25f4..8e6f065c1c4 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -1432,15 +1432,23 @@ int plugin_init(int *argc, char **argv, int flags)
if (register_builtin(plugin, &tmp, &plugin_ptr))
goto err_unlock;
- /* only initialize MyISAM and CSV at this stage */
- if (!(is_myisam=
- !my_strcasecmp(&my_charset_latin1, plugin->name, "MyISAM")) &&
- my_strcasecmp(&my_charset_latin1, plugin->name, "CSV"))
- continue;
+ is_myisam= !my_strcasecmp(&my_charset_latin1, plugin->name, "MyISAM");
- if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED &&
- plugin_initialize(plugin_ptr))
- goto err_unlock;
+ /*
+ strictly speaking, we should to initialize all plugins,
+ even for mysqld --help, because important subsystems
+ may be disabled otherwise, and the help will be incomplete.
+ For example, if the mysql.plugin table is not MyISAM.
+ But for now it's an unlikely corner case, and to optimize
+ mysqld --help for all other users, we will only initialize
+ MyISAM here.
+ */
+ if (!(flags & PLUGIN_INIT_SKIP_INITIALIZATION) || is_myisam)
+ {
+ if (plugin_ptr->state == PLUGIN_IS_UNINITIALIZED &&
+ plugin_initialize(plugin_ptr))
+ goto err_unlock;
+ }
/*
initialize the global default storage engine so that it may
@@ -1653,13 +1661,6 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
goto end;
}
table->use_all_columns();
- /*
- there're no other threads running yet, so we don't need a mutex.
- but plugin_add() before is designed to work in multi-threaded
- environment, and it uses safe_mutex_assert_owner(), so we lock
- the mutex here to satisfy the assert
- */
- pthread_mutex_lock(&LOCK_plugin);
while (!(error= read_record_info.read_record(&read_record_info)))
{
DBUG_PRINT("info", ("init plugin record"));
@@ -1670,12 +1671,19 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv)
LEX_STRING name= {(char *)str_name.ptr(), str_name.length()};
LEX_STRING dl= {(char *)str_dl.ptr(), str_dl.length()};
+ /*
+ there're no other threads running yet, so we don't need a mutex.
+ but plugin_add() before is designed to work in multi-threaded
+ environment, and it uses safe_mutex_assert_owner(), so we lock
+ the mutex here to satisfy the assert
+ */
+ pthread_mutex_lock(&LOCK_plugin);
if (plugin_add(tmp_root, &name, &dl, argc, argv, REPORT_TO_LOG))
sql_print_warning("Couldn't load plugin named '%s' with soname '%s'.",
str_name.c_ptr(), str_dl.c_ptr());
free_root(tmp_root, MYF(MY_MARK_BLOCKS_FREE));
+ pthread_mutex_unlock(&LOCK_plugin);
}
- pthread_mutex_unlock(&LOCK_plugin);
if (error > 0)
sql_print_error(ER(ER_GET_ERRNO), my_errno);
end_read_record(&read_record_info);
@@ -3376,6 +3384,19 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp,
opt->name, plugin_name);
}
}
+ /*
+ PLUGIN_VAR_STR command-line options without PLUGIN_VAR_MEMALLOC, point
+ directly to values in the argv[] array. For plugins started at the
+ server startup, argv[] array is allocated with load_defaults(), and
+ freed when the server is shut down. But for plugins loaded with
+ INSTALL PLUGIN, the memory allocated with load_defaults() is freed with
+ freed() at the end of mysql_install_plugin(). Which means we cannot
+ allow any pointers into that area.
+ Thus, for all plugins loaded after the server was started,
+ we force all command-line options to be PLUGIN_VAR_MEMALLOC
+ */
+ if (mysqld_server_started && !(opt->flags & PLUGIN_VAR_NOCMDOPT))
+ opt->flags|= PLUGIN_VAR_MEMALLOC;
break;
case PLUGIN_VAR_ENUM:
if (!opt->check)
@@ -3532,6 +3553,10 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp,
if (!my_strcasecmp(&my_charset_latin1, tmp->name.str, "ndbcluster"))
plugin_load_policy= PLUGIN_OFF;
#endif
+#ifdef WITH_FEEDBACK_PLUGIN
+ if (!my_strcasecmp(&my_charset_latin1, tmp->name.str, "feedback"))
+ plugin_load_policy= PLUGIN_OFF;
+#endif
for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
diff --git a/sql/sql_plugin_services.h b/sql/sql_plugin_services.h
index 8d4055dd764..497e2c8d6bc 100644
--- a/sql/sql_plugin_services.h
+++ b/sql/sql_plugin_services.h
@@ -38,9 +38,18 @@ static struct thd_alloc_service_st thd_alloc_handler= {
thd_make_lex_string
};
+static struct progress_report_service_st progress_report_handler= {
+ thd_progress_init,
+ thd_progress_report,
+ thd_progress_next_stage,
+ thd_progress_end,
+ set_thd_proc_info
+};
+
static struct st_service_ref list_of_services[] __attribute__((unused)) =
{
{ "my_snprintf_service", VERSION_my_snprintf, &my_snprintf_handler },
- { "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler }
+ { "thd_alloc_service", VERSION_thd_alloc, &thd_alloc_handler },
+ { "progress_report_service", VERSION_progress_report, &progress_report_handler }
};
#endif
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index ece4b8a1014..74ff1f0ebe1 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1269,8 +1269,9 @@ static int mysql_test_update(Prepared_statement *stmt,
thd->fill_derived_tables() is false here for sure (because it is
preparation of PS, so we even do not check it).
*/
- if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT) ||
- table_list->handle_derived(thd->lex, DT_PREPARE))
+ if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
+ goto error;
+ if (table_list->handle_derived(thd->lex, DT_PREPARE))
goto error;
if (!table_list->updatable)
@@ -1340,9 +1341,11 @@ static bool mysql_test_delete(Prepared_statement *stmt,
open_tables(thd, &table_list, &table_count, 0))
goto error;
- if (mysql_handle_derived(thd->lex, DT_INIT) ||
- mysql_handle_list_of_derived(thd->lex, table_list, DT_MERGE_FOR_INSERT) ||
- mysql_handle_list_of_derived(thd->lex, table_list, DT_PREPARE))
+ if (mysql_handle_derived(thd->lex, DT_INIT))
+ goto error;
+ if (mysql_handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
+ goto error;
+ if (mysql_handle_derived(thd->lex, DT_PREPARE))
goto error;
if (!table_list->updatable)
@@ -1410,7 +1413,6 @@ static int mysql_test_select(Prepared_statement *stmt,
goto error;
thd->used_tables= 0; // Updated by setup_fields
- thd->thd_marker.emb_on_expr_nest= 0;
/*
JOIN::prepare calls
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index fc472c17e57..e7363bffa9a 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1277,9 +1277,9 @@ err:
idle, then this could last long, and if the slave reconnects, we could have 2
Binlog_dump threads in SHOW PROCESSLIST, until a query is written to the
binlog. To avoid this, when the slave reconnects and sends COM_BINLOG_DUMP,
- the master kills any existing thread with the slave's server id (if this id is
- not zero; it will be true for real slaves, but false for mysqlbinlog when it
- sends COM_BINLOG_DUMP to get a remote binlog dump).
+ the master kills any existing thread with the slave's server id (if this id
+ is not zero; it will be true for real slaves, but false for mysqlbinlog when
+ it sends COM_BINLOG_DUMP to get a remote binlog dump).
SYNOPSIS
kill_zombie_dump_threads()
@@ -1311,7 +1311,7 @@ void kill_zombie_dump_threads(uint32 slave_server_id)
it will be slow because it will iterate through the list
again. We just to do kill the thread ourselves.
*/
- tmp->awake(THD::KILL_QUERY);
+ tmp->awake(KILL_QUERY);
pthread_mutex_unlock(&tmp->LOCK_thd_data);
}
}
@@ -1978,10 +1978,10 @@ static sys_var_const sys_log_slave_updates(&vars, "log_slave_updates",
OPT_GLOBAL, SHOW_MY_BOOL,
(uchar*) &opt_log_slave_updates);
static sys_var_const
-sys_replicate_annotate_rows_events(&vars,
- "replicate_annotate_rows_events",
+sys_replicate_annotate_row_events(&vars,
+ "replicate_annotate_row_events",
OPT_GLOBAL, SHOW_MY_BOOL,
- (uchar*) &opt_replicate_annotate_rows_events);
+ (uchar*) &opt_replicate_annotate_row_events);
static sys_var_const sys_relay_log(&vars, "relay_log",
OPT_GLOBAL, SHOW_CHAR_PTR,
(uchar*) &opt_relay_logname);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 6212f841793..8d83b4589d5 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -90,7 +90,7 @@ static store_key *get_store_key(THD *thd,
KEYUSE *keyuse, table_map used_tables,
KEY_PART_INFO *key_part, uchar *key_buff,
uint maybe_null);
-static void make_outerjoin_info(JOIN *join);
+static bool make_outerjoin_info(JOIN *join);
static Item*
make_cond_after_sjm(Item *root_cond, Item *cond, table_map tables, table_map sjm_tables);
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
@@ -175,14 +175,14 @@ int join_read_always_key_or_null(JOIN_TAB *tab);
int join_read_next_same_or_null(READ_RECORD *info);
static COND *make_cond_for_table(THD *thd, Item *cond,table_map table,
table_map used_table,
- uint join_tab_idx_arg,
+ int join_tab_idx_arg,
bool exclude_expensive_cond,
bool retain_ref_cond);
static COND *make_cond_for_table_from_pred(THD *thd, Item *root_cond,
Item *cond,
table_map tables,
table_map used_table,
- uint join_tab_idx_arg,
+ int join_tab_idx_arg,
bool exclude_expensive_cond,
bool retain_ref_cond);
@@ -558,7 +558,7 @@ JOIN::prepare(Item ***rref_pointer_array,
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
while ((tbl= li++))
{
- table_count++; /* Count the number of tables in the join. */
+ //table_count++; /* Count the number of tables in the join. */
/*
If the query uses implicit grouping where the select list contains both
aggregate functions and non-aggregate fields, any non-aggregated field
@@ -689,6 +689,10 @@ JOIN::prepare(Item ***rref_pointer_array,
aggregate functions with implicit grouping (there is no GROUP BY).
*/
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && !group_list &&
+ !(select_lex->master_unit()->item &&
+ select_lex->master_unit()->item->is_in_predicate() &&
+ ((Item_in_subselect*)select_lex->master_unit()->item)->
+ test_set_strategy(SUBS_MAXMIN_INJECTED)) &&
select_lex->full_group_by_flag == (NON_AGG_FIELD_USED | SUM_FUNC_USED))
{
my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
@@ -813,7 +817,7 @@ inject_jtbm_conds(JOIN *join, List<TABLE_LIST> *join_list, Item **join_where)
double rows;
double read_time;
- subq_pred->in_strategy &= ~SUBS_IN_TO_EXISTS;
+ DBUG_ASSERT(subq_pred->test_set_strategy(SUBS_MATERIALIZATION));
subq_pred->optimize(&rows, &read_time);
subq_pred->jtbm_read_time= read_time;
@@ -826,6 +830,7 @@ inject_jtbm_conds(JOIN *join, List<TABLE_LIST> *join_list, Item **join_where)
//repeat of convert_subq_to_jtbm:
table->table= hash_sj_engine->tmp_table;
+ table->table->pos_in_table_list= table;
setup_table_map(table->table, table, table->jtbm_table_no);
@@ -864,6 +869,7 @@ JOIN::optimize()
uint no_jbuf_after;
DBUG_ENTER("JOIN::optimize");
+ do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
// to prevent double initialization on EXPLAIN
if (optimized)
DBUG_RETURN(0);
@@ -897,11 +903,10 @@ JOIN::optimize()
/* dump_TABLE_LIST_graph(select_lex, select_lex->leaf_tables); */
select_lex->update_used_tables();
- /* Save this info for the next executions */
- if (select_lex->save_leaf_tables(thd))
- DBUG_RETURN(1);
}
+ eval_select_list_used_tables();
+
table_count= select_lex->leaf_tables.elements;
if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
@@ -913,7 +918,6 @@ JOIN::optimize()
select_limit= unit->select_limit_cnt;
if (having || (select_options & OPTION_FOUND_ROWS))
select_limit= HA_POS_ERROR;
- do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
// Ignore errors of execution if option IGNORE present
if (thd->lex->ignore)
thd->lex->current_select->no_error= 1;
@@ -958,17 +962,22 @@ JOIN::optimize()
/* Convert all outer joins to inner joins if possible */
conds= simplify_joins(this, join_list, conds, TRUE, FALSE);
+ if (select_lex->save_leaf_tables(thd))
+ DBUG_RETURN(1);
build_bitmap_for_nested_joins(join_list, 0);
sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0;
+ sel->where= conds;
+
if (arena)
thd->restore_active_arena(arena, &backup);
}
inject_jtbm_conds(this, join_list, &conds);
- conds= optimize_cond(this, conds, join_list, &cond_value, &cond_equal);
+ conds= optimize_cond(this, conds, join_list, &cond_value, &cond_equal);
+
if (thd->is_error())
{
error= 1;
@@ -985,10 +994,17 @@ JOIN::optimize()
DBUG_RETURN(1);
}
if (select_lex->where)
+ {
select_lex->cond_value= cond_value;
+ if (sel->where != conds && cond_value == Item::COND_OK)
+ thd->change_item_tree(&sel->where, conds);
+ }
if (select_lex->having)
+ {
select_lex->having_value= having_value;
-
+ if (sel->having != having && having_value == Item::COND_OK)
+ thd->change_item_tree(&sel->having, having);
+ }
if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE ||
(!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS)))
{ /* Impossible cond */
@@ -1076,7 +1092,7 @@ JOIN::optimize()
if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
{
COND *table_independent_conds=
- make_cond_for_table(thd, conds, PSEUDO_TABLE_BITS, 0, MAX_TABLES,
+ make_cond_for_table(thd, conds, PSEUDO_TABLE_BITS, 0, -1,
FALSE, FALSE);
DBUG_EXECUTE("where",
print_where(table_independent_conds,
@@ -1164,7 +1180,10 @@ JOIN::optimize()
}
reset_nj_counters(this, join_list);
- make_outerjoin_info(this);
+ if (make_outerjoin_info(this))
+ {
+ DBUG_RETURN(1);
+ }
/*
Among the equal fields belonging to the same multiple equality
@@ -1719,7 +1738,7 @@ int JOIN::init_execution()
if (exec_tmp_table1->distinct)
{
- table_map used_tables= thd->used_tables;
+ table_map used_tables= select_list_used_tables;
JOIN_TAB *last_join_tab= join_tab + top_join_tab_count - 1;
do
{
@@ -2369,7 +2388,6 @@ JOIN::exec()
thd_proc_info(thd, "Copying to group table");
DBUG_PRINT("info", ("%s", thd->proc_info));
- tmp_error= -1;
if (curr_join != this)
{
if (sum_funcs2)
@@ -2394,6 +2412,7 @@ JOIN::exec()
JOIN_TAB *first_tab= curr_join->join_tab + curr_join->const_tables;
first_tab->sorted= test(first_tab->loosescan_match_tab);
}
+ tmp_error= -1;
if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
(tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table,
0)))
@@ -2520,7 +2539,7 @@ JOIN::exec()
Item* sort_table_cond= make_cond_for_table(thd, curr_join->tmp_having,
used_tables,
- (table_map)0, MAX_TABLES,
+ (table_map)0, -1,
FALSE, FALSE);
if (sort_table_cond)
{
@@ -2550,7 +2569,9 @@ JOIN::exec()
if (curr_table->pre_idx_push_select_cond &&
!curr_table->pre_idx_push_select_cond->fixed)
curr_table->pre_idx_push_select_cond->fix_fields(thd, 0);
-
+
+ curr_table->select->pre_idx_push_select_cond=
+ curr_table->pre_idx_push_select_cond;
curr_table->set_select_cond(curr_table->select->cond, __LINE__);
curr_table->select_cond->top_level_item();
DBUG_EXECUTE("where",print_where(curr_table->select->cond,
@@ -2558,7 +2579,7 @@ JOIN::exec()
QT_ORDINARY););
curr_join->tmp_having= make_cond_for_table(thd, curr_join->tmp_having,
~ (table_map) 0,
- ~used_tables, MAX_TABLES,
+ ~used_tables, -1,
FALSE, FALSE);
DBUG_EXECUTE("where",print_where(curr_join->tmp_having,
"having after sort",
@@ -2977,6 +2998,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
uint i,table_count,const_count,key;
table_map found_const_table_map, all_table_map, found_ref, refs;
key_map const_ref, eq_part;
+ bool has_expensive_keyparts;
TABLE **table_vector;
JOIN_TAB *stat,*stat_end,*s,**stat_ref;
KEYUSE *keyuse,*start_keyuse;
@@ -3056,12 +3078,23 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
s->embedding_map|= embedding->nested_join->nj_map;
continue;
}
- if (embedding && !(embedding->sj_on_expr && ! embedding->embedding))
+ if (embedding)
{
/* s belongs to a nested join, maybe to several embedded joins */
s->embedding_map= 0;
+ bool inside_an_outer_join= FALSE;
do
{
+ /*
+ If this is a semi-join nest, skip it, and proceed upwards. Maybe
+ we're in some outer join nest
+ */
+ if (embedding->sj_on_expr)
+ {
+ embedding= embedding->embedding;
+ continue;
+ }
+ inside_an_outer_join= TRUE;
NESTED_JOIN *nested_join= embedding->nested_join;
s->embedding_map|=nested_join->nj_map;
s->dependent|= embedding->dep_tables;
@@ -3069,7 +3102,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
outer_join|= nested_join->used_tables;
}
while (embedding);
- continue;
+ if (inside_an_outer_join)
+ continue;
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
const bool no_partitions_used= table->no_partitions_used;
@@ -3151,7 +3185,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
*/
bool skip_unprefixed_keyparts=
!(join->is_in_subquery() &&
- ((Item_in_subselect*)join->unit->item)->in_strategy & SUBS_IN_TO_EXISTS);
+ ((Item_in_subselect*)join->unit->item)->test_strategy(SUBS_IN_TO_EXISTS));
if (keyuse_array->elements &&
sort_and_filter_keyuse(join->thd, keyuse_array,
@@ -3250,7 +3284,9 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
continue;
if (table->file->stats.records <= 1L &&
(table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
- !table->pos_in_table_list->embedding)
+ !table->pos_in_table_list->embedding &&
+ !((outer_join & table->map) &&
+ (*s->on_expr_ref)->is_expensive()))
{ // system table
int tmp= 0;
s->type=JT_SYSTEM;
@@ -3284,12 +3320,17 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
refs=0;
const_ref.clear_all();
eq_part.clear_all();
+ has_expensive_keyparts= false;
do
{
if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize)
{
if (!((~found_const_table_map) & keyuse->used_tables))
+ {
const_ref.set_bit(keyuse->keypart);
+ if (keyuse->val->is_expensive())
+ has_expensive_keyparts= true;
+ }
else
refs|=keyuse->used_tables;
eq_part.set_bit(keyuse->keypart);
@@ -3310,7 +3351,10 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
{
if (table->key_info[key].flags & HA_NOSAME)
{
- if (const_ref == eq_part)
+ if (const_ref == eq_part &&
+ !has_expensive_keyparts &&
+ !((outer_join & table->map) &&
+ (*s->on_expr_ref)->is_expensive()))
{ // Found everything for ref.
int tmp;
ref_changed = 1;
@@ -3789,7 +3833,9 @@ add_key_field(JOIN *join,
uint optimize= 0;
if (eq_func &&
((join->is_allowed_hash_join_access() &&
- field->hash_join_is_possible()) ||
+ field->hash_join_is_possible() &&
+ !(field->table->pos_in_table_list->is_materialized_derived() &&
+ field->table->created)) ||
(field->table->pos_in_table_list->is_materialized_derived() &&
!field->table->created)))
{
@@ -4745,12 +4791,15 @@ static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
(map= (keyuse->used_tables & ~join->const_table_map &
~OUTER_REF_TABLE_BIT)))
{
- uint tablenr;
- tablenr= my_count_bits(map);
- if (map == 1) // Only one table
+ uint n_tables= my_count_bits(map);
+ if (n_tables == 1) // Only one table
{
+ Table_map_iterator it(map);
+ int tablenr= it.next_bit();
+ DBUG_ASSERT(tablenr != Table_map_iterator::BITMAP_END);
TABLE *tmp_table=join->table[tablenr];
- keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
+ if (tmp_table) // already created
+ keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
}
}
/*
@@ -5136,7 +5185,7 @@ best_access_path(JOIN *join,
tmp= table->file->keyread_time(key, 1, (ha_rows) tmp);
else
tmp= table->file->read_time(key, 1,
- (ha_rows) min(tmp,s->worst_seeks)-1);
+ (ha_rows) min(tmp,s->worst_seeks));
tmp*= record_count;
}
}
@@ -5300,13 +5349,14 @@ best_access_path(JOIN *join,
tmp= table->file->keyread_time(key, 1, (ha_rows) tmp);
else
tmp= table->file->read_time(key, 1,
- (ha_rows) min(tmp,s->worst_seeks)-1);
+ (ha_rows) min(tmp,s->worst_seeks));
tmp*= record_count;
}
else
tmp= best_time; // Do nothing
}
+ DBUG_ASSERT(tmp > 0 || record_count == 0);
tmp += s->startup_cost;
loose_scan_opt.check_ref_access_part2(key, start_key, records, tmp);
} /* not ft_key */
@@ -5342,7 +5392,7 @@ best_access_path(JOIN *join,
/* Estimate the cost of the hash join access to the table */
ha_rows rnd_records= matching_candidates_in_table(s, found_constraint);
- tmp= s->quick ? s->quick->read_time : s->table->file->scan_time();
+ tmp= s->quick ? s->quick->read_time : s->scan_time();
tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
/* We read the table as many times as join buffer becomes full. */
@@ -6006,7 +6056,7 @@ greedy_search(JOIN *join,
read_time_arg and record_count_arg contain the computed cost and fanout
*/
-void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
+void JOIN::get_partial_cost_and_fanout(int end_tab_idx,
table_map filter_map,
double *read_time_arg,
double *record_count_arg)
@@ -6016,14 +6066,14 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
double sj_inner_fanout= 1.0;
JOIN_TAB *end_tab= NULL;
JOIN_TAB *tab;
- uint i;
- uint last_sj_table= MAX_TABLES;
+ int i;
+ int last_sj_table= MAX_TABLES;
/*
Handle a special case where the join is degenerate, and produces no
records
*/
- if (table_count == 0)
+ if (table_count == const_tables)
{
*read_time_arg= 0.0;
/*
@@ -6033,6 +6083,7 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
calculations.
*/
*record_count_arg=1.0;
+ return;
}
for (tab= first_depth_first_tab(this), i= const_tables;
@@ -6045,19 +6096,17 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
}
for (tab= first_depth_first_tab(this), i= const_tables;
- tab;
+ ;
tab= next_depth_first_tab(this, tab), i++)
{
- /*
- We've entered the SJM nest that contains the end_tab. The caller is
- actually
- - interested in fanout inside the nest (because that's how many times
- we'll invoke the attached WHERE conditions)
- - not interested in cost
- */
if (end_tab->bush_root_tab && end_tab->bush_root_tab == tab)
{
- /* Ok, end_tab is inside SJM nest and we're entering that nest now */
+ /*
+ We've entered the SJM nest that contains the end_tab. The caller is
+ - interested in fanout inside the nest (because that's how many times
+ we'll invoke the attached WHERE conditions)
+ - not interested in cost
+ */
record_count= 1.0;
read_time= 0.0;
}
@@ -6071,8 +6120,18 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
sj_inner_fanout= 1.0;
last_sj_table= i + tab->n_sj_tables;
}
-
- if (tab->records_read && (tab->table->map & filter_map))
+
+ table_map cur_table_map;
+ if (tab->table)
+ cur_table_map= tab->table->map;
+ else
+ {
+ /* This is a SJ-Materialization nest. Check all of its tables */
+ TABLE *first_child= tab->bush_children->start->table;
+ TABLE_LIST *sjm_nest= first_child->pos_in_table_list->embedding;
+ cur_table_map= sjm_nest->nested_join->used_tables;
+ }
+ if (tab->records_read && (cur_table_map & filter_map))
{
record_count *= tab->records_read;
read_time += tab->read_time;
@@ -6086,6 +6145,9 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
sj_inner_fanout= 1.0;
last_sj_table= MAX_TABLES;
}
+
+ if (tab == end_tab)
+ break;
}
*read_time_arg= read_time;// + record_count / TIME_FOR_COMPARE;
*record_count_arg= record_count;
@@ -6491,7 +6553,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
void JOIN_TAB::calc_used_field_length(bool max_fl)
{
- uint null_fields,blobs,fields,rec_length;
+ uint null_fields,blobs,fields;
+ ulong rec_length;
Field **f_ptr,*field;
uint uneven_bit_fields;
MY_BITMAP *read_set= table->read_set;
@@ -6517,24 +6580,32 @@ void JOIN_TAB::calc_used_field_length(bool max_fl)
rec_length+=(table->s->null_fields+7)/8;
if (table->maybe_null)
rec_length+=sizeof(my_bool);
+
+ /* Take into account that DuplicateElimination may need to store rowid */
+ uint rowid_add_size= 0;
+ if (keep_current_rowid)
+ {
+ rowid_add_size= table->file->ref_length;
+ rec_length += rowid_add_size;
+ fields++;
+ }
+
if (max_fl)
{
// TODO: to improve this estimate for max expected length
if (blobs)
{
- uint blob_length=(uint) (table->file->stats.mean_rec_length-
- (table->s->reclength-rec_length));
- rec_length+=(uint) max(sizeof(void*) * blobs, blob_length);
+ ulong blob_length= table->file->stats.mean_rec_length;
+ if (ULONG_MAX - rec_length > blob_length)
+ rec_length+= blob_length;
+ else
+ rec_length= ULONG_MAX;
}
max_used_fieldlength= rec_length;
}
- else if (table->file->stats.mean_rec_length)
- set_if_smaller(rec_length, table->file->stats.mean_rec_length);
+ else if (table->file->stats.mean_rec_length)
+ set_if_smaller(rec_length, table->file->stats.mean_rec_length + rowid_add_size);
- /*
- TODO: why we don't count here rowid that we might need to store when
- using DuplicateElimination?
- */
used_fields=fields;
used_fieldlength=rec_length;
used_blobs=blobs;
@@ -6571,7 +6642,7 @@ int JOIN_TAB::make_scan_filter()
if (cond &&
(tmp= make_cond_for_table(join->thd, cond,
join->const_table_map | table->map,
- table->map, MAX_TABLES, FALSE, TRUE)))
+ table->map, -1, FALSE, TRUE)))
{
DBUG_EXECUTE("where",print_where(tmp,"cache", QT_ORDINARY););
if (!(cache_select=
@@ -7043,6 +7114,7 @@ get_best_combination(JOIN *join)
goto loop_end; // Handled in make_join_stat..
j->loosescan_match_tab= NULL; //non-nulls will be set later
+ j->inside_loosescan_range= FALSE;
j->ref.key = -1;
j->ref.key_parts=0;
@@ -7150,7 +7222,8 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
(first_keyuse || keyuse->keypart != (keyuse-1)->keypart))
{
Field *field= table->field[keyuse->keypart];
- table->create_key_part_by_field(keyinfo, key_part_info, field);
+ uint fieldnr= keyuse->keypart+1;
+ table->create_key_part_by_field(keyinfo, key_part_info, field, fieldnr);
first_keyuse= FALSE;
key_part_info++;
}
@@ -7162,6 +7235,33 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
DBUG_RETURN(FALSE);
}
+/*
+ Check if a set of tables specified by used_tables can be accessed when
+ we're doing scan on join_tab jtab.
+*/
+static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables)
+{
+ if (jtab->bush_root_tab)
+ {
+ /*
+ jtab is inside execution join nest. We may not refer to outside tables,
+ except the const tables.
+ */
+ table_map local_tables= jtab->emb_sj_nest->nested_join->used_tables |
+ jtab->join->const_table_map |
+ OUTER_REF_TABLE_BIT;
+ return !test(used_tables & ~local_tables);
+ }
+
+ /*
+ If we got here then jtab is at top level.
+ - all other tables at top level are accessible,
+ - tables in join nests are accessible too, because all their columns that
+ are needed at top level will be unpacked when scanning the
+ materialization table.
+ */
+ return TRUE;
+}
static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
KEYUSE *org_keyuse, table_map used_tables)
@@ -7207,14 +7307,17 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
{
if (!(~used_tables & keyuse->used_tables))
{
- if ((is_hash_join_key_no(key) &&
- (keyparts == 0 || keyuse->keypart != (keyuse-1)->keypart)) ||
- (!is_hash_join_key_no(key) && keyparts == keyuse->keypart &&
- !(found_part_ref_or_null & keyuse->optimize)))
+ if (are_tables_local(j, keyuse->val->used_tables()))
{
- length+= keyinfo->key_part[keyparts].store_length;
- keyparts++;
- found_part_ref_or_null|= keyuse->optimize & ~KEY_OPTIMIZE_EQ;
+ if ((is_hash_join_key_no(key) &&
+ (keyparts == 0 || keyuse->keypart != (keyuse-1)->keypart)) ||
+ (!is_hash_join_key_no(key) && keyparts == keyuse->keypart &&
+ !(found_part_ref_or_null & keyuse->optimize)))
+ {
+ length+= keyinfo->key_part[keyparts].store_length;
+ keyparts++;
+ found_part_ref_or_null|= keyuse->optimize & ~KEY_OPTIMIZE_EQ;
+ }
}
}
keyuse++;
@@ -7263,7 +7366,8 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
while (((~used_tables) & keyuse->used_tables) ||
(keyuse->keypart !=
(is_hash_join_key_no(key) ?
- keyinfo->key_part[i].field->field_index : i)))
+ keyinfo->key_part[i].field->field_index : i)) ||
+ !are_tables_local(j, keyuse->val->used_tables()))
keyuse++; /* Skip other parts */
uint maybe_null= test(keyinfo->key_part[i].null_bit);
@@ -7360,7 +7464,7 @@ get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
maybe_null ? key_buff : 0,
key_part->length,
((Item_field*) keyuse->val->real_item())->field,
- keyuse->val->full_name());
+ keyuse->val->real_item()->full_name());
return new store_key_item(thd,
key_part->field,
key_buff + maybe_null,
@@ -7620,6 +7724,12 @@ static void add_not_null_conds(JOIN *join)
nested outer join and so on until it reaches root_tab
(root_tab can be 0).
+ In other words:
+ add_found_match_trig_cond(tab->first_inner_tab, y, 0) is the way one should
+ wrap parts of WHERE. The idea is that the part of WHERE should be only
+ evaluated after we've finished figuring out whether outer joins.
+ ^^^ is the above correct?
+
@param tab the first inner table for most nested outer join
@param cond the predicate to be guarded (must be set)
@param root_tab the first inner table to stop
@@ -7647,6 +7757,12 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
}
+bool TABLE_LIST::is_active_sjm()
+{
+ return sj_mat_info && sj_mat_info->is_used;
+}
+
+
/**
Fill in outer join related info for the execution plan structure.
@@ -7664,6 +7780,12 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
corresponding first inner table through the field t0->on_expr_ref.
Here ti are structures of the JOIN_TAB type.
+ In other words, for each join tab, set
+ - first_inner
+ - last_inner
+ - first_upper
+ - on_expr_ref, cond_equal
+
EXAMPLE. For the query:
@code
SELECT * FROM t1
@@ -7689,20 +7811,33 @@ add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
has been chosen.
*/
-static void
+static bool
make_outerjoin_info(JOIN *join)
{
DBUG_ENTER("make_outerjoin_info");
+
+ /*
+ Create temp. tables for merged SJ-Materialization nests. We need to do
+ this now, because further code relies on tab->table and
+ tab->table->pos_in_table_list being set.
+ */
+ JOIN_TAB *tab;
+ for (tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
+ tab;
+ tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
+ {
+ if (tab->bush_children)
+ {
+ if (setup_sj_materialization_part1(tab))
+ DBUG_RETURN(TRUE);
+ tab->table->reginfo.join_tab= tab;
+ }
+ }
+
for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES); tab;
- tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
+ tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
{
- TABLE *table=tab->table;
- /*
- psergey: The following is probably incorrect, fix it when we get
- semi+outer joins processing to work:
- */
- if (!table)
- continue;
+ TABLE *table= tab->table;
TABLE_LIST *tbl= table->pos_in_table_list;
TABLE_LIST *embedding= tbl->embedding;
@@ -7716,11 +7851,16 @@ make_outerjoin_info(JOIN *join)
tab->last_inner= tab->first_inner= tab;
tab->on_expr_ref= &tbl->on_expr;
tab->cond_equal= tbl->cond_equal;
- if (embedding)
+ if (embedding && !embedding->is_active_sjm())
tab->first_upper= embedding->nested_join->first_nested;
}
for ( ; embedding ; embedding= embedding->embedding)
{
+ if (embedding->is_active_sjm())
+ {
+ /* We're trying to walk out of an SJ-Materialization nest. Don't do this. */
+ break;
+ }
/* Ignore sj-nests: */
if (!(embedding->on_expr && embedding->outer_join))
continue;
@@ -7752,7 +7892,7 @@ make_outerjoin_info(JOIN *join)
}
}
}
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -7791,7 +7931,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
join->exec_const_cond=
make_cond_for_table(thd, cond,
join->const_table_map,
- (table_map) 0, MAX_TABLES, FALSE, FALSE);
+ (table_map) 0, -1, FALSE, FALSE);
/* Add conditions added by add_not_null_conds(). */
for (uint i= 0 ; i < join->const_tables ; i++)
add_cond_and_fix(thd, &join->exec_const_cond,
@@ -7810,7 +7950,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
COND *outer_ref_cond= make_cond_for_table(thd, cond,
OUTER_REF_TABLE_BIT,
OUTER_REF_TABLE_BIT,
- MAX_TABLES, FALSE, FALSE);
+ -1, FALSE, FALSE);
if (outer_ref_cond)
{
add_cond_and_fix(thd, &outer_ref_cond, join->outer_ref_cond);
@@ -7838,7 +7978,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
*/
JOIN_TAB *first_inner_tab= tab->first_inner;
- if (tab->table)
+ if (!tab->bush_children)
current_map= tab->table->map;
else
current_map= tab->bush_children->start->emb_sj_nest->sj_inner_tables;
@@ -7980,7 +8120,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
{
COND *push_cond=
make_cond_for_table(thd, tmp, current_map, current_map,
- MAX_TABLES, FALSE, FALSE);
+ -1, FALSE, FALSE);
if (push_cond)
{
/* Push condition to handler */
@@ -8127,17 +8267,32 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
the null complemented row.
*/
- /* First push down constant conditions from on expressions */
- for (JOIN_TAB *join_tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
- join_tab;
- join_tab= next_linear_tab(join, join_tab, WITH_BUSH_ROOTS))
+ /*
+ First push down constant conditions from ON expressions.
+ - Each pushed-down condition is wrapped into trigger which is
+ enabled only for non-NULL-complemented record
+ - The condition is attached to the first_inner_table.
+
+ With regards to join nests:
+ - if we start at top level, don't walk into nests
+ - if we start inside a nest, stay within that nest.
+ */
+ JOIN_TAB *start_from= tab->bush_root_tab?
+ tab->bush_root_tab->bush_children->start :
+ join->join_tab + join->const_tables;
+ JOIN_TAB *end_with= tab->bush_root_tab?
+ tab->bush_root_tab->bush_children->end :
+ join->join_tab + join->top_join_tab_count;
+ for (JOIN_TAB *join_tab= start_from;
+ join_tab != end_with;
+ join_tab++)
{
if (*join_tab->on_expr_ref)
{
JOIN_TAB *cond_tab= join_tab->first_inner;
COND *tmp= make_cond_for_table(thd, *join_tab->on_expr_ref,
join->const_table_map,
- (table_map) 0, MAX_TABLES, FALSE, FALSE);
+ (table_map) 0, -1, FALSE, FALSE);
if (!tmp)
continue;
tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
@@ -8155,9 +8310,14 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
}
}
+
/* Push down non-constant conditions from ON expressions */
- //JOIN_TAB *first_tab= join->join_tab+join->const_tables;
JOIN_TAB *last_tab= tab;
+
+ /*
+ while we're inside of an outer join and last_tab is
+ the last of its tables ...
+ */
while (first_inner_tab && first_inner_tab->last_inner == last_tab)
{
/*
@@ -8168,26 +8328,20 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
table_map used_tables2= (join->const_table_map |
OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
- for (JOIN_TAB *tab= first_linear_tab(join, WITHOUT_CONST_TABLES);
- tab;
- tab= (tab == last_tab)? NULL: next_linear_tab(join, tab,
- WITH_BUSH_ROOTS))
+
+ start_from= tab->bush_root_tab?
+ tab->bush_root_tab->bush_children->start :
+ join->join_tab + join->const_tables;
+ for (JOIN_TAB *tab= start_from; tab <= last_tab; tab++)
{
- if (!tab->table)
- {
- /*
- psergey-todo: this is probably incorrect, fix this when we get
- correct processing for outer joins + semi joins
- */
- continue;
- }
+ DBUG_ASSERT(tab->table);
current_map= tab->table->map;
used_tables2|= current_map;
/*
- psergey: have put the MAX_TABLES below. It's bad, will need to fix it.
+ psergey: have put the -1 below. It's bad, will need to fix it.
*/
COND *tmp_cond= make_cond_for_table(thd, on_expr, used_tables2,
- current_map, /*(tab - first_tab)*/ MAX_TABLES,
+ current_map, /*(tab - first_tab)*/ -1,
FALSE, FALSE);
if (tab == first_inner_tab && tab->on_precond)
add_cond_and_fix(thd, &tmp_cond, tab->on_precond);
@@ -8257,6 +8411,7 @@ uint get_next_field_for_derived_key(uchar *arg)
keyuse->keypart= keypart;
if (keyuse->key != key)
keyuse= 0;
+ *((KEYUSE **) arg)= keyuse;
return fldno;
}
@@ -8267,34 +8422,43 @@ bool generate_derived_keys_for_table(KEYUSE *keyuse, uint count, uint keys)
TABLE *table= keyuse->table;
if (table->alloc_keys(keys))
return TRUE;
- uint keyno= 0;
+ uint key_count= 0;
KEYUSE *first_keyuse= keyuse;
- uint prev_part= (uint) (-1);
+ uint prev_part= keyuse->keypart;
uint parts= 0;
uint i= 0;
- do
+
+ for ( ; i < count && key_count < keys; )
{
- keyuse->key= keyno;
- keyuse->keypart_map= (key_part_map) (1 << parts);
- keyuse++;
- if (++i == count || keyuse->used_tables != first_keyuse->used_tables)
+ do
{
- if (table->add_tmp_key(keyno, ++parts,
+ keyuse->key= table->s->keys;
+ keyuse->keypart_map= (key_part_map) (1 << parts);
+ keyuse++;
+ i++;
+ }
+ while (i < count && keyuse->used_tables == first_keyuse->used_tables &&
+ keyuse->keypart == prev_part);
+ parts++;
+ if (i < count && keyuse->used_tables == first_keyuse->used_tables)
+ {
+ prev_part= keyuse->keypart;
+ }
+ else
+ {
+ if (table->add_tmp_key(table->s->keys, parts,
get_next_field_for_derived_key,
(uchar *) &first_keyuse,
FALSE))
return TRUE;
- table->reginfo.join_tab->keys.set_bit(keyno);
+ table->reginfo.join_tab->keys.set_bit(table->s->keys);
first_keyuse= keyuse;
- keyno++;
+ key_count++;
parts= 0;
- }
- else if (keyuse->keypart != prev_part)
- {
- parts++;
prev_part= keyuse->keypart;
}
- } while (keyno < keys);
+ }
+
return FALSE;
}
@@ -8316,12 +8480,23 @@ bool generate_derived_keys(DYNAMIC_ARRAY *keyuse_array)
TABLE_LIST *derived= NULL;
if (keyuse->table != prev_table)
derived= keyuse->table->pos_in_table_list;
- while (derived && derived->is_materialized_derived() &&
- keyuse->key == MAX_KEY)
+ while (derived && derived->is_materialized_derived())
{
if (keyuse->table != prev_table)
{
prev_table= keyuse->table;
+ while (keyuse->table == prev_table && keyuse->key != MAX_KEY)
+ {
+ keyuse++;
+ i++;
+ }
+ if (keyuse->table != prev_table)
+ {
+ keyuse--;
+ i--;
+ derived= NULL;
+ continue;
+ }
first_table_keyuse= keyuse;
last_used_tables= keyuse->used_tables;
count= 0;
@@ -8334,11 +8509,13 @@ bool generate_derived_keys(DYNAMIC_ARRAY *keyuse_array)
}
count++;
keyuse++;
+ i++;
if (keyuse->table != prev_table)
{
if (generate_derived_keys_for_table(first_table_keyuse, count, ++keys))
return TRUE;
keyuse--;
+ i--;
derived= NULL;
}
}
@@ -8369,14 +8546,40 @@ void JOIN::drop_unused_derived_keys()
TABLE *table=tab->table;
if (!table)
continue;
- if (!table->pos_in_table_list->is_materialized_derived() ||
- table->max_keys <= 1)
+ if (!table->pos_in_table_list->is_materialized_derived())
continue;
- table->use_index(tab->ref.key);
- tab->ref.key= 0;
+ if (table->max_keys > 1)
+ table->use_index(tab->ref.key);
+ if (table->s->keys && tab->ref.key >= 0)
+ tab->ref.key= 0;
+ tab->keys= (key_map) (table->s->keys ? 1 : 0);
}
}
+
+/*
+ Evaluate the bitmap of used tables for items from the select list
+*/
+
+inline void JOIN::eval_select_list_used_tables()
+{
+ select_list_used_tables= 0;
+ Item *item;
+ List_iterator_fast<Item> it(fields_list);
+ while ((item= it++))
+ {
+ select_list_used_tables|= item->used_tables();
+ }
+ Item_outer_ref *ref;
+ List_iterator_fast<Item_outer_ref> ref_it(select_lex->inner_refs_list);
+ while ((ref= ref_it++))
+ {
+ item= ref->outer_ref;
+ select_list_used_tables|= item->used_tables();
+ }
+}
+
+
/*
Determine {after which table we'll produce ordered set}
@@ -8478,7 +8681,7 @@ void set_join_cache_denial(JOIN_TAB *join_tab)
void rr_unlock_row(st_join_table *tab)
{
READ_RECORD *info= &tab->read_record;
- info->file->unlock_row();
+ info->table->file->unlock_row();
}
@@ -8812,6 +9015,15 @@ uint check_join_cache_usage(JOIN_TAB *tab,
if (tab->use_quick == 2)
goto no_join_cache;
+
+ /*
+ Don't use join cache if we're inside a join tab range covered by LooseScan
+ strategy (TODO: LooseScan is very similar to FirstMatch so theoretically it
+ should be possible to use join buffering in the same way we're using it for
+ multi-table firstmatch ranges).
+ */
+ if (tab->inside_loosescan_range)
+ goto no_join_cache;
if (tab->is_inner_table_of_semi_join_with_first_match() &&
!join->allowed_semijoin_with_cache)
@@ -8893,6 +9105,9 @@ uint check_join_cache_usage(JOIN_TAB *tab,
case JT_EQ_REF:
if (cache_level <=2 || (no_hashed_cache && no_bka_cache))
goto no_join_cache;
+ if (tab->ref.is_access_triggered())
+ goto no_join_cache;
+
if (!tab->is_ref_for_hash_join())
{
flags= HA_MRR_NO_NULL_ENDPOINTS | HA_MRR_SINGLE_POINT;
@@ -9131,14 +9346,13 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
{
if (tab->bush_children)
{
- if (setup_sj_materialization(tab))
+ if (setup_sj_materialization_part2(tab))
return TRUE;
}
TABLE *table=tab->table;
uint jcl= tab->used_join_cache_level;
tab->read_record.table= table;
- tab->read_record.file=table->file;
tab->read_record.unlock_row= rr_unlock_row;
tab->sorted= sorted;
sorted= 0; // only first must be sorted
@@ -9184,9 +9398,9 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
- else if (!jcl || jcl > 4)
+ else if ((!jcl || jcl > 4) && !tab->ref.is_access_triggered())
push_index_cond(tab, tab->ref.key);
- break;
+ break;
case JT_EQ_REF:
tab->read_record.unlock_row= join_read_key_unlock_row;
/* fall through */
@@ -9196,7 +9410,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
- else if (!jcl || jcl > 4)
+ else if ((!jcl || jcl > 4) && !tab->ref.is_access_triggered())
push_index_cond(tab, tab->ref.key);
break;
case JT_REF_OR_NULL:
@@ -9211,7 +9425,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
table->enable_keyread();
- else if (!jcl || jcl > 4)
+ else if ((!jcl || jcl > 4) && !tab->ref.is_access_triggered())
push_index_cond(tab, tab->ref.key);
break;
case JT_ALL:
@@ -9420,7 +9634,6 @@ void JOIN_TAB::cleanup()
table->pos_in_table_list->jtbm_subselect)
{
end_read_record(&read_record);
- //psergey-merge:
table->pos_in_table_list->jtbm_subselect->cleanup();
DBUG_VOID_RETURN;
}
@@ -9465,7 +9678,7 @@ double JOIN_TAB::scan_time()
else
{
found_records= records=table->file->stats.records;
- read_time= found_records ? found_records: 10;// TODO:fix this stub
+ read_time= found_records ? (double)found_records: 10.0;// TODO:fix this stub
res= read_time;
}
return res;
@@ -9474,6 +9687,8 @@ double JOIN_TAB::scan_time()
/**
Initialize the join_tab before reading.
Currently only derived table/view materialization is done here.
+
+ TODO: consider moving this together with join_tab_execution_startup
*/
bool JOIN_TAB::preread_init()
{
@@ -9490,6 +9705,8 @@ bool JOIN_TAB::preread_init()
derived, DT_CREATE | DT_FILL))
return TRUE;
preread_init_done= TRUE;
+ if (select && select->quick)
+ select->quick->replace_handler(table->file);
return FALSE;
}
@@ -9501,6 +9718,7 @@ bool JOIN_TAB::preread_init()
@param thd Thread handle
@param tmp_key The temporary table key
@param it The iterator of items for lookup in the key
+ @param skip Number of fields from the beginning to skip
@details
Build TABLE_REF object for lookup in the key 'tmp_key' using items
@@ -9513,9 +9731,11 @@ bool JOIN_TAB::preread_init()
bool TABLE_REF::tmp_table_index_lookup_init(THD *thd,
KEY *tmp_key,
Item_iterator &it,
- bool value)
+ bool value,
+ uint skip)
{
uint tmp_key_parts= tmp_key->key_parts;
+ uint i;
DBUG_ENTER("TABLE_REF::tmp_table_index_lookup_init");
key= 0; /* The only temp table index. */
@@ -9536,7 +9756,8 @@ bool TABLE_REF::tmp_table_index_lookup_init(THD *thd,
uchar *cur_ref_buff= key_buff;
it.open();
- for (uint i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
+ for (i= 0; i < skip; i++) it.next();
+ for (i= 0; i < tmp_key_parts; i++, cur_key_part++, ref_key++)
{
Item *item= it.next();
DBUG_ASSERT(item);
@@ -9561,6 +9782,22 @@ bool TABLE_REF::tmp_table_index_lookup_init(THD *thd,
}
+/*
+ Check if ref access uses "Full scan on NULL key" (i.e. it actually alternates
+ between ref access and full table scan)
+*/
+
+bool TABLE_REF::is_access_triggered()
+{
+ for (uint i = 0; i < key_parts; i++)
+ {
+ if (cond_guards[i])
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
/**
Partially cleanup JOIN after it has executed: close index or rnd read
(table cursors), free quick selects.
@@ -9612,8 +9849,7 @@ void JOIN::join_free()
Optimization: if not EXPLAIN and we are done with the JOIN,
free all tables.
*/
- bool full= (!(select_lex->uncacheable) &&
- !thd->lex->describe);
+ bool full= !(select_lex->uncacheable);
bool can_unlock= full;
DBUG_ENTER("JOIN::join_free");
@@ -10031,7 +10267,9 @@ return_zero_rows(JOIN *join, select_result *result, List<TABLE_LIST> &tables,
TABLE_LIST *table;
while ((table= ti++))
mark_as_null_row(table->table); // All fields are NULL
- if (having && having->val_int() == 0)
+ if (having &&
+ !having->walk(&Item::clear_sum_processor, FALSE, NULL) &&
+ having->val_int() == 0)
send_row=0;
}
if (!(result->send_fields(fields,
@@ -10334,7 +10572,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
!((Item_field*)left_item)->get_depended_from() &&
right_item->const_item() && !right_item->is_expensive())
{
- orig_field_item= left_item;
+ orig_field_item= orig_left_item;
field_item= (Item_field *) left_item;
const_item= right_item;
}
@@ -10342,7 +10580,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item,
!((Item_field*)right_item)->get_depended_from() &&
left_item->const_item() && !left_item->is_expensive())
{
- orig_field_item= right_item;
+ orig_field_item= orig_right_item;
field_item= (Item_field *) right_item;
const_item= left_item;
}
@@ -11464,10 +11702,10 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
{
Item_func_eq *func=(Item_func_eq*) cond;
Item **args= func->arguments();
- bool left_const= args[0]->const_item();
- bool right_const= args[1]->const_item();
+ bool left_const= args[0]->const_item() && !args[0]->is_expensive();
+ bool right_const= args[1]->const_item() && !args[1]->is_expensive();
if (!(left_const && right_const) &&
- args[0]->result_type() == args[1]->result_type())
+ args[0]->cmp_type() == args[1]->cmp_type())
{
if (right_const)
{
@@ -11778,6 +12016,18 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top,
leave it intact (otherwise it is flattened)
*/
join->select_lex->sj_nests.push_back(table);
+
+ /*
+ Also, walk through semi-join children and mark those that are now
+ top-level
+ */
+ TABLE_LIST *tbl;
+ List_iterator<TABLE_LIST> it(nested_join->join_list);
+ while ((tbl= it++))
+ {
+ if (!tbl->on_expr && tbl->table)
+ tbl->table->maybe_null= FALSE;
+ }
}
else if (nested_join && !table->on_expr)
{
@@ -11888,8 +12138,8 @@ static uint reset_nj_counters(JOIN *join, List<TABLE_LIST> *join_list)
if (!nested_join->n_tables)
is_eliminated_nest= TRUE;
}
- if ((!table->table && !is_eliminated_nest) ||
- (table->table && (table->table->map & ~join->eliminated_tables)))
+ if ((table->nested_join && !is_eliminated_nest) ||
+ (!table->nested_join && (table->table->map & ~join->eliminated_tables)))
n++;
}
DBUG_RETURN(n);
@@ -12771,8 +13021,9 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
If item have to be able to store NULLs but underlaid field can't do it,
create_tmp_field_from_field() can't be used for tmp field creation.
*/
- if (((field->maybe_null && field->in_rollup) ||
- (orig_item && orig_item->maybe_null)) && /* for outer joined views/dt*/
+ if (((field->maybe_null && field->in_rollup) ||
+ (thd->create_tmp_table_for_derived && /* for mat. view/dt */
+ orig_item && orig_item->maybe_null)) &&
!field->field->maybe_null())
{
bool save_maybe_null= FALSE;
@@ -12944,7 +13195,7 @@ void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps)
*/
TABLE *
-create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
+create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
ORDER *group, bool distinct, bool save_sum_fields,
ulonglong select_options, ha_rows rows_limit,
char *table_alias, bool do_not_open)
@@ -12962,7 +13213,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
bool using_unique_constraint= 0;
bool use_packed_rows= 0;
bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
- char *tmpname,path[FN_REFLEN], tmp_table_name[50];
+ char *tmpname,path[FN_REFLEN];
uchar *pos, *group_buff, *bitmaps;
uchar *null_flags;
Field **reg_field, **from_field, **default_field;
@@ -12993,12 +13244,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
temp_pool_slot = bitmap_lock_set_next(&temp_pool);
if (temp_pool_slot != MY_BIT_NONE) // we got a slot
- sprintf(tmp_table_name, "%s_%lx_%i", tmp_file_prefix,
+ sprintf(path, "%s_%lx_%i", tmp_file_prefix,
current_pid, temp_pool_slot);
else
{
/* if we run out of slots or we are not using tempool */
- sprintf(tmp_table_name, "%s%lx_%lx_%x", tmp_file_prefix,current_pid,
+ sprintf(path, "%s%lx_%lx_%x", tmp_file_prefix,current_pid,
thd->thread_id, thd->tmp_table++);
}
@@ -13006,7 +13257,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
No need to change table name to lower case as we are only creating
MyISAM, Aria or HEAP tables here
*/
- fn_format(path, tmp_table_name, mysql_tmpdir, "",
+ fn_format(path, path, mysql_tmpdir, "",
MY_REPLACE_EXT|MY_UNPACK_FILENAME);
if (group)
@@ -13059,7 +13310,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
sizeof(*key_part_info)*(param->group_parts+1),
&param->start_recinfo,
sizeof(*param->recinfo)*(field_count*2+4),
- &tmpname, (uint) strlen(tmp_table_name)+1,
+ &tmpname, (uint) strlen(path)+1,
&group_buff, (group && ! using_unique_constraint ?
param->group_length : 0),
&bitmaps, bitmap_buffer_size(field_count)*4,
@@ -13078,7 +13329,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
DBUG_RETURN(NULL); /* purecov: inspected */
}
param->items_to_copy= copy_func;
- strmov(tmpname, tmp_table_name);
+ strmov(tmpname, path);
/* make table according to fields */
bzero((char*) table,sizeof(*table));
@@ -13310,6 +13561,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*reg_field= 0;
*blob_field= 0; // End marker
share->fields= field_count;
+ share->column_bitmap_size= bitmap_buffer_size(share->fields);
/* If result table is small; use a heap */
/* future: storage engine selection can be made dynamic? */
@@ -13535,6 +13787,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
bool maybe_null=(*cur_group->item)->maybe_null;
key_part_info->null_bit=0;
key_part_info->field= field;
+ key_part_info->fieldnr= field->field_index + 1;
if (cur_group == group)
field->key_start.set_bit(0);
key_part_info->offset= field->offset(table->record[0]);
@@ -13545,15 +13798,30 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
(ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
0 : FIELDFLAG_BINARY;
+
if (!using_unique_constraint)
{
cur_group->buff=(char*) group_buff;
+
+ if (maybe_null && !field->null_bit)
+ {
+ /*
+ This can only happen in the unusual case where an outer join
+ table was found to be not-nullable by the optimizer and we
+ the item can't really be null.
+ We solve this by marking the item as !maybe_null to ensure
+ that the key,field and item definition match.
+ */
+ (*cur_group->item)->maybe_null= maybe_null= 0;
+ }
+
if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
group_buff +
test(maybe_null),
field->null_ptr,
field->null_bit)))
goto err; /* purecov: inspected */
+
if (maybe_null)
{
/*
@@ -13575,6 +13843,12 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
}
keyinfo->key_length+= key_part_info->length;
}
+ /*
+ Ensure we didn't overrun the group buffer. The < is only true when
+ some maybe_null fields was changed to be not null fields.
+ */
+ DBUG_ASSERT(using_unique_constraint ||
+ group_buff <= param->group_buff + param->group_length);
}
if (distinct && field_count != param->hidden_field_count)
@@ -13637,6 +13911,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
key_part_info->field->init(table);
key_part_info->key_type=FIELDFLAG_BINARY;
key_part_info->type= HA_KEYTYPE_BINARY;
+ key_part_info->fieldnr= key_part_info->field->field_index + 1;
key_part_info++;
}
/* Create a distinct key over the columns we are going to return */
@@ -13654,6 +13929,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
key_part_info->offset= (*reg_field)->offset(table->record[0]);
key_part_info->length= (uint16) (*reg_field)->pack_length();
+ key_part_info->fieldnr= (*reg_field)->field_index + 1;
/* TODO:
The below method of computing the key format length of the
key part is a copy/paste from opt_range.cc, and table.cc.
@@ -13917,6 +14193,13 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
keyinfo->key_parts > table->file->max_key_parts() ||
share->uniques)
{
+ if (!share->uniques && !(keyinfo->flags & HA_NOSAME))
+ {
+ my_error(ER_INTERNAL_ERROR, MYF(0),
+ "Using too big key for internal temp tables");
+ DBUG_RETURN(1);
+ }
+
/* Can't create a key; Make a unique constraint instead of a key */
share->keys= 0;
share->uniques= 1;
@@ -13935,9 +14218,9 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
}
else
{
- /* Create an unique key */
+ /* Create a key */
bzero((char*) &keydef,sizeof(keydef));
- keydef.flag=HA_NOSAME;
+ keydef.flag= keyinfo->flags & HA_NOSAME;
keydef.keysegs= keyinfo->key_parts;
keydef.seg= seg;
}
@@ -14113,7 +14396,8 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
{
/* Create an unique key */
bzero((char*) &keydef,sizeof(keydef));
- keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
+ keydef.flag= ((keyinfo->flags & HA_NOSAME) | HA_BINARY_PACK_KEY |
+ HA_PACK_KEY);
keydef.keysegs= keyinfo->key_parts;
keydef.seg= seg;
}
@@ -14297,7 +14581,7 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
/* remove heap table and change to use myisam table */
(void) table->file->ha_rnd_end();
- (void) table->file->close(); // This deletes the table !
+ (void) table->file->ha_close(); // This deletes the table !
delete table->file;
table->file=0;
plugin_unlock(0, table->s->db_plugin);
@@ -14318,7 +14602,7 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
table->file->print_error(write_err, MYF(0));
err_killed:
(void) table->file->ha_rnd_end();
- (void) new_table.file->close();
+ (void) new_table.file->ha_close();
err1:
new_table.file->ha_delete_table(new_table.s->table_name.str);
err2:
@@ -14518,14 +14802,6 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{
List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
fields);
- /*
- With implicit grouping all fields of special row produced for an
- empty result are NULL. See return_zero_rows() for the same behavior.
- */
- TABLE_LIST *table;
- List_iterator_fast<TABLE_LIST> li(join->select_lex->leaf_tables);
- while ((table= li++))
- mark_as_null_row(table->table);
rc= join->result->send_data(*columns_list) > 0;
}
}
@@ -14642,10 +14918,12 @@ sub_select_cache(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
{
enum_nested_loop_state rc;
JOIN_CACHE *cache= join_tab->cache;
-
DBUG_ENTER("sub_select_cache");
- /* This function cannot be called if join_tab has no associated join buffer */
+ /*
+ This function cannot be called if join_tab has no associated join
+ buffer
+ */
DBUG_ASSERT(cache != NULL);
join_tab->cache->reset_join(join);
@@ -14980,7 +15258,6 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
condition is true => a match is found.
*/
bool found= 1;
- bool use_not_exists_opt= 0;
while (join_tab->first_unmatched && found)
{
/*
@@ -14996,8 +15273,6 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
first_unmatched->found= 1;
for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
{
- if (tab->table->reginfo.not_exists_optimize)
- use_not_exists_opt= 1;
/* Check all predicates that has just been activated. */
/*
Actually all predicates non-guarded by first_unmatched->found
@@ -15008,7 +15283,11 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
{
/* The condition attached to table tab is false */
if (tab == join_tab)
+ {
found= 0;
+ if (tab->table->reginfo.not_exists_optimize)
+ DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
+ }
else
{
/*
@@ -15016,7 +15295,10 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
not to the last table of the current nest level.
*/
join->return_tab= tab;
- DBUG_RETURN(NESTED_LOOP_OK);
+ if (tab->table->reginfo.not_exists_optimize)
+ DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
+ else
+ DBUG_RETURN(NESTED_LOOP_OK);
}
}
}
@@ -15030,8 +15312,6 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
join_tab->first_unmatched= first_unmatched;
}
- if (use_not_exists_opt)
- DBUG_RETURN(NESTED_LOOP_NO_MORE_ROWS);
JOIN_TAB *return_tab= join->return_tab;
join_tab->found_match= TRUE;
@@ -15158,6 +15438,26 @@ evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab)
/*
The row complemented by nulls satisfies all conditions
attached to inner tables.
+ */
+ if (join_tab->check_weed_out_table)
+ {
+ int res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table);
+ if (res == -1)
+ return NESTED_LOOP_ERROR;
+ else if (res == 1)
+ return NESTED_LOOP_OK;
+ }
+ else if (join_tab->do_firstmatch)
+ {
+ /*
+ We should return to the join_tab->do_firstmatch after we have
+ enumerated all the suffixes for current prefix row combination
+ */
+ if (join_tab->do_firstmatch < join->return_tab)
+ join->return_tab= join_tab->do_firstmatch;
+ }
+
+ /*
Send the row complemented by nulls to be joined with the
remaining tables.
*/
@@ -15440,7 +15740,7 @@ int join_read_key2(THD *thd, JOIN_TAB *tab, TABLE *table, TABLE_REF *table_ref)
*/
if (tab && tab->ref.has_record && tab->ref.use_count == 0)
{
- tab->read_record.file->unlock_row();
+ tab->read_record.table->file->unlock_row();
table_ref->has_record= FALSE;
}
error=table->file->ha_index_read_map(table->record[0],
@@ -15626,7 +15926,7 @@ join_init_quick_read_record(JOIN_TAB *tab)
int init_read_record_seq(JOIN_TAB *tab)
{
tab->read_record.read_record= rr_sequential;
- if (tab->read_record.file->ha_rnd_init_with_error(1))
+ if (tab->read_record.table->file->ha_rnd_init_with_error(1))
return 1;
return (*tab->read_record.read_record)(&tab->read_record);
}
@@ -15693,7 +15993,6 @@ join_read_first(JOIN_TAB *tab)
tab->table->status=0;
tab->read_record.read_record=join_read_next;
tab->read_record.table=table;
- tab->read_record.file=table->file;
tab->read_record.index=tab->index;
tab->read_record.record=table->record[0];
if (!table->file->inited)
@@ -15714,7 +16013,7 @@ static int
join_read_next(READ_RECORD *info)
{
int error;
- if ((error= info->file->ha_index_next(info->record)))
+ if ((error= info->table->file->ha_index_next(info->record)))
return report_error(info->table, error);
return 0;
@@ -15732,7 +16031,6 @@ join_read_last(JOIN_TAB *tab)
tab->table->status=0;
tab->read_record.read_record=join_read_prev;
tab->read_record.table=table;
- tab->read_record.file=table->file;
tab->read_record.index=tab->index;
tab->read_record.record=table->record[0];
if (!table->file->inited)
@@ -15750,7 +16048,7 @@ static int
join_read_prev(READ_RECORD *info)
{
int error;
- if ((error= info->file->ha_index_prev(info->record)))
+ if ((error= info->table->file->ha_index_prev(info->record)))
return report_error(info->table, error);
return 0;
}
@@ -15784,7 +16082,7 @@ static int
join_ft_read_next(READ_RECORD *info)
{
int error;
- if ((error= info->file->ha_ft_read(info->table->record[0])))
+ if ((error= info->table->file->ha_ft_read(info->table->record[0])))
return report_error(info->table, error);
return 0;
}
@@ -16158,8 +16456,8 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
{ /* Update old record */
restore_record(table,record[1]);
update_tmptable_sum_func(join->sum_funcs,table);
- if ((error= table->file->ha_update_row(table->record[1],
- table->record[0])))
+ if ((error= table->file->ha_update_tmp_row(table->record[1],
+ table->record[0])))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
@@ -16242,8 +16540,8 @@ end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
}
restore_record(table,record[1]);
update_tmptable_sum_func(join->sum_funcs,table);
- if ((error= table->file->ha_update_row(table->record[1],
- table->record[0])))
+ if ((error= table->file->ha_update_tmp_row(table->record[1],
+ table->record[0])))
{
table->file->print_error(error,MYF(0)); /* purecov: inspected */
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
@@ -16376,16 +16674,12 @@ bool test_if_ref(Item *root_cond, Item_field *left_item,Item *right_item)
between ref access and full table scan), then no equality can be
guaranteed to be true.
*/
- for (uint i = 0; i < join_tab->ref.key_parts; i++)
- {
- if (join_tab->ref.cond_guards[i])
- {
- return FALSE;
- }
- }
+ if (join_tab->ref.is_access_triggered())
+ return FALSE;
Item *ref_item=part_of_refkey(field->table,field);
- if (ref_item && ref_item->eq(right_item,1))
+ if (ref_item && (ref_item->eq(right_item,1) ||
+ ref_item->real_item()->eq(right_item,1)))
{
right_item= right_item->real_item();
if (right_item->type() == Item::FIELD_ITEM)
@@ -16463,7 +16757,7 @@ bool test_if_ref(Item *root_cond, Item_field *left_item,Item *right_item)
static Item *
make_cond_for_table(THD *thd, Item *cond, table_map tables,
table_map used_table,
- uint join_tab_idx_arg,
+ int join_tab_idx_arg,
bool exclude_expensive_cond __attribute__((unused)),
bool retain_ref_cond)
{
@@ -16477,7 +16771,7 @@ make_cond_for_table(THD *thd, Item *cond, table_map tables,
static Item *
make_cond_for_table_from_pred(THD *thd, Item *root_cond, Item *cond,
table_map tables, table_map used_table,
- uint join_tab_idx_arg,
+ int join_tab_idx_arg,
bool exclude_expensive_cond __attribute__
((unused)),
bool retain_ref_cond)
@@ -17653,8 +17947,10 @@ check_reverse_order:
condition are not relevant anymore
*/
if (tab->select && tab->select->pre_idx_push_select_cond)
+ {
tab->set_cond(tab->select->pre_idx_push_select_cond);
-
+ tab->table->file->cancel_pushed_idx_cond();
+ }
/*
TODO: update the number of records in join->best_positions[tablenr]
*/
@@ -17713,14 +18009,11 @@ skipped_filesort:
delete save_quick;
save_quick= NULL;
}
- /*
- orig_cond is a part of pre_idx_push_cond,
- no need to restore it.
- */
- orig_cond= 0;
- orig_cond_saved= false;
if (orig_cond_saved && !changed_key)
tab->set_cond(orig_cond);
+ if (!no_changes && changed_key && table->file->pushed_idx_cond)
+ table->file->cancel_pushed_idx_cond();
+
DBUG_RETURN(1);
use_filesort:
@@ -17732,6 +18025,7 @@ use_filesort:
}
if (orig_cond_saved)
tab->set_cond(orig_cond);
+
DBUG_RETURN(0);
}
@@ -19659,7 +19953,6 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
}
if (thd->is_fatal_error)
DBUG_RETURN(TRUE);
-
if (!cond->fixed)
{
Item *tmp_item= (Item*) cond;
@@ -19668,11 +19961,21 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
}
if (join_tab->select)
{
+ Item *cond_copy;
+ UNINIT_VAR(cond_copy); // used when pre_idx_push_select_cond!=NULL
+ if (join_tab->select->pre_idx_push_select_cond)
+ cond_copy= cond->copy_andor_structure(thd);
if (join_tab->select->cond)
error=(int) cond->add(join_tab->select->cond);
join_tab->select->cond= cond;
if (join_tab->select->pre_idx_push_select_cond)
- join_tab->select->pre_idx_push_select_cond= cond;
+ {
+ Item *new_cond= and_conds(cond_copy, join_tab->select->pre_idx_push_select_cond);
+ if (!new_cond->fixed && new_cond->fix_fields(thd, &new_cond))
+ error= 1;
+ join_tab->pre_idx_push_select_cond=
+ join_tab->select->pre_idx_push_select_cond= new_cond;
+ }
join_tab->set_select_cond(cond, __LINE__);
}
else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
@@ -20467,7 +20770,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
keylen_str_buf);
tmp3.append(keylen_str_buf, length, cs);
}
- if (tab->select && tab->select->quick)
+ if (tab->type != JT_CONST && tab->select && tab->select->quick)
tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3);
if (key_info || (tab->select && tab->select->quick))
{
@@ -20538,8 +20841,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
examined_rows= tab->limit;
else
{
- if (!tab->table->pos_in_table_list ||
- tab->table->is_filled_at_execution()) // temporary, is_filled_at_execution
+ if (tab->table->is_filled_at_execution())
{
examined_rows= tab->records;
}
@@ -20714,7 +21016,8 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
need_order=0;
extra.append(STRING_WITH_LEN("; Using filesort"));
}
- if (distinct & test_all_bits(used_tables,thd->used_tables))
+ if (distinct & test_all_bits(used_tables,
+ join->select_list_used_tables))
extra.append(STRING_WITH_LEN("; Distinct"));
if (tab->loosescan_match_tab)
{
@@ -21321,6 +21624,28 @@ void JOIN::save_query_plan(Join_plan_state *save_to)
memcpy((uchar*) save_to->best_positions, (uchar*) best_positions,
sizeof(POSITION) * (table_count + 1));
memset(best_positions, 0, sizeof(POSITION) * (table_count + 1));
+
+ /* Save SJM nests */
+ List_iterator<TABLE_LIST> it(select_lex->sj_nests);
+ TABLE_LIST *tlist;
+ SJ_MATERIALIZATION_INFO **p_info= save_to->sj_mat_info;
+ while ((tlist= it++))
+ {
+ *(p_info++)= tlist->sj_mat_info;
+ }
+}
+
+
+/**
+ Reset a query execution plan so that it can be reoptimized in-place.
+*/
+void JOIN::reset_query_plan()
+{
+ for (uint i= 0; i < table_count; i++)
+ {
+ join_tab[i].keyuse= NULL;
+ join_tab[i].checked_keys.clear_all();
+ }
}
@@ -21348,6 +21673,14 @@ void JOIN::restore_query_plan(Join_plan_state *restore_from)
}
memcpy((uchar*) best_positions, (uchar*) restore_from->best_positions,
sizeof(POSITION) * (table_count + 1));
+ /* Restore SJM nests */
+ List_iterator<TABLE_LIST> it(select_lex->sj_nests);
+ TABLE_LIST *tlist;
+ SJ_MATERIALIZATION_INFO **p_info= restore_from->sj_mat_info;
+ while ((tlist= it++))
+ {
+ tlist->sj_mat_info= *(p_info++);
+ }
}
@@ -21357,7 +21690,8 @@ void JOIN::restore_query_plan(Join_plan_state *restore_from)
@param added_where An extra conjunct to the WHERE clause to reoptimize with
@param join_tables The set of tables to reoptimize
- @param save_to If != NULL, save here the state of the current query plan
+ @param save_to If != NULL, save here the state of the current query plan,
+ otherwise reuse the existing query plan structures.
@notes
Given a query plan that was already optimized taking into account some WHERE
@@ -21401,6 +21735,8 @@ JOIN::reoptimize(Item *added_where, table_map join_tables,
if (save_to)
save_query_plan(save_to);
+ else
+ reset_query_plan();
if (!keyuse.buffer &&
my_init_dynamic_array(&keyuse, sizeof(KEYUSE), 20, 64))
@@ -21434,6 +21770,9 @@ JOIN::reoptimize(Item *added_where, table_map join_tables,
return REOPT_ERROR;
optimize_keyuse(this, &keyuse);
+ if (optimize_semijoin_nests(this, join_tables))
+ return REOPT_ERROR;
+
/* Re-run the join optimizer to compute a new query plan. */
if (choose_plan(this, join_tables))
return REOPT_ERROR;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index abb9a98030e..5476ef9b46c 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -135,7 +135,8 @@ typedef struct st_table_ref
bool disable_cache;
bool tmp_table_index_lookup_init(THD *thd, KEY *tmp_key, Item_iterator &it,
- bool value);
+ bool value, uint skip= 0);
+ bool is_access_triggered();
} TABLE_REF;
@@ -204,7 +205,13 @@ typedef struct st_join_table {
NULL means no index condition pushdown was performed.
*/
Item *pre_idx_push_select_cond;
- Item **on_expr_ref; /**< pointer to the associated on expression */
+ /*
+ Pointer to the associated ON expression. on_expr_ref=!NULL except for
+ degenerate joins.
+ *on_expr_ref!=NULL for tables that are first inner tables within an outer
+ join.
+ */
+ Item **on_expr_ref;
COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */
st_join_table *first_inner; /**< first inner table for including outerjoin */
bool found; /**< true after all matches or null complement */
@@ -282,7 +289,6 @@ typedef struct st_join_table {
ulong max_used_fieldlength;
uint used_blobs;
uint used_null_fields;
- uint used_rowid_fields;
uint used_uneven_bit_fields;
enum join_type type;
bool cached_eq_ref_table,eq_ref_table,not_used_in_distinct;
@@ -341,6 +347,9 @@ typedef struct st_join_table {
NULL - Not doing a loose scan on this join tab.
*/
struct st_join_table *loosescan_match_tab;
+
+ /* TRUE <=> we are inside LooseScan range */
+ bool inside_loosescan_range;
/* Buffer to save index tuple to be able to skip duplicates */
uchar *loosescan_buf;
@@ -378,15 +387,6 @@ typedef struct st_join_table {
(select->quick->get_type() ==
QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX));
}
- bool check_rowid_field()
- {
- if (keep_current_rowid && !used_rowid_fields)
- {
- used_rowid_fields= 1;
- used_fieldlength+= table->file->ref_length;
- }
- return test(used_rowid_fields);
- }
bool is_inner_table_of_semi_join_with_first_match()
{
return first_sj_inner_tab != NULL;
@@ -478,6 +478,8 @@ typedef struct st_join_table {
}
double scan_time();
bool preread_init();
+
+ bool is_sjm_nest() { return test(bush_children); }
} JOIN_TAB;
@@ -665,6 +667,7 @@ protected:
KEYUSE *join_tab_keyuse[MAX_TABLES];
/* Copies of JOIN_TAB::checked_keys for each JOIN_TAB. */
key_map join_tab_checked_keys[MAX_TABLES];
+ SJ_MATERIALIZATION_INFO *sj_mat_info[MAX_TABLES];
public:
Join_plan_state()
{
@@ -690,6 +693,7 @@ protected:
enum_reopt_result reoptimize(Item *added_where, table_map join_tables,
Join_plan_state *save_to);
void save_query_plan(Join_plan_state *save_to);
+ void reset_query_plan();
void restore_query_plan(Join_plan_state *restore_from);
/* Choose a subquery plan for a table-less subquery. */
bool choose_tableless_subquery_plan();
@@ -759,6 +763,8 @@ public:
make_join_statistics)
*/
table_map outer_join;
+ /* Bitmap of tables used in the select list items */
+ table_map select_list_used_tables;
ha_rows send_records,found_records,examined_rows,row_limit, select_limit;
/**
Used to fetch no more than given amount of rows per one
@@ -956,11 +962,6 @@ public:
bool optimized; ///< flag to avoid double optimization in EXPLAIN
bool initialized; ///< flag to avoid double init_execution calls
- /*
- Subqueries that will need to be converted to semi-join nests, including
- those converted to jtbm nests. The list is emptied when conversion is done.
- */
- Array<Item_in_subselect> sj_subselects;
/*
Additional WHERE and HAVING predicates to be considered for IN=>EXISTS
subquery transformation of a JOIN object.
@@ -990,7 +991,7 @@ public:
JOIN(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
select_result *result_arg)
- :fields_list(fields_arg), sj_subselects(thd_arg->mem_root, 4)
+ :fields_list(fields_arg)
{
init(thd_arg, fields_arg, select_options_arg, result_arg);
}
@@ -1126,6 +1127,7 @@ public:
return (table_map(1) << table_count) - 1;
}
void drop_unused_derived_keys();
+ inline void eval_select_list_used_tables();
/*
Return the table for which an index scan can be used to satisfy
the sort order needed by the ORDER BY/(implicit) GROUP BY clause
@@ -1147,7 +1149,7 @@ public:
max_allowed_join_cache_level > JOIN_CACHE_HASHED_BIT;
}
bool choose_subquery_plan(table_map join_tables);
- void get_partial_cost_and_fanout(uint end_tab_idx,
+ void get_partial_cost_and_fanout(int end_tab_idx,
table_map filter_map,
double *read_time_arg,
double *record_count_arg);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 0cf7a9b1dc2..c7cd692000f 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -22,8 +22,8 @@
#include "create_options.h"
#include "sql_show.h"
#include "repl_failsafe.h"
-#include "sp.h"
#include "sp_head.h"
+#include "sp.h"
#include "sql_trigger.h"
#include "authors.h"
#include "contributors.h"
@@ -1274,7 +1274,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
handler *file= table->file;
TABLE_SHARE *share= table->s;
HA_CREATE_INFO create_info;
- bool show_table_options= FALSE;
+ bool show_table_options __attribute__ ((unused))= FALSE;
bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
MODE_ORACLE |
MODE_MSSQL |
@@ -1507,7 +1507,9 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
packet->append(STRING_WITH_LEN("\n)"));
if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode)
{
+#ifdef WITH_PARTITION_STORAGE_ENGINE
show_table_options= TRUE;
+#endif
/*
Get possible table space definitions and append them
to the CREATE TABLE statement
@@ -1870,6 +1872,7 @@ public:
uint command;
const char *user,*host,*db,*proc_info,*state_info;
char *query;
+ double progress;
};
#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
@@ -1898,6 +1901,11 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
field->maybe_null=1;
field_list.push_back(field=new Item_empty_string("Info",max_query_length));
field->maybe_null=1;
+ if (!thd->variables.old_mode)
+ {
+ field_list.push_back(field= new Item_float("Progress", 0.0, 3, 7));
+ field->maybe_null= 0;
+ }
if (protocol->send_fields(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_VOID_RETURN;
@@ -1937,7 +1945,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
pthread_mutex_lock(&tmp->LOCK_thd_data);
if ((mysys_var= tmp->mysys_var))
pthread_mutex_lock(&mysys_var->mutex);
- thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
+ thd_info->proc_info= (char*) (tmp->killed >= KILL_QUERY ?
+ "Killed" : 0);
#ifndef EMBEDDED_LIBRARY
thd_info->state_info= (char*) (tmp->net.reading_or_writing ?
(tmp->net.reading_or_writing == 2 ?
@@ -1957,6 +1966,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thd_info->start_time= tmp->start_time;
thd_info->query=0;
+ thd_info->progress= 0.0;
+
/* Lock THD mutex that protects its data when looking at it. */
pthread_mutex_lock(&tmp->LOCK_thd_data);
if (tmp->query())
@@ -1964,6 +1975,20 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
uint length= min(max_query_length, tmp->query_length());
thd_info->query= (char*) thd->strmake(tmp->query(),length);
}
+
+ /*
+ Progress report. We need to do this under a lock to ensure that all
+ is from the same stage.
+ */
+ if (tmp->progress.max_counter)
+ {
+ uint max_stage= max(tmp->progress.max_stage, 1);
+ thd_info->progress= (((tmp->progress.stage / (double) max_stage) +
+ ((tmp->progress.counter /
+ (double) tmp->progress.max_counter) /
+ (double) max_stage)) *
+ 100.0);
+ }
pthread_mutex_unlock(&tmp->LOCK_thd_data);
thread_infos.append(thd_info);
}
@@ -1973,6 +1998,9 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thread_info *thd_info;
time_t now= my_time(0);
+ char buff[20]; // For progress
+ String store_buffer(buff, sizeof(buff), system_charset_info);
+
while ((thd_info=thread_infos.get()))
{
protocol->prepare_for_resend();
@@ -1990,6 +2018,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
protocol->store_null();
protocol->store(thd_info->state_info, system_charset_info);
protocol->store(thd_info->query, system_charset_info);
+ if (!thd->variables.old_mode)
+ protocol->store(thd_info->progress, 3, &store_buffer);
if (protocol->write())
break; /* purecov: inspected */
}
@@ -2020,6 +2050,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
Security_context *tmp_sctx= tmp->security_ctx;
struct st_my_thread_var *mysys_var;
const char *val;
+ ulonglong max_counter;
if ((!tmp->vio_ok() && !tmp->system_thread) ||
(user && (!tmp_sctx->user || strcmp(tmp_sctx->user, user))))
@@ -2054,7 +2085,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
if ((mysys_var= tmp->mysys_var))
pthread_mutex_lock(&mysys_var->mutex);
/* COMMAND */
- if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
+ if ((val= (char *) ((tmp->killed >= KILL_QUERY ?
+ "Killed" : 0))))
table->field[4]->store(val, strlen(val), cs);
else
table->field[4]->store(command_name[tmp->command].str,
@@ -2087,6 +2119,9 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
if (mysys_var)
pthread_mutex_unlock(&mysys_var->mutex);
+ /* TIME_MS */
+ table->field[8]->store((double)(utime / (HRTIME_RESOLUTION / 1000.0)));
+
/* INFO */
/* Lock THD mutex that protects its data when looking at it. */
pthread_mutex_lock(&tmp->LOCK_thd_data);
@@ -2097,10 +2132,19 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
tmp->query_length()), cs);
table->field[7]->set_notnull();
}
- pthread_mutex_unlock(&tmp->LOCK_thd_data);
- /* TIME_MS */
- table->field[8]->store((double)(utime / (HRTIME_RESOLUTION / 1000.0)));
+ /*
+ Progress report. We need to do this under a lock to ensure that all
+ is from the same stage.
+ */
+ if ((max_counter= tmp->progress.max_counter))
+ {
+ table->field[9]->store((longlong) tmp->progress.stage + 1, 1);
+ table->field[10]->store((longlong) tmp->progress.max_stage, 1);
+ table->field[11]->store((double) tmp->progress.counter /
+ (double) max_counter*100.0);
+ }
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
if (schema_table_store_record(thd, table))
{
@@ -2397,7 +2441,7 @@ static bool show_status_array(THD *thd, const char *wild,
end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
break;
case SHOW_INT:
- end= int10_to_str((long) *(uint32*) value, buff, 10);
+ end= int10_to_str((long) *(int*) value, buff, -10);
break;
case SHOW_HAVE:
{
@@ -2814,7 +2858,7 @@ typedef struct st_lookup_field_values
bool schema_table_store_record(THD *thd, TABLE *table)
{
int error;
- if ((error= table->file->ha_write_row(table->record[0])))
+ if ((error= table->file->ha_write_tmp_row(table->record[0])))
{
TMP_TABLE_PARAM *param= table->pos_in_table_list->schema_table_param;
if (create_internal_tmp_table_from_heap(thd, table, param->start_recinfo,
@@ -6703,11 +6747,11 @@ bool get_schema_tables_result(JOIN *join,
{
result= 1;
join->error= 1;
- tab->read_record.file= table_list->table->file;
+ tab->read_record.table->file= table_list->table->file;
table_list->schema_table_state= executed_place;
break;
}
- tab->read_record.file= table_list->table->file;
+ tab->read_record.table->file= table_list->table->file;
table_list->schema_table_state= executed_place;
}
}
@@ -7300,6 +7344,10 @@ ST_FIELD_INFO processlist_fields_info[]=
SKIP_OPEN_TABLE},
{"TIME_MS", 100 * (MY_INT64_NUM_DECIMAL_DIGITS + 1) + 3, MYSQL_TYPE_DECIMAL,
0, 0, "Time_ms", SKIP_OPEN_TABLE},
+ {"STAGE", 2, MYSQL_TYPE_TINY, 0, 0, "Stage", SKIP_OPEN_TABLE},
+ {"MAX_STAGE", 2, MYSQL_TYPE_TINY, 0, 0, "Max_stage", SKIP_OPEN_TABLE},
+ {"PROGRESS", 703, MYSQL_TYPE_DECIMAL, 0, 0, "Progress",
+ SKIP_OPEN_TABLE},
{0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 9d71f2482b4..90844824368 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -36,7 +36,8 @@ const char *primary_key_name="PRIMARY";
static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
-static int copy_data_between_tables(TABLE *,TABLE *, List<Create_field> &, bool,
+static int copy_data_between_tables(THD *thd, TABLE *,TABLE *,
+ List<Create_field> &, bool,
uint, ORDER *, ha_rows *,ha_rows *,
enum enum_enable_or_disable, bool);
@@ -58,7 +59,7 @@ static void wait_for_kill_signal(THD *thd)
while (thd->killed == 0)
sleep(1);
// Reset signal and continue as if nothing happend
- thd->killed= THD::NOT_KILLED;
+ thd->killed= NOT_KILLED;
}
#endif
@@ -4689,6 +4690,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
int result_code;
bool need_repair_or_alter= 0;
DBUG_ENTER("mysql_admin_table");
+ DBUG_PRINT("enter", ("extra_open_options: %u", extra_open_options));
if (end_active_trans(thd))
DBUG_RETURN(1);
@@ -4713,9 +4715,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
bool fatal_error=0;
DBUG_PRINT("admin", ("table: '%s'.'%s'", table->db, table->table_name));
- DBUG_PRINT("admin", ("extra_open_options: %u", extra_open_options));
strxmov(table_name, db, ".", table->table_name, NullS);
- thd->open_options|= extra_open_options;
table->lock_type= lock_type;
/* open only one table from local list of command */
{
@@ -4742,12 +4742,13 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
lex->sql_command == SQLCOM_ANALYZE ||
lex->sql_command == SQLCOM_OPTIMIZE)
thd->prepare_derived_at_open= TRUE;
+ thd->open_options|= extra_open_options;
open_and_lock_tables(thd, table);
+ thd->open_options&= ~extra_open_options;
thd->prepare_derived_at_open= FALSE;
thd->no_warnings_for_error= 0;
table->next_global= save_next_global;
table->next_local= save_next_local;
- thd->open_options&= ~extra_open_options;
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (table->table)
{
@@ -4931,7 +4932,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
/* We use extra_open_options to be able to open crashed tables */
thd->open_options|= extra_open_options;
result_code= admin_recreate_table(thd, table);
- thd->open_options= ~extra_open_options;
+ thd->open_options&= ~extra_open_options;
goto send_result;
}
if (check_old_types || check_for_upgrade)
@@ -7505,8 +7506,7 @@ view_err:
/* We don't want update TIMESTAMP fields during ALTER TABLE. */
new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
new_table->next_number_field=new_table->found_next_number_field;
- thd_proc_info(thd, "copy to tmp table");
- error= copy_data_between_tables(table, new_table,
+ error= copy_data_between_tables(thd, table, new_table,
alter_info->create_list, ignore,
order_num, order, &copied, &deleted,
alter_info->keys_onoff,
@@ -7913,7 +7913,7 @@ err_with_placeholders:
/* Copy all rows from one table to another */
static int
-copy_data_between_tables(TABLE *from,TABLE *to,
+copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
List<Create_field> &create,
bool ignore,
uint order_num, ORDER *order,
@@ -7925,7 +7925,6 @@ copy_data_between_tables(TABLE *from,TABLE *to,
int error= 1, errpos= 0;
Copy_field *copy= NULL, *copy_end;
ha_rows found_count= 0, delete_count= 0;
- THD *thd= current_thd;
uint length= 0;
SORT_FIELD *sortorder;
READ_RECORD info;
@@ -7935,11 +7934,14 @@ copy_data_between_tables(TABLE *from,TABLE *to,
ha_rows examined_rows;
bool auto_increment_field_copied= 0;
ulong save_sql_mode= thd->variables.sql_mode;
- ulonglong prev_insert_id;
+ ulonglong prev_insert_id, time_to_report_progress;
List_iterator<Create_field> it(create);
Create_field *def;
DBUG_ENTER("copy_data_between_tables");
+ /* Two or 3 stages; Sorting, copying data and update indexes */
+ thd_progress_init(thd, 2 + test(order));
+
/*
Turn off recovery logging since rollback of an alter table is to
delete the new table so there is no need to log the changes to it.
@@ -8013,6 +8015,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
tables.alias= tables.table_name= from->s->table_name.str;
tables.db= from->s->db.str;
+ thd_proc_info(thd, "Sorting");
if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
setup_order(thd, thd->lex->select_lex.ref_pointer_array,
&tables, fields, all_fields, order) ||
@@ -8023,8 +8026,10 @@ copy_data_between_tables(TABLE *from,TABLE *to,
HA_POS_ERROR)
goto err;
}
- };
+ thd_progress_next_stage(thd);
+ }
+ thd_proc_info(thd, "copy to tmp table");
/* Tell handler that we have values for all columns in the to table */
to->use_all_columns();
to->mark_virtual_columns_for_write(TRUE);
@@ -8035,6 +8040,10 @@ copy_data_between_tables(TABLE *from,TABLE *to,
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
thd->row_count= 0;
restore_record(to, s->default_values); // Create empty record
+
+ thd->progress.max_counter= from->file->records();
+ time_to_report_progress= MY_HOW_OFTEN_TO_WRITE/10;
+
while (!(error=info.read_record(&info)))
{
if (thd->killed)
@@ -8045,6 +8054,13 @@ copy_data_between_tables(TABLE *from,TABLE *to,
}
update_virtual_fields(thd, from);
thd->row_count++;
+ if (++thd->progress.counter >= time_to_report_progress)
+ {
+ time_to_report_progress+= MY_HOW_OFTEN_TO_WRITE/10;
+ thd_progress_report(thd, thd->progress.counter,
+ thd->progress.max_counter);
+ }
+
/* Return error if source table isn't empty. */
if (error_if_not_empty)
{
@@ -8108,6 +8124,9 @@ err:
free_io_cache(from);
delete [] copy;
+ thd_proc_info(thd, "Enabling keys");
+ thd_progress_next_stage(thd);
+
if (error > 0)
to->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
if (errpos >= 3 && to->file->ha_end_bulk_insert() && error <= 0)
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 50505dd94a9..50de42d153c 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -60,7 +60,7 @@ int select_union::send_data(List<Item> &values)
if (thd->is_error())
return 1;
- if ((write_err= table->file->ha_write_row(table->record[0])))
+ if ((write_err= table->file->ha_write_tmp_row(table->record[0])))
{
if (write_err == HA_ERR_FOUND_DUPP_KEY)
{
@@ -371,6 +371,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
ulonglong create_options;
uint save_tablenr= 0;
table_map save_map= 0;
+ uint save_maybe_null= 0;
while ((type= tp++))
{
@@ -429,6 +430,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
{
save_tablenr= result_table_list.tablenr_exec;
save_map= result_table_list.map_exec;
+ save_maybe_null= result_table_list.maybe_null_exec;
}
bzero((char*) &result_table_list, sizeof(result_table_list));
result_table_list.db= (char*) "";
@@ -438,6 +440,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
{
result_table_list.tablenr_exec= save_tablenr;
result_table_list.map_exec= save_map;
+ result_table_list.maybe_null_exec= save_maybe_null;
}
thd_arg->lex->current_select= lex_select_save;
@@ -642,6 +645,7 @@ bool st_select_lex_unit::exec()
if (!saved_error)
{
examined_rows+= thd->examined_row_count;
+ thd->examined_row_count= 0;
if (union_result->flush())
{
thd->lex->current_select= lex_select_save;
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 4821fc2bd8f..80eb823c346 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -221,7 +221,7 @@ int mysql_update(THD *thd,
bool need_reopen;
ulonglong id;
List<Item> all_fields;
- THD::killed_state killed_status= THD::NOT_KILLED;
+ killed_state killed_status= NOT_KILLED;
DBUG_ENTER("mysql_update");
for ( ; ; )
@@ -248,6 +248,7 @@ int mysql_update(THD *thd,
DBUG_RETURN(1);
close_tables_for_reopen(thd, &table_list);
}
+
if (table_list->handle_derived(thd->lex, DT_MERGE_FOR_INSERT))
DBUG_RETURN(1);
if (table_list->handle_derived(thd->lex, DT_PREPARE))
@@ -787,9 +788,9 @@ int mysql_update(THD *thd,
// simulated killing after the loop must be ineffective for binlogging
DBUG_EXECUTE_IF("simulate_kill_bug27571",
{
- thd->killed= THD::KILL_QUERY;
+ thd->killed= KILL_QUERY;
};);
- error= (killed_status == THD::NOT_KILLED)? error : 1;
+ error= (killed_status == NOT_KILLED)? error : 1;
if (error &&
will_batch &&
@@ -850,7 +851,7 @@ int mysql_update(THD *thd,
if (error < 0)
thd->clear_error();
else
- errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ errcode= query_error_code(thd, killed_status == NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
@@ -1037,9 +1038,10 @@ reopen_tables:
second time, but this call will do nothing (there are check for second
call in setup_tables()).
*/
+
//We need to merge for insert prior to prepare.
- if (mysql_handle_list_of_derived(lex, table_list, DT_MERGE_FOR_INSERT))
- DBUG_RETURN(1);
+ if (mysql_handle_derived(lex, DT_MERGE_FOR_INSERT))
+ DBUG_RETURN(TRUE);
if (mysql_handle_derived(lex, DT_PREPARE))
DBUG_RETURN(TRUE);
@@ -1047,7 +1049,10 @@ reopen_tables:
&lex->select_lex.top_join_list,
table_list,
lex->select_lex.leaf_tables, FALSE,
- UPDATE_ACL, SELECT_ACL, TRUE))
+ UPDATE_ACL, SELECT_ACL, FALSE))
+ DBUG_RETURN(TRUE);
+
+ if (lex->select_lex.handle_derived(thd->lex, DT_MERGE))
DBUG_RETURN(TRUE);
if (setup_fields_with_no_wrap(thd, 0, *fields, MARK_COLUMNS_WRITE, 0, 0))
@@ -1237,6 +1242,9 @@ reopen_tables:
further check in multi_update::prepare whether to use record cache.
*/
lex->select_lex.exclude_from_table_unique_test= FALSE;
+
+ if (lex->select_lex.save_prep_leaf_tables(thd))
+ DBUG_RETURN(TRUE);
DBUG_RETURN (FALSE);
}
@@ -1330,13 +1338,6 @@ int multi_update::prepare(List<Item> &not_used_values,
thd->cuted_fields=0L;
thd_proc_info(thd, "updating main table");
- SELECT_LEX *select_lex= lex_unit->first_select();
- if (select_lex->first_cond_optimization)
- {
- if (select_lex->handle_derived(thd->lex, DT_MERGE))
- DBUG_RETURN(TRUE);
- }
-
tables_to_update= get_table_map(fields);
if (!tables_to_update)
@@ -1868,7 +1869,7 @@ int multi_update::send_data(List<Item> &not_used_values)
*values_for_table[offset], TRUE, FALSE);
/* Write row, ignoring duplicated updates to a row */
- error= tmp_table->file->ha_write_row(tmp_table->record[0]);
+ error= tmp_table->file->ha_write_tmp_row(tmp_table->record[0]);
if (error != HA_ERR_FOUND_DUPP_KEY && error != HA_ERR_FOUND_DUPP_UNIQUE)
{
if (error &&
@@ -1936,7 +1937,7 @@ void multi_update::abort()
got caught and if happens later the killed error is written
into repl event.
*/
- int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
/* the error of binary logging is ignored */
(void)thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
@@ -2150,7 +2151,7 @@ bool multi_update::send_eof()
{
char buff[STRING_BUFFER_USUAL_SIZE];
ulonglong id;
- THD::killed_state killed_status= THD::NOT_KILLED;
+ killed_state killed_status= NOT_KILLED;
DBUG_ENTER("multi_update::send_eof");
thd_proc_info(thd, "updating reference tables");
@@ -2163,7 +2164,7 @@ bool multi_update::send_eof()
if local_error is not set ON until after do_updates() then
later carried out killing should not affect binlogging.
*/
- killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
+ killed_status= (local_error == 0) ? NOT_KILLED : thd->killed;
thd_proc_info(thd, "end");
/* We must invalidate the query cache before binlog writing and
@@ -2192,7 +2193,7 @@ bool multi_update::send_eof()
if (local_error == 0)
thd->clear_error();
else
- errcode= query_error_code(thd, killed_status == THD::NOT_KILLED);
+ errcode= query_error_code(thd, killed_status == NOT_KILLED);
if (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
transactional_tables, FALSE, errcode))
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 89ccfd10a45..9d71a61f411 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -18,8 +18,8 @@
#include "mysql_priv.h"
#include "sql_select.h"
#include "parse_file.h"
-#include "sp.h"
#include "sp_head.h"
+#include "sp.h"
#include "sp_cache.h"
#define MD5_BUFF_LENGTH 33
@@ -1483,8 +1483,22 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
We can safely ignore the VIEW's ORDER BY if we merge into union
branch, as order is not important there.
*/
- if (!table->select_lex->master_unit()->is_union())
+ if (!table->select_lex->master_unit()->is_union() &&
+ table->select_lex->order_list.elements == 0)
table->select_lex->order_list.push_back(&lex->select_lex.order_list);
+ else
+ {
+ if (old_lex->sql_command == SQLCOM_SELECT &&
+ (old_lex->describe & DESCRIBE_EXTENDED) &&
+ lex->select_lex.order_list.elements &&
+ !table->select_lex->master_unit()->is_union())
+ {
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_VIEW_ORDERBY_IGNORED,
+ ER(ER_VIEW_ORDERBY_IGNORED),
+ table->db, table->table_name);
+ }
+ }
/*
This SELECT_LEX will be linked in global SELECT_LEX list
to make it processed by mysql_handle_derived(),
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 3337b1b487e..0d0e0ef98a4 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -682,10 +682,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%pure_parser /* We have threads */
/*
- Currently there are 171 shift/reduce conflicts.
+ Currently there are 174 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
-%expect 171
+%expect 174
/*
Comments for TOKENS.
@@ -901,6 +901,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token GROUP_CONCAT_SYM
%token GT_SYM /* OPERATOR */
%token HANDLER_SYM
+%token HARD_SYM
%token HASH_SYM
%token HAVING /* SQL-2003-R */
%token HELP_SYM
@@ -1169,6 +1170,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SMALLINT /* SQL-2003-R */
%token SNAPSHOT_SYM
%token SOCKET_SYM
+%token SOFT_SYM
%token SONAME_SYM
%token SOUNDS_SYM
%token SOURCE_SYM
@@ -1348,7 +1350,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
optional_flush_tables_arguments opt_dyncol_type dyncol_type
- opt_time_precision
+ opt_time_precision kill_type kill_option int_num
%type <ulong_num>
ulong_num real_ulong_num merge_insert_types
@@ -1380,7 +1382,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
function_call_keyword
function_call_nonkeyword
function_call_generic
- function_call_conflict
+ function_call_conflict kill_expr
%type <item_num>
NUM_literal
@@ -7172,7 +7174,7 @@ expr:
| expr XOR expr %prec XOR
{
/* XOR is a proprietary extension */
- $$ = new (YYTHD->mem_root) Item_cond_xor($1, $3);
+ $$ = new (YYTHD->mem_root) Item_func_xor($1, $3);
if ($$ == NULL)
MYSQL_YYABORT;
}
@@ -9426,7 +9428,7 @@ where_clause:
expr
{
SELECT_LEX *select= Select;
- select->where= $3;
+ select->where= normalize_cond($3);
select->parsing_place= NO_MATTER;
if ($3)
$3->top_level_item();
@@ -9442,7 +9444,7 @@ having_clause:
expr
{
SELECT_LEX *sel= Select;
- sel->having= $3;
+ sel->having= normalize_cond($3);
sel->parsing_place= NO_MATTER;
if ($3)
$3->top_level_item();
@@ -9674,6 +9676,12 @@ delete_limit_clause:
}
;
+int_num:
+ NUM { int error; $$= (int) my_strtoll10($1.str, (char**) 0, &error); }
+ | '-' NUM { int error; $$= -(int) my_strtoll10($2.str, (char**) 0, &error); }
+ | '-' LONG_NUM { int error; $$= -(int) my_strtoll10($2.str, (char**) 0, &error); }
+ ;
+
ulong_num:
NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); }
| HEX_NUM { $$= (ulong) strtol($1.str, (char**) 0, 16); }
@@ -10909,7 +10917,7 @@ wild_and_where:
}
| WHERE expr
{
- Select->where= $2;
+ Select->where= normalize_cond($2);
if ($2)
$2->top_level_item();
}
@@ -11081,19 +11089,41 @@ purge_option:
/* kill threads */
kill:
- KILL_SYM kill_option expr
+ KILL_SYM
{
LEX *lex=Lex;
lex->value_list.empty();
- lex->value_list.push_front($3);
+ lex->users_list.empty();
lex->sql_command= SQLCOM_KILL;
}
+ kill_type kill_option kill_expr
+ {
+ Lex->kill_signal= (killed_state) ($3 | $4);
+ }
;
+kill_type:
+ /* Empty */ { $$= (int) KILL_HARD_BIT; }
+ | HARD_SYM { $$= (int) KILL_HARD_BIT; }
+ | SOFT_SYM { $$= 0; }
+
kill_option:
- /* empty */ { Lex->type= 0; }
- | CONNECTION_SYM { Lex->type= 0; }
- | QUERY_SYM { Lex->type= ONLY_KILL_QUERY; }
+ /* empty */ { $$= (int) KILL_CONNECTION; }
+ | CONNECTION_SYM { $$= (int) KILL_CONNECTION; }
+ | QUERY_SYM { $$= (int) KILL_QUERY; }
+ ;
+
+kill_expr:
+ expr
+ {
+ Lex->value_list.push_front($$);
+ Lex->kill_type= KILL_TYPE_ID;
+ }
+ | USER user
+ {
+ Lex->users_list.push_back($2);
+ Lex->kill_type= KILL_TYPE_USER;
+ }
;
/* change database */
@@ -12208,6 +12238,7 @@ keyword_sp:
| GRANTS {}
| GLOBAL_SYM {}
| HASH_SYM {}
+ | HARD_SYM {}
| HOSTS_SYM {}
| HOUR_SYM {}
| IDENTIFIED_SYM {}
@@ -12339,6 +12370,7 @@ keyword_sp:
| SHUTDOWN {}
| SLOW_SYM {}
| SNAPSHOT_SYM {}
+ | SOFT_SYM {}
| SOUNDS_SYM {}
| SOURCE_SYM {}
| SQL_CACHE_SYM {}
@@ -13408,7 +13440,7 @@ grant_option:
lex->mqh.conn_per_hour= $2;
lex->mqh.specified_limits|= USER_RESOURCES::CONNECTIONS_PER_HOUR;
}
- | MAX_USER_CONNECTIONS_SYM ulong_num
+ | MAX_USER_CONNECTIONS_SYM int_num
{
LEX *lex=Lex;
lex->mqh.user_conn= $2;
diff --git a/sql/structs.h b/sql/structs.h
index 29ccde3fb03..61354cbd01c 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -149,7 +149,7 @@ struct READ_RECORD { /* Parameter to read_record */
typedef int (*Read_func)(READ_RECORD*);
typedef void (*Unlock_row_func)(st_join_table *);
struct st_table *table; /* Head-form */
- handler *file;
+ // handler *file_;
struct st_table **forms; /* head and ref forms */
Read_func read_record;
@@ -222,8 +222,11 @@ typedef struct user_resources {
uint updates;
/* Maximum number of connections established per hour. */
uint conn_per_hour;
- /* Maximum number of concurrent connections. */
- uint user_conn;
+ /*
+ Maximum number of concurrent connections. If -1 then no new
+ connections allowed
+ */
+ int user_conn;
/*
Values of this enum and specified_limits member are used by the
parser to store which user limits were specified in GRANT statement.
@@ -256,7 +259,7 @@ typedef struct user_conn {
/* Total length of the key. */
uint len;
/* Current amount of concurrent connections for this account. */
- uint connections;
+ int connections;
/*
Current number of connections per hour, number of updating statements
per hour and total number of statements per hour for this account.
diff --git a/sql/table.cc b/sql/table.cc
index 8427ca6e112..23c43f91d22 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -989,14 +989,13 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
#endif
next_chunk+= 5 + partition_info_len;
}
- if (share->mysql_version >= 50110)
+ if (share->mysql_version >= 50110 && next_chunk < buff_end)
{
/* New auto_partitioned indicator introduced in 5.1.11 */
#ifdef WITH_PARTITION_STORAGE_ENGINE
share->auto_partitioned= *next_chunk;
#endif
next_chunk++;
- DBUG_ASSERT(next_chunk <= buff_end);
}
keyinfo= share->key_info;
for (i= 0; i < keys; i++, keyinfo++)
@@ -2460,7 +2459,7 @@ int closefrm(register TABLE *table, bool free_share)
{
if (table->s->deleting)
table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
- error=table->file->close();
+ error=table->file->ha_close();
}
table->alias.free();
if (table->expr_arena)
@@ -4537,7 +4536,7 @@ Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
Force creation of nullable item for the result tmp table for outer joined
views/derived tables.
*/
- if (view->outer_join)
+ if (view->table && view->table->maybe_null)
item->maybe_null= TRUE;
/* Save item in case we will need to fall back to materialization. */
view->used_items.push_back(item);
@@ -5221,10 +5220,11 @@ void st_table::mark_virtual_columns_for_write(bool insert_fl)
@brief
Allocate space for keys
- @param key_count number of keys to allocate
+ @param key_count number of keys to allocate additionally
@details
- The function allocates memory to fit 'key_count' keys for this table.
+ The function allocates memory to fit additionally 'key_count' keys
+ for this table.
@return FALSE space was successfully allocated
@return TRUE an error occur
@@ -5232,22 +5232,25 @@ void st_table::mark_virtual_columns_for_write(bool insert_fl)
bool TABLE::alloc_keys(uint key_count)
{
- DBUG_ASSERT(!s->keys);
- key_info= s->key_info= (KEY*) alloc_root(&mem_root, sizeof(KEY)*key_count);
- max_keys= key_count;
+ key_info= (KEY*) alloc_root(&mem_root, sizeof(KEY)*(s->keys+key_count));
+ if (s->keys)
+ memmove(key_info, s->key_info, sizeof(KEY)*s->keys);
+ s->key_info= key_info;
+ max_keys= s->keys+key_count;
return !(key_info);
}
void TABLE::create_key_part_by_field(KEY *keyinfo,
KEY_PART_INFO *key_part_info,
- Field *field)
+ Field *field, uint fieldnr)
{
field->flags|= PART_KEY_FLAG;
key_part_info->null_bit= field->null_bit;
key_part_info->null_offset= (uint) (field->null_ptr -
(uchar*) record[0]);
key_part_info->field= field;
+ key_part_info->fieldnr= fieldnr;
key_part_info->offset= field->offset(record[0]);
key_part_info->length= (uint16) field->pack_length();
keyinfo->key_length+= key_part_info->length;
@@ -5340,11 +5343,12 @@ bool TABLE::add_tmp_key(uint key, uint key_parts,
for (i= 0; i < key_parts; i++)
{
- reg_field= field + next_field_no(arg);
+ uint fld_idx= next_field_no(arg);
+ reg_field= field + fld_idx;
if (key_start)
(*reg_field)->key_start.set_bit(key);
(*reg_field)->part_of_key.set_bit(key);
- create_key_part_by_field(keyinfo, key_part_info, *reg_field);
+ create_key_part_by_field(keyinfo, key_part_info, *reg_field, fld_idx+1);
key_start= FALSE;
key_part_info++;
}
@@ -5372,12 +5376,12 @@ void TABLE::use_index(int key_to_save)
DBUG_ASSERT(!created && key_to_save < (int)s->keys);
if (key_to_save >= 0)
/* Save the given key. */
- memcpy(key_info, key_info + key_to_save, sizeof(KEY));
+ memmove(key_info, key_info + key_to_save, sizeof(KEY));
else
/* Drop all keys; */
i= 0;
- s->keys= (key_to_save < 0) ? 0 : 1;
+ s->keys= i;
}
/**
@@ -5408,9 +5412,11 @@ bool st_table::is_children_attached(void)
bool st_table::is_filled_at_execution()
{
- return test(pos_in_table_list->jtbm_subselect);
+ return test(pos_in_table_list->jtbm_subselect ||
+ pos_in_table_list->is_active_sjm());
}
+
/*
Cleanup this table for re-execution.
@@ -5686,7 +5692,7 @@ int update_virtual_fields(THD *thd, TABLE *table, bool for_write)
{
DBUG_ENTER("update_virtual_fields");
Field **vfield_ptr, *vfield;
- int error= 0;
+ int error __attribute__ ((unused))= 0;
if (!table || !table->vfield)
DBUG_RETURN(0);
diff --git a/sql/table.h b/sql/table.h
index 4205b81dc12..5dd464ac876 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -959,7 +959,7 @@ struct st_table {
uint (*next_field_no) (uchar *), uchar *arg,
bool unique);
void create_key_part_by_field(KEY *keyinfo, KEY_PART_INFO *key_part_info,
- Field *field);
+ Field *field, uint fieldnr);
void use_index(int key_to_save);
void set_table_map(table_map map_arg, uint tablenr_arg)
{
@@ -1320,6 +1320,7 @@ struct TABLE_LIST
/* If this is a jtbm semi-join object: corresponding subselect predicate */
Item_in_subselect *jtbm_subselect;
+ /* TODO: check if this can be joined with tablenr_exec */
uint jtbm_table_no;
SJ_MATERIALIZATION_INFO *sj_mat_info;
@@ -1445,7 +1446,9 @@ struct TABLE_LIST
table_map view_used_tables;
table_map map_exec;
+ /* TODO: check if this can be joined with jtbm_table_no */
uint tablenr_exec;
+ uint maybe_null_exec;
/* Ptr to parent MERGE table list item. See top comment in ha_myisammrg.cc */
TABLE_LIST *parent_l;
@@ -1765,6 +1768,8 @@ struct TABLE_LIST
respectively.
*/
char *get_table_name() { return view != NULL ? view_name.str : table_name; }
+ bool is_active_sjm();
+ bool is_jtbm() { return test(jtbm_subselect!=NULL); }
st_select_lex_unit *get_unit();
st_select_lex *get_single_select();
void wrap_into_nested_join(List<TABLE_LIST> &join_list);
diff --git a/storage/archive/archive_reader.c b/storage/archive/archive_reader.c
index 0cf795cefdf..90220f26f6d 100644
--- a/storage/archive/archive_reader.c
+++ b/storage/archive/archive_reader.c
@@ -93,12 +93,16 @@ int main(int argc, char *argv[])
printf("\tFRM length %u\n", reader_handle.frm_length);
if (reader_handle.comment_start_pos)
{
- char *comment =
- (char *) malloc(sizeof(char) * reader_handle.comment_length);
- azread_comment(&reader_handle, comment);
- printf("\tComment length %u\n\t\t%.*s\n", reader_handle.comment_length,
- reader_handle.comment_length, comment);
- free(comment);
+ char *comment = (char *) my_malloc(reader_handle.comment_length,
+ MYF(MY_WME));
+ if (comment)
+ {
+ azread_comment(&reader_handle, comment);
+ printf("\tComment length %u\n\t\t%.*s\n",
+ reader_handle.comment_length,
+ reader_handle.comment_length, comment);
+ my_free(comment,MYF(0));
+ }
}
}
else
@@ -180,7 +184,7 @@ int main(int argc, char *argv[])
azio_stream writer_handle;
- buffer= (char *)malloc(reader_handle.longest_row);
+ buffer= (char *) my_malloc(reader_handle.longest_row, MYF(0));
if (buffer == NULL)
{
printf("Could not allocate memory for row %llu\n", row_count);
@@ -251,7 +255,7 @@ int main(int argc, char *argv[])
break;
}
- free(buffer);
+ my_free(buffer, MYF(0));
azclose(&writer_handle);
}
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index d70de0dd13c..f7efaf4566f 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -684,11 +684,11 @@ int ha_archive::create(const char *name, TABLE *table_arg,
{
if (!my_fstat(frm_file, &file_stat, MYF(MY_WME)))
{
- frm_ptr= (uchar *)my_malloc(sizeof(uchar) * file_stat.st_size, MYF(0));
+ frm_ptr= (uchar *)my_malloc(sizeof(uchar) * (size_t)file_stat.st_size, MYF(0));
if (frm_ptr)
{
- my_read(frm_file, frm_ptr, file_stat.st_size, MYF(0));
- azwrite_frm(&create_stream, (char *)frm_ptr, file_stat.st_size);
+ my_read(frm_file, frm_ptr, (size_t)file_stat.st_size, MYF(0));
+ azwrite_frm(&create_stream, (char *)frm_ptr, (size_t)file_stat.st_size);
my_free((uchar*)frm_ptr, MYF(0));
}
}
@@ -835,7 +835,7 @@ int ha_archive::write_row(uchar *buf)
if (!share->archive_write_open)
if (init_archive_writer())
- DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
+ DBUG_RETURN(errno);
if (table->next_number_field && record == table->record[0])
@@ -1020,7 +1020,8 @@ int ha_archive::rnd_init(bool scan)
if (share->crashed)
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
- init_archive_reader();
+ if (init_archive_reader())
+ DBUG_RETURN(errno);
/* We rewind the file so that we can read from the beginning if scan */
if (scan)
@@ -1317,7 +1318,8 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
char* frm_string;
DBUG_ENTER("ha_archive::optimize");
- init_archive_reader();
+ if (init_archive_reader())
+ DBUG_RETURN(errno);
// now we close both our writer and our reader for the rename
if (share->archive_write_open)
@@ -1326,7 +1328,7 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
share->archive_write_open= FALSE;
}
- if (!(frm_string= (char*) malloc(archive.frm_length)))
+ if (!(frm_string= (char*) my_malloc(archive.frm_length, MYF(0))))
return ENOMEM;
azread_frm(&archive, frm_string);
@@ -1337,12 +1339,12 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt)
if (!(azopen(&writer, writer_filename, O_CREAT|O_RDWR|O_BINARY)))
{
- free(frm_string);
+ my_free(frm_string, MYF(0));
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
}
rc= azwrite_frm(&writer, frm_string, archive.frm_length);
- free(frm_string);
+ my_free(frm_string, MYF(0));
if (rc)
{
rc= HA_ERR_CRASHED_ON_USAGE;
@@ -1547,7 +1549,9 @@ int ha_archive::info(uint flag)
if (flag & HA_STATUS_AUTO)
{
- init_archive_reader();
+ if (init_archive_reader())
+ DBUG_RETURN(errno);
+
pthread_mutex_lock(&share->mutex);
azflush(&archive, Z_SYNC_FLUSH);
pthread_mutex_unlock(&share->mutex);
@@ -1626,7 +1630,9 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
Now we will rewind the archive file so that we are positioned at the
start of the file.
*/
- init_archive_reader();
+ if (init_archive_reader())
+ DBUG_RETURN(errno);
+
read_data_header(&archive);
while (!(rc= get_row(&archive, table->record[0])))
count--;
diff --git a/storage/blackhole/plug.in b/storage/blackhole/plug.in
index 2f3b120fa5d..84b7299969b 100644
--- a/storage/blackhole/plug.in
+++ b/storage/blackhole/plug.in
@@ -1,6 +1,5 @@
MYSQL_STORAGE_ENGINE(blackhole,,[Blackhole Storage Engine],
[Basic Write-only Read-never tables], [max,max-no-ndb])
-MYSQL_PLUGIN_DIRECTORY(blackhole, [storage/blackhole])
MYSQL_PLUGIN_STATIC(blackhole, [libblackhole.la])
MYSQL_PLUGIN_DYNAMIC(blackhole, [ha_blackhole.la])
diff --git a/storage/csv/plug.in b/storage/csv/plug.in
index 4ff32959fa2..eb4bd4d9883 100644
--- a/storage/csv/plug.in
+++ b/storage/csv/plug.in
@@ -1,5 +1,4 @@
MYSQL_STORAGE_ENGINE(csv,, [CSV Storage Engine],
[Stores tables in text CSV format])
-MYSQL_PLUGIN_DIRECTORY(csv, [storage/csv])
MYSQL_PLUGIN_STATIC(csv, [libcsv.la])
MYSQL_PLUGIN_MANDATORY(csv) dnl Used for logging
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index 0297451871f..ae45e85c1b3 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -226,7 +226,6 @@ void ha_heap::update_key_stats()
int ha_heap::write_row(uchar * buf)
{
int res;
- ha_statistic_increment(&SSV::ha_write_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
table->timestamp_field->set_time();
if (table->next_number_field && buf == table->record[0])
@@ -250,7 +249,6 @@ int ha_heap::write_row(uchar * buf)
int ha_heap::update_row(const uchar * old_data, uchar * new_data)
{
int res;
- ha_statistic_increment(&SSV::ha_update_count);
if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
table->timestamp_field->set_time();
res= heap_update(file,old_data,new_data);
@@ -269,7 +267,6 @@ int ha_heap::update_row(const uchar * old_data, uchar * new_data)
int ha_heap::delete_row(const uchar * buf)
{
int res;
- ha_statistic_increment(&SSV::ha_delete_count);
res= heap_delete(file,buf);
if (!res && table->s->tmp_table == NO_TMP_TABLE &&
++records_changed*HEAP_STATS_UPDATE_THRESHOLD > file->s->records)
@@ -288,7 +285,6 @@ int ha_heap::index_read_map(uchar *buf, const uchar *key,
enum ha_rkey_function find_flag)
{
DBUG_ASSERT(inited==INDEX);
- ha_statistic_increment(&SSV::ha_read_key_count);
int error = heap_rkey(file,buf,active_index, key, keypart_map, find_flag);
table->status = error ? STATUS_NOT_FOUND : 0;
return error;
@@ -298,7 +294,6 @@ int ha_heap::index_read_last_map(uchar *buf, const uchar *key,
key_part_map keypart_map)
{
DBUG_ASSERT(inited==INDEX);
- ha_statistic_increment(&SSV::ha_read_key_count);
int error= heap_rkey(file, buf, active_index, key, keypart_map,
HA_READ_PREFIX_LAST);
table->status= error ? STATUS_NOT_FOUND : 0;
@@ -309,7 +304,6 @@ int ha_heap::index_read_idx_map(uchar *buf, uint index, const uchar *key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
- ha_statistic_increment(&SSV::ha_read_key_count);
int error = heap_rkey(file, buf, index, key, keypart_map, find_flag);
table->status = error ? STATUS_NOT_FOUND : 0;
return error;
@@ -318,7 +312,6 @@ int ha_heap::index_read_idx_map(uchar *buf, uint index, const uchar *key,
int ha_heap::index_next(uchar * buf)
{
DBUG_ASSERT(inited==INDEX);
- ha_statistic_increment(&SSV::ha_read_next_count);
int error=heap_rnext(file,buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -327,7 +320,6 @@ int ha_heap::index_next(uchar * buf)
int ha_heap::index_prev(uchar * buf)
{
DBUG_ASSERT(inited==INDEX);
- ha_statistic_increment(&SSV::ha_read_prev_count);
int error=heap_rprev(file,buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -336,7 +328,6 @@ int ha_heap::index_prev(uchar * buf)
int ha_heap::index_first(uchar * buf)
{
DBUG_ASSERT(inited==INDEX);
- ha_statistic_increment(&SSV::ha_read_first_count);
int error=heap_rfirst(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -345,7 +336,6 @@ int ha_heap::index_first(uchar * buf)
int ha_heap::index_last(uchar * buf)
{
DBUG_ASSERT(inited==INDEX);
- ha_statistic_increment(&SSV::ha_read_last_count);
int error=heap_rlast(file, buf, active_index);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -358,7 +348,6 @@ int ha_heap::rnd_init(bool scan)
int ha_heap::rnd_next(uchar *buf)
{
- ha_statistic_increment(&SSV::ha_read_rnd_next_count);
int error=heap_scan(file, buf);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
@@ -368,7 +357,6 @@ int ha_heap::rnd_pos(uchar * buf, uchar *pos)
{
int error;
HEAP_PTR heap_position;
- ha_statistic_increment(&SSV::ha_read_rnd_count);
memcpy_fixed((char*) &heap_position, pos, sizeof(HEAP_PTR));
error=heap_rrnd(file, buf, heap_position);
table->status=error ? STATUS_NOT_FOUND: 0;
@@ -582,7 +570,7 @@ int ha_heap::delete_table(const char *name)
void ha_heap::drop_table(const char *name)
{
file->s->delete_on_close= 1;
- close();
+ ha_close();
}
diff --git a/storage/heap/plug.in b/storage/heap/plug.in
index 92ec01d3c88..f1b02b38c2b 100644
--- a/storage/heap/plug.in
+++ b/storage/heap/plug.in
@@ -1,6 +1,5 @@
MYSQL_STORAGE_ENGINE(heap,no, [Memory Storage Engine],
[Volatile memory based tables])
-MYSQL_PLUGIN_DIRECTORY(heap, [storage/heap])
MYSQL_PLUGIN_STATIC(heap, [libheap_s.la], [libheap_embedded.la])
MYSQL_PLUGIN_MANDATORY(heap) dnl Memory tables
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index ce264b1bbb4..eaf5ec4bed5 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1061,7 +1061,29 @@ innobase_mysql_tmpfile(void)
will be passed to fdopen(), it will be closed by invoking
fclose(), which in turn will invoke close() instead of
my_close(). */
+
+#ifdef _WIN32
+ /* Note that on Windows, the integer returned by mysql_tmpfile
+ has no relation to C runtime file descriptor. Here, we need
+ to call my_get_osfhandle to get the HANDLE and then convert it
+ to C runtime filedescriptor. */
+ {
+ HANDLE hFile = my_get_osfhandle(fd);
+ HANDLE hDup;
+ BOOL bOK =
+ DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(),
+ &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
+ if(bOK) {
+ fd2 = _open_osfhandle((intptr_t)hDup,0);
+ }
+ else {
+ my_osmaperr(GetLastError());
+ fd2 = -1;
+ }
+ }
+#else
fd2 = dup(fd);
+#endif
if (fd2 < 0) {
DBUG_PRINT("error",("Got error %d on dup",fd2));
my_errno=errno;
diff --git a/storage/innobase/plug.in.disabled b/storage/innobase/plug.in.disabled
index b18950b9c7a..2d6af1d2883 100644
--- a/storage/innobase/plug.in.disabled
+++ b/storage/innobase/plug.in.disabled
@@ -1,6 +1,5 @@
MYSQL_STORAGE_ENGINE(innobase, innodb, [InnoDB Storage Engine],
[Transactional Tables using InnoDB], [max,max-no-ndb])
-MYSQL_PLUGIN_DIRECTORY(innobase, [storage/innobase])
MYSQL_PLUGIN_STATIC(innobase, [libinnobase.la])
MYSQL_PLUGIN_DYNAMIC(innobase, [ha_innodb.la])
MYSQL_PLUGIN_ACTIONS(innobase, [
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index 38adab109fc..e470616d169 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -49,7 +49,9 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <m_ctype.h>
#include <mysys_err.h>
#include <mysql/plugin.h>
-
+#ifdef _WIN32
+#include <io.h>
+#endif
/** @file ha_innodb.cc */
/* Include necessary InnoDB headers */
@@ -1172,7 +1174,28 @@ innobase_mysql_tmpfile(void)
will be passed to fdopen(), it will be closed by invoking
fclose(), which in turn will invoke close() instead of
my_close(). */
+#ifdef _WIN32
+ /* Note that on Windows, the integer returned by mysql_tmpfile
+ has no relation to C runtime file descriptor. Here, we need
+ to call my_get_osfhandle to get the HANDLE and then convert it
+ to C runtime filedescriptor. */
+ {
+ HANDLE hFile = my_get_osfhandle(fd);
+ HANDLE hDup;
+ BOOL bOK =
+ DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(),
+ &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
+ if(bOK) {
+ fd2 = _open_osfhandle((intptr_t)hDup,0);
+ }
+ else {
+ my_osmaperr(GetLastError());
+ fd2 = -1;
+ }
+ }
+#else
fd2 = dup(fd);
+#endif
if (fd2 < 0) {
DBUG_PRINT("error",("Got error %d on dup",fd2));
my_errno=errno;
diff --git a/storage/innodb_plugin/plug.in b/storage/innodb_plugin/plug.in
index ebaa3f574a0..e5e2def5435 100644
--- a/storage/innodb_plugin/plug.in
+++ b/storage/innodb_plugin/plug.in
@@ -16,7 +16,6 @@
MYSQL_STORAGE_ENGINE(innodb_plugin,, [InnoDB Storage Engine],
[Transactional Tables using InnoDB], [])
-MYSQL_PLUGIN_DIRECTORY(innodb_plugin, [storage/innodb_plugin])
# Enable if you know what you are doing (trying to link both InnoDB and
# InnoDB Plugin statically into MySQL does not work).
#MYSQL_PLUGIN_STATIC(innodb_plugin, [libinnobase.a])
diff --git a/storage/maria/CMakeLists.txt b/storage/maria/CMakeLists.txt
index 7e32d2fe3d8..77083c5839f 100644
--- a/storage/maria/CMakeLists.txt
+++ b/storage/maria/CMakeLists.txt
@@ -50,36 +50,36 @@ MYSQL_STORAGE_ENGINE(ARIA)
IF(NOT SOURCE_SUBLIBS)
- ADD_DEPENDENCIES(aria GenError)
+ ADD_DEPENDENCIES(libaria_s GenError)
MYSQL_ADD_EXECUTABLE(aria_ftdump maria_ftdump.c)
-TARGET_LINK_LIBRARIES(aria_ftdump aria myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(aria_ftdump libaria_s libmyisam_s mysys dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(aria_chk maria_chk.c)
-TARGET_LINK_LIBRARIES(aria_chk aria myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(aria_chk libaria_s libmyisam_s mysys dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(aria_read_log maria_read_log.c)
-TARGET_LINK_LIBRARIES(aria_read_log aria myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(aria_read_log libaria_s libmyisam_s mysys dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(aria_pack maria_pack.c)
-TARGET_LINK_LIBRARIES(aria_pack aria myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(aria_pack libaria_s libmyisam_s mysys dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(aria_dump_log maria_dump_log.c unittest/ma_loghandler_examples.c)
-TARGET_LINK_LIBRARIES(aria_dump_log aria myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(aria_dump_log libaria_s libmyisam_s mysys dbug strings zlib wsock32)
ADD_EXECUTABLE(ma_test1 ma_test1.c)
-TARGET_LINK_LIBRARIES(ma_test1 aria myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(ma_test1 libaria_s libmyisam_s mysys dbug strings zlib wsock32)
ADD_EXECUTABLE(ma_test2 ma_test2.c)
-TARGET_LINK_LIBRARIES(ma_test2 aria myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(ma_test2 libaria_s libmyisam_s mysys dbug strings zlib wsock32)
ADD_EXECUTABLE(ma_test3 ma_test3.c)
-TARGET_LINK_LIBRARIES(ma_test3 aria myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(ma_test3 libaria_s libmyisam_s mysys dbug strings zlib wsock32)
ADD_EXECUTABLE(ma_rt_test ma_rt_test.c)
-TARGET_LINK_LIBRARIES(ma_rt_test aria myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(ma_rt_test libaria_s libmyisam_s mysys dbug strings zlib wsock32)
ADD_EXECUTABLE(ma_sp_test ma_sp_test.c)
-TARGET_LINK_LIBRARIES(ma_sp_test aria myisam mysys dbug strings zlib wsock32)
+TARGET_LINK_LIBRARIES(ma_sp_test libaria_s libmyisam_s mysys dbug strings zlib wsock32)
ENDIF(NOT SOURCE_SUBLIBS)
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 4963e6e7a04..a6636316efb 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -150,10 +150,16 @@ static MYSQL_SYSVAR_ULONG(block_size, maria_block_size,
static MYSQL_SYSVAR_ULONG(checkpoint_interval, checkpoint_interval,
PLUGIN_VAR_RQCMDARG,
- "Interval between automatic checkpoints, in seconds; 0 means"
+ "Interval between tries to do an automatic checkpoints. In seconds; 0 means"
" 'no automatic checkpoints' which makes sense only for testing.",
NULL, update_checkpoint_interval, 30, 0, UINT_MAX, 1);
+static MYSQL_SYSVAR_ULONG(checkpoint_log_activity, maria_checkpoint_min_log_activity,
+ PLUGIN_VAR_RQCMDARG,
+ "Number of bytes that the transaction log has to grow between checkpoints before a new "
+ "checkpoint is written to the log.",
+ NULL, NULL, 1024*1024, 0, UINT_MAX, 1);
+
static MYSQL_SYSVAR_ULONG(force_start_after_recovery_failures,
force_start_after_recovery_failures,
/*
@@ -304,7 +310,7 @@ static void _ma_check_print_msg(HA_CHECK *param, const char *msg_type,
if (!thd->vio_ok())
{
- sql_print_error(fmt, args);
+ sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf);
return;
}
@@ -312,6 +318,8 @@ static void _ma_check_print_msg(HA_CHECK *param, const char *msg_type,
(T_CREATE_MISSING_KEYS | T_SAFE_REPAIR | T_AUTO_REPAIR))
{
my_message(ER_NOT_KEYFILE, msgbuf, MYF(MY_WME));
+ if (thd->variables.log_warnings > 2)
+ sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf);
return;
}
length= (uint) (strxmov(name, param->db_name, ".", param->table_name,
@@ -330,8 +338,11 @@ static void _ma_check_print_msg(HA_CHECK *param, const char *msg_type,
protocol->store(msg_type, system_charset_info);
protocol->store(msgbuf, msg_length, system_charset_info);
if (protocol->write())
- sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
- msgbuf);
+ sql_print_error("Failed on my_net_write, writing to stderr instead: %s.%s: %s\n",
+ param->db_name, param->table_name, msgbuf);
+ else if (thd->variables.log_warnings > 2)
+ sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf);
+
return;
}
@@ -711,6 +722,34 @@ int _ma_killed_ptr(HA_CHECK *param)
}
+/*
+ Report progress to mysqld
+
+ This is a bit more complex than what a normal progress report
+ function normally is.
+
+ The reason is that this is called by enable_index/repair which
+ is one stage in ALTER TABLE and we can't use the external
+ stage/max_stage for this.
+
+ thd_progress_init/thd_progress_next_stage is to be called by
+ high level commands like CHECK TABLE or REPAIR TABLE, not
+ by sub commands like enable_index().
+
+ In ma_check.c it's easier to work with stages than with a total
+ progress, so we use internal stage/max_stage here to keep the
+ code simple.
+*/
+
+void _ma_report_progress(HA_CHECK *param, ulonglong progress,
+ ulonglong max_progress)
+{
+ thd_progress_report((THD*)param->thd,
+ progress + max_progress * param->stage,
+ max_progress * param->max_stage);
+}
+
+
void _ma_check_print_error(HA_CHECK *param, const char *fmt, ...)
{
va_list args;
@@ -881,7 +920,7 @@ double ha_maria::scan_time()
}
/*
- We need to be able to store at least two keys on an index page as the
+ We need to be able to store at least 2 keys on an index page as the
splitting algorithms depends on this. (With only one key on a page
we also can't use any compression, which may make the index file much
larger)
@@ -896,8 +935,7 @@ double ha_maria::scan_time()
uint ha_maria::max_supported_key_length() const
{
- uint tmp= (maria_max_key_length() - 8 - HA_MAX_KEY_SEG*3);
- return min(HA_MAX_KEY_BUFF, tmp);
+ return maria_max_key_length();
}
@@ -1104,7 +1142,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
int error;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
MARIA_SHARE *share= file->s;
- const char *old_proc_info= thd_proc_info(thd, "Checking table");
+ const char *old_proc_info;
TRN *old_trn= file->trn;
if (!file || !&param) return HA_ADMIN_INTERNAL_ERROR;
@@ -1132,12 +1170,18 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
return HA_ADMIN_ALREADY_DONE;
maria_chk_init_for_check(&param, file);
+ old_proc_info= thd_proc_info(thd, "Checking status");
+ thd_progress_init(thd, 3);
(void) maria_chk_status(&param, file); // Not fatal
error= maria_chk_size(&param, file);
if (!error)
error|= maria_chk_del(&param, file, param.testflag);
+ thd_proc_info(thd, "Checking keys");
+ thd_progress_next_stage(thd);
if (!error)
error= maria_chk_key(&param, file);
+ thd_proc_info(thd, "Checking data");
+ thd_progress_next_stage(thd);
if (!error)
{
if ((!(param.testflag & T_QUICK) &&
@@ -1188,6 +1232,7 @@ int ha_maria::check(THD * thd, HA_CHECK_OPT * check_opt)
/* Reset trn, that may have been set by repair */
_ma_set_trn_for_table(file, old_trn);
thd_proc_info(thd, old_proc_info);
+ thd_progress_end(thd);
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
}
@@ -1203,6 +1248,7 @@ int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt)
int error= 0;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
MARIA_SHARE *share= file->s;
+ const char *old_proc_info;
if (!&param)
return HA_ADMIN_INTERNAL_ERROR;
@@ -1220,6 +1266,8 @@ int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt)
if (!(share->state.changed & STATE_NOT_ANALYZED))
return HA_ADMIN_ALREADY_DONE;
+ old_proc_info= thd_proc_info(thd, "Scanning");
+ thd_progress_init(thd, 1);
error= maria_chk_key(&param, file);
if (!error)
{
@@ -1229,6 +1277,8 @@ int ha_maria::analyze(THD *thd, HA_CHECK_OPT * check_opt)
}
else if (!maria_is_crashed(file) && !thd->killed)
maria_mark_crashed(file);
+ thd_proc_info(thd, old_proc_info);
+ thd_progress_end(thd);
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
}
@@ -1362,6 +1412,7 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
int error;
HA_CHECK &param= *(HA_CHECK*) thd->alloc(sizeof(param));
ha_rows start_records;
+ const char *old_proc_info;
if (!file || !&param)
return HA_ADMIN_INTERNAL_ERROR;
@@ -1375,6 +1426,8 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
param.backup_time= check_opt->start_time;
start_records= file->state->records;
+ old_proc_info= thd_proc_info(thd, "Checking table");
+ thd_progress_init(thd, 1);
while ((error= repair(thd, &param, 0)) && param.retry_repair)
{
param.retry_repair= 0;
@@ -1410,6 +1463,8 @@ int ha_maria::repair(THD * thd, HA_CHECK_OPT *check_opt)
llstr(start_records, llbuff2),
table->s->path.str);
}
+ thd_proc_info(thd, old_proc_info);
+ thd_progress_end(thd);
return error;
}
@@ -1457,14 +1512,15 @@ int ha_maria::optimize(THD * thd, HA_CHECK_OPT *check_opt)
param.testflag= (check_opt->flags | T_SILENT | T_FORCE_CREATE |
T_REP_BY_SORT | T_STATISTICS | T_SORT_INDEX);
param.sort_buffer_length= THDVAR(thd, sort_buffer_size);
+ thd_progress_init(thd, 1);
if ((error= repair(thd, &param, 1)) && param.retry_repair)
{
sql_print_warning("Warning: Optimize table got errno %d on %s.%s, retrying",
my_errno, param.db_name, param.table_name);
param.testflag &= ~T_REP_BY_SORT;
- error= repair(thd, &param, 1);
+ error= repair(thd, &param, 0);
}
-
+ thd_progress_end(thd);
return error;
}
@@ -1638,6 +1694,7 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
}
pthread_mutex_unlock(&share->intern_lock);
thd_proc_info(thd, old_proc_info);
+ thd_progress_end(thd); // Mark done
if (!thd->locked_tables)
maria_lock_database(file, F_UNLCK);
@@ -1999,19 +2056,21 @@ void ha_maria::start_bulk_insert(ha_rows rows)
we don't want to update the key statistics based of only a few rows.
Index file rebuild requires an exclusive lock, so if versioning is on
don't do it (see how ha_maria::store_lock() tries to predict repair).
- We can repair index only if we have an exclusive (TL_WRITE) lock. To
- see if table is empty, we shouldn't rely on the old records' count from
- our transaction's start (if that old count is 0 but now there are
- records in the table, we would wrongly destroy them).
- So we need to look at share->state.state.records.
- As a safety net for now, we don't remove the test of
- file->state->records, because there is uncertainty on what will happen
- during repair if the two states disagree.
+ We can repair index only if we have an exclusive (TL_WRITE) lock or
+ if this is inside an ALTER TABLE, in which case lock_type == TL_UNLOCK.
+
+ To see if table is empty, we shouldn't rely on the old record
+ count from our transaction's start (if that old count is 0 but
+ now there are records in the table, we would wrongly destroy
+ them). So we need to look at share->state.state.records. As a
+ safety net for now, we don't remove the test of
+ file->state->records, because there is uncertainty on what will
+ happen during repair if the two states disagree.
*/
if ((file->state->records == 0) &&
(share->state.state.records == 0) && can_enable_indexes &&
(!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES) &&
- (file->lock.type == TL_WRITE))
+ (file->lock.type == TL_WRITE || file->lock.type == TL_UNLOCK))
{
/**
@todo for a single-row INSERT SELECT, we will go into repair, which
@@ -2135,13 +2194,17 @@ bool ha_maria::check_and_repair(THD *thd)
if (crashed)
{
+ bool save_log_all_errors;
sql_print_warning("Recovering table: '%s'", table->s->path.str);
+ save_log_all_errors= thd->log_all_errors;
+ thd->log_all_errors|= (thd->variables.log_warnings > 2);
check_opt.flags=
((maria_recover_options & HA_RECOVER_BACKUP ? T_BACKUP_DATA : 0) |
(maria_recover_options & HA_RECOVER_FORCE ? 0 : T_SAFE_REPAIR) |
T_AUTO_REPAIR);
if (repair(thd, &check_opt))
error= 1;
+ thd->log_all_errors= save_log_all_errors;
}
pthread_mutex_lock(&LOCK_thread_count);
thd->query_string= old_query;
@@ -2210,7 +2273,15 @@ int ha_maria::index_read_idx_map(uchar * buf, uint index, const uchar * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
- int error= maria_rkey(file, buf, index, key, keypart_map, find_flag);
+ int error;
+ /* Use the pushed index condition if it matches the index we're scanning */
+ end_range= NULL;
+ if (index == pushed_idx_cond_keyno)
+ ma_set_index_cond_func(file, index_cond_func_maria, this);
+
+ error= maria_rkey(file, buf, index, key, keypart_map, find_flag);
+
+ ma_set_index_cond_func(file, NULL, 0);
table->status= error ? STATUS_NOT_FOUND : 0;
return error;
}
@@ -2467,9 +2538,6 @@ int ha_maria::extra(enum ha_extra_function operation)
int ha_maria::reset(void)
{
- pushed_idx_cond= NULL;
- pushed_idx_cond_keyno= MAX_KEY;
- in_range_check_pushed_down= FALSE;
ma_set_index_cond_func(file, NULL, 0);
ds_mrr.dsmrr_close();
if (file->trn)
@@ -2524,11 +2592,19 @@ int ha_maria::delete_table(const char *name)
void ha_maria::drop_table(const char *name)
{
DBUG_ASSERT(file->s->temporary);
- (void) close();
+ (void) ha_close();
(void) maria_delete_table_files(name, 0);
}
+void ha_maria::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
+{
+ handler::change_table_ptr(table_arg, share);
+ if (file)
+ file->external_ref= table_arg;
+}
+
+
int ha_maria::external_lock(THD *thd, int lock_type)
{
DBUG_ENTER("ha_maria::external_lock");
@@ -2629,7 +2705,7 @@ int ha_maria::external_lock(THD *thd, int lock_type)
changes to commit (rollback shouldn't be tested).
*/
DBUG_ASSERT(!thd->main_da.is_sent ||
- thd->killed == THD::KILL_CONNECTION);
+ thd->killed == KILL_CONNECTION);
/* autocommit ? rollback a transaction */
#ifdef MARIA_CANNOT_ROLLBACK
if (ma_commit(trn))
@@ -3464,7 +3540,7 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name,
*engine_data= 0;
if (file->s->now_transactional && file->s->have_versioning)
- return (file->trn->trid >= file->s->state.last_change_trn);
+ DBUG_RETURN(file->trn->trid >= file->s->state.last_change_trn);
/*
If a concurrent INSERT has happened just before the currently processed
@@ -3499,6 +3575,7 @@ my_bool ha_maria::register_query_cache_table(THD *thd, char *table_name,
struct st_mysql_sys_var* system_variables[]= {
MYSQL_SYSVAR(block_size),
MYSQL_SYSVAR(checkpoint_interval),
+ MYSQL_SYSVAR(checkpoint_log_activity),
MYSQL_SYSVAR(force_start_after_recovery_failures),
MYSQL_SYSVAR(group_commit),
MYSQL_SYSVAR(group_commit_interval),
@@ -3532,6 +3609,7 @@ static void update_checkpoint_interval(MYSQL_THD thd,
ma_checkpoint_init(*(ulong *)var_ptr= (ulong)(*(long *)save));
}
+
/**
@brief Updates group commit mode
*/
diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h
index 0ba134a5b45..26b616e9682 100644
--- a/storage/maria/ha_maria.h
+++ b/storage/maria/ha_maria.h
@@ -77,6 +77,7 @@ public:
{ return max_supported_key_length(); }
enum row_type get_row_type() const;
uint checksum() const;
+ void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
virtual double scan_time();
int open(const char *name, int mode, uint test_if_locked);
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index 5b3be5d7bf4..18ea1fc3997 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -176,6 +176,7 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
PAGECACHE_LOCK_LEFT_UNLOCKED,
PAGECACHE_PIN_LEFT_UNPINNED,
PAGECACHE_WRITE_DELAY, 0, LSN_IMPOSSIBLE);
+ DBUG_ASSERT(!res);
DBUG_RETURN(res);
}
else
@@ -199,6 +200,7 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
page_link.unlock= PAGECACHE_LOCK_LEFT_UNLOCKED;
page_link.changed= 1;
push_dynamic(&bitmap->pinned_pages, (const uchar*) (void*) &page_link);
+ DBUG_ASSERT(!res);
DBUG_RETURN(res);
}
}
@@ -209,7 +211,10 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
SYNOPSIS
_ma_bitmap_init()
share Share handler
- file data file handler
+ file Data file handler
+ last_page Pointer to last page (max_file_size) that needs to be
+ mapped by the bitmap. This is adjusted to bitmap
+ alignment.
NOTES
This is called the first time a file is opened.
@@ -219,12 +224,14 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
1 error
*/
-my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
+my_bool _ma_bitmap_init(MARIA_SHARE *share, File file,
+ pgcache_page_no_t *last_page)
{
uint aligned_bit_blocks;
uint max_page_size;
MARIA_FILE_BITMAP *bitmap= &share->bitmap;
uint size= share->block_size;
+ pgcache_page_no_t first_bitmap_with_space;
#ifndef DBUG_OFF
/* We want to have a copy of the bitmap to be able to print differences */
size*= 2;
@@ -241,7 +248,7 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
/* Size needs to be aligned on 6 */
aligned_bit_blocks= (share->block_size - PAGE_SUFFIX_SIZE) / 6;
- bitmap->total_size= aligned_bit_blocks * 6;
+ bitmap->max_total_size= bitmap->total_size= aligned_bit_blocks * 6;
/*
In each 6 bytes, we have 6*8/3 = 16 pages covered
The +1 is to add the bitmap page, as this doesn't have to be covered
@@ -266,13 +273,35 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file)
pthread_mutex_init(&share->bitmap.bitmap_lock, MY_MUTEX_INIT_SLOW);
pthread_cond_init(&share->bitmap.bitmap_cond, 0);
+ first_bitmap_with_space= share->state.first_bitmap_with_space;
_ma_bitmap_reset_cache(share);
- if (share->state.first_bitmap_with_space == ~(pgcache_page_no_t) 0)
+ /*
+ The bitmap used to map the file are aligned on 6 bytes. We now
+ calculate the max file size that can be used by the bitmap. This
+ is needed to get ma_info() give a true file size so that the user can
+ estimate if there is still space free for records in the file.
+ */
{
- /* Start scanning for free space from start of file */
- share->state.first_bitmap_with_space = 0;
+ pgcache_page_no_t last_bitmap_page;
+ pgcache_page_no_t blocks, bytes;
+
+ last_bitmap_page= *last_page - *last_page % bitmap->pages_covered;
+ blocks= *last_page - last_bitmap_page;
+ bytes= (blocks * 3) / 8; /* 3 bit per page / 8 bits per byte */
+ /* Size needs to be aligned on 6 */
+ bytes/= 6;
+ bytes*= 6;
+ bitmap->last_bitmap_page= last_bitmap_page;
+ bitmap->last_total_size= bytes;
+ *last_page= ((last_bitmap_page + bytes*8/3));
}
+
+ /* Restore first_bitmap_with_space if it's resonable */
+ if (first_bitmap_with_space <= (share->state.state.data_file_length /
+ share->block_size))
+ share->state.first_bitmap_with_space= first_bitmap_with_space;
+
return 0;
}
@@ -310,6 +339,40 @@ my_bool _ma_bitmap_end(MARIA_SHARE *share)
return res;
}
+/*
+ Ensure that we have incremented open count before we try to read/write
+ a page while we have the bitmap lock.
+ This is needed to ensure that we don't call _ma_mark_file_changed() as
+ part of flushing a page to disk, as this locks share->internal_lock
+ and then mutex lock would happen in the wrong order.
+*/
+
+static inline void _ma_bitmap_mark_file_changed(MARIA_SHARE *share,
+ my_bool flush_translog)
+{
+ /*
+ It's extremely unlikely that the following test is true as it
+ only happens once if the table has changed.
+ */
+ if (unlikely(!share->global_changed &&
+ (share->state.changed & STATE_CHANGED)))
+ {
+ /* purecov: begin inspected */
+ /* unlock mutex as it can't be hold during _ma_mark_file_changed() */
+ pthread_mutex_unlock(&share->bitmap.bitmap_lock);
+
+ /*
+ We have to flush the translog to ensure we have registered that the
+ table is open.
+ */
+ if (flush_translog && share->now_transactional)
+ (void) translog_flush(share->state.logrec_file_id);
+
+ _ma_mark_file_changed(share);
+ pthread_mutex_lock(&share->bitmap.bitmap_lock);
+ /* purecov: end */
+ }
+}
/*
Send updated bitmap to the page cache
@@ -346,6 +409,12 @@ my_bool _ma_bitmap_flush(MARIA_SHARE *share)
pthread_mutex_lock(&share->bitmap.bitmap_lock);
if (share->bitmap.changed)
{
+ /*
+ We have to mark the file changed here, as otherwise the following
+ write to pagecache may force a page out from this file, which would
+ cause _ma_mark_file_changed() to be called with bitmaplock hold!
+ */
+ _ma_bitmap_mark_file_changed(share, 1);
res= write_changed_bitmap(share, &share->bitmap);
share->bitmap.changed= 0;
}
@@ -413,24 +482,13 @@ my_bool _ma_bitmap_flush_all(MARIA_SHARE *share)
DBUG_RETURN(0);
}
+ _ma_bitmap_mark_file_changed(share, 0);
+
/*
- Before flusing bitmap, ensure that we have incremented open count.
- This is needed to ensure that we don't call
- _ma_mark_file_changed() as part of flushing bitmap page as in this
- case we would use mutex lock in wrong order.
- It's extremely unlikely that the following test is true as normally
- this is happening when table is flushed.
+ The following should be true as it was tested above. We have to test
+ this again as _ma_bitmap_mark_file_changed() did temporarly release
+ the bitmap mutex.
*/
- if (unlikely(!share->global_changed))
- {
- /* purecov: begin inspected */
- /* unlock bitmap mutex as it can't be hold during _ma_mark_file_changed */
- pthread_mutex_unlock(&bitmap->bitmap_lock);
- _ma_mark_file_changed(share);
- pthread_mutex_lock(&bitmap->bitmap_lock);
- /* purecov: end */
- }
-
if (bitmap->changed || bitmap->changed_not_flushed)
{
bitmap->flush_all_requested++;
@@ -616,7 +674,7 @@ void _ma_bitmap_delete_all(MARIA_SHARE *share)
bzero(bitmap->map, bitmap->block_size);
bitmap->changed= 1;
bitmap->page= 0;
- bitmap->used_size= bitmap->total_size;
+ bitmap->used_size= bitmap->total_size= bitmap->max_total_size;
}
DBUG_VOID_RETURN;
}
@@ -630,7 +688,8 @@ void _ma_bitmap_delete_all(MARIA_SHARE *share)
@notes
This is called after we have swapped file descriptors and we want
- bitmap to forget all cached information
+ bitmap to forget all cached information.
+ It's also called directly after we have opened a file.
*/
void _ma_bitmap_reset_cache(MARIA_SHARE *share)
@@ -646,13 +705,20 @@ void _ma_bitmap_reset_cache(MARIA_SHARE *share)
We can't read a page yet, as in some case we don't have an active
page cache yet.
Pretend we have a dummy, full and not changed bitmap page in memory.
+
+ We set bitmap->page to a value so that if we use it in
+ move_to_next_bitmap() it will point to page 0.
+ (This can only happen if writing to a bitmap page fails)
*/
- bitmap->page= ~(ulonglong) 0;
- bitmap->used_size= bitmap->total_size;
+ bitmap->page= ((pgcache_page_no_t) 0) - bitmap->pages_covered;
+ bitmap->used_size= bitmap->total_size= bitmap->max_total_size;
bfill(bitmap->map, share->block_size, 255);
#ifndef DBUG_OFF
memcpy(bitmap->map + bitmap->block_size, bitmap->map, bitmap->block_size);
#endif
+
+ /* Start scanning for free space from start of file */
+ share->state.first_bitmap_with_space = 0;
}
}
@@ -841,7 +907,7 @@ void _ma_print_bitmap(MARIA_FILE_BITMAP *bitmap, uchar *data,
fprintf(DBUG_FILE,"\nDump of bitmap page at %s\n", llstr(page, llbuff));
page++; /* Skip bitmap page */
- for (pos= data, end= pos + bitmap->total_size;
+ for (pos= data, end= pos + bitmap->max_total_size;
pos < end ;
pos+= 6)
{
@@ -920,6 +986,20 @@ void _ma_get_bitmap_description(MARIA_FILE_BITMAP *bitmap,
}
+/*
+ Adjust bitmap->total_size to not go over max_data_file_size
+*/
+
+static void adjust_total_size(MARIA_HA *info, pgcache_page_no_t page)
+{
+ MARIA_FILE_BITMAP *bitmap= &info->s->bitmap;
+
+ if (page < bitmap->last_bitmap_page)
+ bitmap->total_size= bitmap->max_total_size; /* Use all bits in bitmap */
+ else
+ bitmap->total_size= bitmap->last_total_size;
+}
+
/***************************************************************************
Reading & writing bitmap pages
***************************************************************************/
@@ -956,12 +1036,16 @@ static my_bool _ma_read_bitmap_page(MARIA_HA *info,
DBUG_ASSERT(!bitmap->changed);
bitmap->page= page;
- if (((page + 1) * bitmap->block_size) > share->state.state.data_file_length)
+ if ((page + 1) * bitmap->block_size > share->state.state.data_file_length)
{
/* Inexistent or half-created page */
res= _ma_bitmap_create_missing(info, bitmap, page);
+ if (!res)
+ adjust_total_size(info, page);
DBUG_RETURN(res);
}
+
+ adjust_total_size(info, page);
bitmap->used_size= bitmap->total_size;
DBUG_ASSERT(share->pagecache->block_size == bitmap->block_size);
res= pagecache_read(share->pagecache,
@@ -1010,6 +1094,13 @@ static my_bool _ma_change_bitmap_page(MARIA_HA *info,
{
DBUG_ENTER("_ma_change_bitmap_page");
+ /*
+ We have to mark the file changed here, as otherwise the following
+ read/write to pagecache may force a page out from this file, which would
+ cause _ma_mark_file_changed() to be called with bitmaplock hold!
+ */
+ _ma_bitmap_mark_file_changed(info->s, 1);
+
if (bitmap->changed)
{
if (write_changed_bitmap(info->s, bitmap))
@@ -1045,14 +1136,18 @@ static my_bool move_to_next_bitmap(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap)
MARIA_STATE_INFO *state= &info->s->state;
DBUG_ENTER("move_to_next_bitmap");
- if (state->first_bitmap_with_space != ~(ulonglong) 0 &&
+ if (state->first_bitmap_with_space != ~(pgcache_page_no_t) 0 &&
state->first_bitmap_with_space != page)
{
page= state->first_bitmap_with_space;
- state->first_bitmap_with_space= ~(ulonglong) 0;
+ state->first_bitmap_with_space= ~(pgcache_page_no_t) 0;
+ DBUG_ASSERT(page % bitmap->pages_covered == 0);
}
else
+ {
page+= bitmap->pages_covered;
+ DBUG_ASSERT(page % bitmap->pages_covered == 0);
+ }
DBUG_RETURN(_ma_change_bitmap_page(info, bitmap, page));
}
@@ -1318,7 +1413,7 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
uchar *page_end= data + bitmap->total_size;
uchar *best_data= 0;
uint min_size;
- uint best_area_size, best_prefix_area_size, best_suffix_area_size;
+ uint best_area_size, best_prefix_area_size;
uint page, size;
ulonglong best_prefix_bits;
DBUG_ENTER("allocate_full_pages");
@@ -1327,7 +1422,6 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
/* Following variables are only used if best_data is set */
LINT_INIT(best_prefix_bits);
LINT_INIT(best_prefix_area_size);
- LINT_INIT(best_suffix_area_size);
min_size= pages_needed;
if (!full_page && min_size > BLOB_SEGMENT_MIN_SIZE)
@@ -1399,7 +1493,6 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
best_area_size= area_size;
best_prefix_bits= prefix_bits;
best_prefix_area_size= prefix_area_size;
- best_suffix_area_size= suffix_area_size;
/* Prefer to put data in biggest possible area */
if (area_size <= pages_needed)
@@ -1447,10 +1540,7 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
best_prefix_bits|= tmp;
int6store(best_data, best_prefix_bits);
if (!(best_area_size-= best_prefix_area_size))
- {
- DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
- DBUG_RETURN(block->page_count);
- }
+ goto end;
best_data+= 6;
}
best_area_size*= 3; /* Bits to set */
@@ -1468,6 +1558,7 @@ static ulong allocate_full_pages(MARIA_FILE_BITMAP *bitmap,
bitmap->used_size= (uint) (best_data - bitmap->map);
DBUG_ASSERT(bitmap->used_size <= bitmap->total_size);
}
+end:
bitmap->changed= 1;
DBUG_EXECUTE("bitmap", _ma_print_bitmap_changes(bitmap););
DBUG_RETURN(block->page_count);
@@ -1760,7 +1851,7 @@ static void use_head(MARIA_HA *info, pgcache_page_no_t page, uint size,
find_where_to_split_row()
share Maria share
row Information of what is in the row (from calc_record_size())
- extents_length Number of bytes needed to store all extents
+ extents Max number of extents we have to store in header
split_size Free size on the page (The head length must be less
than this)
@@ -1769,7 +1860,7 @@ static void use_head(MARIA_HA *info, pgcache_page_no_t page, uint size,
*/
static uint find_where_to_split_row(MARIA_SHARE *share, MARIA_ROW *row,
- uint extents_length, uint split_size)
+ uint extents, uint split_size)
{
uint *lengths, *lengths_end;
/*
@@ -1779,19 +1870,20 @@ static uint find_where_to_split_row(MARIA_SHARE *share, MARIA_ROW *row,
- One extent
*/
uint row_length= (row->min_length +
- size_to_store_key_length(extents_length) +
+ size_to_store_key_length(extents) +
ROW_EXTENT_SIZE);
- DBUG_ASSERT(row_length < split_size);
+ DBUG_ASSERT(row_length <= split_size);
+
/*
Store first in all_field_lengths the different parts that are written
to the row. This needs to be in same order as in
ma_block_rec.c::write_block_record()
*/
- row->null_field_lengths[-3]= extents_length;
+ row->null_field_lengths[-3]= extents * ROW_EXTENT_SIZE;
row->null_field_lengths[-2]= share->base.fixed_not_null_fields_length;
row->null_field_lengths[-1]= row->field_lengths_length;
for (lengths= row->null_field_lengths - EXTRA_LENGTH_FIELDS,
- lengths_end= (lengths + share->base.pack_fields - share->base.blobs +
+ lengths_end= (lengths + share->base.fields - share->base.blobs +
EXTRA_LENGTH_FIELDS); lengths < lengths_end; lengths++)
{
if (row_length + *lengths > split_size)
@@ -1947,18 +2039,19 @@ my_bool _ma_bitmap_find_place(MARIA_HA *info, MARIA_ROW *row,
head_length+= ELEMENTS_RESERVED_FOR_MAIN_PART * ROW_EXTENT_SIZE;
/* The first segment size is stored in 'row_length' */
- row_length= find_where_to_split_row(share, row, extents_length,
+ row_length= find_where_to_split_row(share, row, row->extents_count +
+ ELEMENTS_RESERVED_FOR_MAIN_PART-1,
max_page_size);
full_page_size= MAX_TAIL_SIZE(share->block_size);
position= 0;
- if (head_length - row_length <= full_page_size)
+ rest_length= head_length - row_length;
+ if (rest_length <= full_page_size)
position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */
if (find_head(info, row_length, position))
goto abort;
row->space_on_head_page= row_length;
- rest_length= head_length - row_length;
if (write_rest_of_head(info, position, rest_length))
goto abort;
@@ -2025,8 +2118,7 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row,
goto abort;
/* Switch bitmap to current head page */
- bitmap_page= page / share->bitmap.pages_covered;
- bitmap_page*= share->bitmap.pages_covered;
+ bitmap_page= page - page % share->bitmap.pages_covered;
if (share->bitmap.page != bitmap_page &&
_ma_change_bitmap_page(info, &share->bitmap, bitmap_page))
@@ -2045,16 +2137,22 @@ my_bool _ma_bitmap_find_new_place(MARIA_HA *info, MARIA_ROW *row,
/* Allocate enough space */
head_length+= ELEMENTS_RESERVED_FOR_MAIN_PART * ROW_EXTENT_SIZE;
- /* The first segment size is stored in 'row_length' */
- row_length= find_where_to_split_row(share, row, extents_length, free_size);
+ /*
+ The first segment size is stored in 'row_length'
+ We have to add ELEMENTS_RESERVED_FOR_MAIN_PART here as the extent
+ information may be up to this size when the header splits.
+ */
+ row_length= find_where_to_split_row(share, row, row->extents_count +
+ ELEMENTS_RESERVED_FOR_MAIN_PART-1,
+ free_size);
position= 0;
- if (head_length - row_length < MAX_TAIL_SIZE(share->block_size))
+ rest_length= head_length - row_length;
+ if (rest_length <= MAX_TAIL_SIZE(share->block_size))
position= ELEMENTS_RESERVED_FOR_MAIN_PART -2; /* Only head and tail */
use_head(info, page, row_length, position);
row->space_on_head_page= row_length;
- rest_length= head_length - row_length;
if (write_rest_of_head(info, position, rest_length))
goto abort;
@@ -2142,7 +2240,7 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
Get bitmap pattern for a given page
SYNOPSIS
- get_page_bits()
+ bitmap_get_page_bits()
info Maria handler
bitmap Bitmap handler
page Page number
@@ -2152,8 +2250,8 @@ static my_bool set_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
~0 Error (couldn't read page)
*/
-uint _ma_bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
- pgcache_page_no_t page)
+static uint bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
+ pgcache_page_no_t page)
{
pgcache_page_no_t bitmap_page;
uint offset_page, offset, tmp;
@@ -2179,6 +2277,19 @@ uint _ma_bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
}
+/* As above, but take a lock while getting the data */
+
+uint _ma_bitmap_get_page_bits(MARIA_HA *info, MARIA_FILE_BITMAP *bitmap,
+ pgcache_page_no_t page)
+{
+ uint tmp;
+ pthread_mutex_lock(&bitmap->bitmap_lock);
+ tmp= bitmap_get_page_bits(info, bitmap, page);
+ pthread_mutex_unlock(&bitmap->bitmap_lock);
+ return tmp;
+}
+
+
/*
Mark all pages in a region as free
@@ -2258,6 +2369,7 @@ my_bool _ma_bitmap_reset_full_page_bits(MARIA_HA *info,
DBUG_RETURN(0);
}
+
/*
Set all pages in a region as used
@@ -2290,7 +2402,7 @@ my_bool _ma_bitmap_set_full_page_bits(MARIA_HA *info,
bitmap_page= page - page % bitmap->pages_covered;
if (page == bitmap_page ||
- page + page_count >= bitmap_page + bitmap->pages_covered)
+ page + page_count > bitmap_page + bitmap->pages_covered)
{
DBUG_ASSERT(0); /* Wrong in data */
DBUG_RETURN(1);
@@ -2494,7 +2606,7 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks)
else
{
DBUG_ASSERT(current_bitmap_value ==
- _ma_bitmap_get_page_bits(info, bitmap, block->page));
+ bitmap_get_page_bits(info, bitmap, block->page));
}
/* Handle all full pages and tail pages (for head page and blob) */
@@ -2526,7 +2638,7 @@ my_bool _ma_bitmap_release_unused(MARIA_HA *info, MARIA_BITMAP_BLOCKS *blocks)
to not set the bits to the same value as before.
*/
DBUG_ASSERT(current_bitmap_value ==
- _ma_bitmap_get_page_bits(info, bitmap, block->page));
+ bitmap_get_page_bits(info, bitmap, block->page));
if (bits != current_bitmap_value)
{
@@ -2935,6 +3047,11 @@ static my_bool _ma_bitmap_create_missing(MARIA_HA *info,
/* First (in offset order) bitmap page to create */
if (data_file_length < block_size)
goto err; /* corrupted, should have first bitmap page */
+ if (page * block_size >= share->base.max_data_file_length)
+ {
+ my_errno= HA_ERR_RECORD_FILE_FULL;
+ goto err;
+ }
from= (data_file_length / block_size - 1) / bitmap->pages_covered + 1;
from*= bitmap->pages_covered;
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index c3b6110f4d1..670be915570 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -414,14 +414,29 @@ void _ma_init_block_record_data(void)
my_bool _ma_once_init_block_record(MARIA_SHARE *share, File data_file)
{
+ my_bool res;
+ pgcache_page_no_t last_page;
+
+ /*
+ First calculate the max file length with can have with a pointer of size
+ rec_reflength.
- share->base.max_data_file_length=
- (((ulonglong) 1 << ((share->base.rec_reflength-1)*8))-1) *
- share->block_size;
+ The 'rec_reflength - 1' is because one byte is used for row
+ position withing the page.
+ The /2 comes from _ma_transaction_recpos_to_keypos() where we use
+ the lowest bit to mark if there is a transid following the rownr.
+ */
+ last_page= ((ulonglong) 1 << ((share->base.rec_reflength-1)*8))/2;
+ if (!last_page) /* Overflow; set max size */
+ last_page= ~(pgcache_page_no_t) 0;
+
+ res= _ma_bitmap_init(share, data_file, &last_page);
+ share->base.max_data_file_length= _ma_safe_mul(last_page + 1,
+ share->block_size);
#if SIZEOF_OFF_T == 4
- set_if_smaller(share->base.max_data_file_length, INT_MAX32);
+ set_if_smaller(share->base.max_data_file_length, INT_MAX32);
#endif
- return _ma_bitmap_init(share, data_file);
+ return res;
}
@@ -1019,7 +1034,7 @@ make_space_for_directory(MARIA_HA *info,
UNDO of DELETE (in which case we know the row was on the
page before) or if the bitmap told us there was space on page
*/
- DBUG_ASSERT(0);
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
return(1);
}
}
@@ -1706,7 +1721,7 @@ struct st_row_pos_info
static my_bool get_head_or_tail_page(MARIA_HA *info,
- MARIA_BITMAP_BLOCK *block,
+ const MARIA_BITMAP_BLOCK *block,
uchar *buff, uint length, uint page_type,
enum pagecache_page_lock lock,
struct st_row_pos_info *res)
@@ -1776,6 +1791,7 @@ static my_bool get_head_or_tail_page(MARIA_HA *info,
DBUG_RETURN(0);
crashed:
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD); /* File crashed */
DBUG_RETURN(1);
}
@@ -1805,7 +1821,7 @@ crashed:
*/
static my_bool get_rowpos_in_head_or_tail_page(MARIA_HA *info,
- MARIA_BITMAP_BLOCK *block,
+ const MARIA_BITMAP_BLOCK *block,
uchar *buff, uint length,
uint page_type,
enum pagecache_page_lock lock,
@@ -1869,6 +1885,7 @@ static my_bool get_rowpos_in_head_or_tail_page(MARIA_HA *info,
DBUG_RETURN(0);
err:
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD); /* File crashed */
DBUG_RETURN(1);
}
@@ -2240,7 +2257,7 @@ static void store_extent_info(uchar *to,
for (block= first_block, end_block= first_block+count ;
block < end_block; block++)
{
- /* The following is only false for marker blocks */
+ /* The following is only false for marker (unused) blocks */
if (likely(block->used & BLOCKUSED_USED))
{
uint page_count= block->page_count;
@@ -2755,7 +2772,7 @@ static my_bool write_block_record(MARIA_HA *info,
DBUG_ASSERT(length <= column->length);
break;
default: /* Wrong data */
- DBUG_ASSERT(0);
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
length=0;
break;
}
@@ -3071,9 +3088,10 @@ static my_bool write_block_record(MARIA_HA *info,
extent_data= row_extents_second_part +
((last_head_block - head_block) - 2) * ROW_EXTENT_SIZE;
}
- DBUG_ASSERT(uint2korr(extent_data+5) & TAIL_BIT);
+ /* Write information for tail block in the reserved space */
page_store(extent_data, head_tail_block->page);
- int2store(extent_data + PAGE_STORE_SIZE, head_tail_block->page_count);
+ pagerange_store(extent_data + PAGE_STORE_SIZE,
+ head_tail_block->page_count);
}
}
else
@@ -3418,6 +3436,7 @@ static my_bool write_block_record(MARIA_HA *info,
DBUG_RETURN(0);
crashed:
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
/* Something was wrong with data on page */
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
@@ -3625,6 +3644,7 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
}
}
}
+ _ma_bitmap_unlock(share);
if (share->now_transactional)
{
if (_ma_write_clr(info, info->cur_row.orig_undo_lsn,
@@ -3634,7 +3654,6 @@ my_bool _ma_write_abort_block_record(MARIA_HA *info)
&lsn, (void*) 0))
res= 1;
}
- _ma_bitmap_unlock(share);
_ma_unpin_all_pages_and_finalize_row(info, lsn);
DBUG_RETURN(res);
}
@@ -3812,6 +3831,7 @@ static my_bool _ma_update_block_record2(MARIA_HA *info,
DBUG_RETURN(0);
err:
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
DBUG_PRINT("error", ("errpos: %d", errpos));
if (info->non_flushable_state)
_ma_bitmap_flushable(info, -1);
@@ -3952,6 +3972,7 @@ static my_bool _ma_update_at_original_place(MARIA_HA *info,
DBUG_RETURN(0);
err:
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
_ma_mark_file_crashed(share);
if (info->non_flushable_state)
_ma_bitmap_flushable(info, -1);
@@ -4333,6 +4354,7 @@ my_bool _ma_delete_block_record(MARIA_HA *info, const uchar *record)
DBUG_RETURN(0);
err:
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
_ma_bitmap_flushable(info, -1);
_ma_unpin_all_pages_and_finalize_row(info, LSN_IMPOSSIBLE);
DBUG_RETURN(1);
@@ -4533,6 +4555,7 @@ static uchar *read_next_extent(MARIA_HA *info, MARIA_EXTENT_CURSOR *extent,
crashed:
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
DBUG_PRINT("error", ("wrong extent information"));
DBUG_RETURN(0);
@@ -4680,6 +4703,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
if (!info->trn)
{
/* File crashed */
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
}
@@ -4961,6 +4985,7 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
DBUG_RETURN(0);
err:
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
/* Something was wrong with data on record */
DBUG_PRINT("error", ("Found record with wrong data"));
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
@@ -4989,7 +5014,7 @@ static my_bool read_row_extent_info(MARIA_HA *info, uchar *buff,
MARIA_EXTENT_CURSOR extent;
MARIA_RECORD_POS *tail_pos;
uchar *data, *end_of_data;
- uint flag, row_extents, row_extents_size, field_lengths;
+ uint flag, row_extents, row_extents_size;
uchar *extents, *end;
DBUG_ENTER("read_row_extent_info");
@@ -5024,9 +5049,6 @@ static my_bool read_row_extent_info(MARIA_HA *info, uchar *buff,
}
info->cur_row.extents_count= row_extents;
- if (share->base.max_field_lengths)
- get_key_length(field_lengths, data);
-
if (share->calc_checksum)
info->cur_row.checksum= (uint) (uchar) *data++;
if (row_extents > 1)
@@ -5100,6 +5122,7 @@ int _ma_read_block_record(MARIA_HA *info, uchar *record,
DBUG_ASSERT((buff[PAGE_TYPE_OFFSET] & PAGE_TYPE_MASK) == HEAD_PAGE);
if (!(data= get_record_position(buff, block_size, offset, &end_of_data)))
{
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
DBUG_PRINT("error", ("Wrong directory entry in data block"));
my_errno= HA_ERR_RECORD_DELETED; /* File crashed */
DBUG_RETURN(HA_ERR_RECORD_DELETED);
@@ -5177,7 +5200,7 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info)
(uchar *) my_malloc(share->block_size * 2, MYF(MY_WME))))))
DBUG_RETURN(1);
info->scan.page_buff= info->scan.bitmap_buff + share->block_size;
- info->scan.bitmap_end= info->scan.bitmap_buff + share->bitmap.total_size;
+ info->scan.bitmap_end= info->scan.bitmap_buff + share->bitmap.max_total_size;
/* Set scan variables to get _ma_scan_block() to start with reading bitmap */
info->scan.number_of_rows= 0;
@@ -5311,7 +5334,6 @@ int _ma_scan_block_record(MARIA_HA *info, uchar *record,
my_bool skip_deleted __attribute__ ((unused)))
{
uint block_size;
- my_off_t filepos;
MARIA_SHARE *share= info->s;
DBUG_ENTER("_ma_scan_block_record");
@@ -5330,7 +5352,7 @@ restart_record_read:
#ifdef SANITY_CHECKS
if (info->scan.dir < info->scan.dir_end)
{
- DBUG_ASSERT(0);
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
goto err;
}
#endif
@@ -5441,8 +5463,7 @@ restart_bitmap_scan:
/* Read next bitmap */
info->scan.bitmap_page+= share->bitmap.pages_covered;
- filepos= (my_off_t) info->scan.bitmap_page * block_size;
- if (unlikely(filepos >= share->state.state.data_file_length))
+ if (unlikely(info->scan.bitmap_page >= info->scan.max_page))
{
DBUG_PRINT("info", ("Found end of file"));
DBUG_RETURN((my_errno= HA_ERR_END_OF_FILE));
@@ -5460,6 +5481,7 @@ restart_bitmap_scan:
goto restart_bitmap_scan;
err:
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
DBUG_PRINT("error", ("Wrong data on page"));
_ma_set_fatal_error(share, HA_ERR_WRONG_IN_RECORD);
DBUG_RETURN(HA_ERR_WRONG_IN_RECORD);
@@ -6391,7 +6413,7 @@ err:
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0, FALSE);
_ma_mark_file_crashed(share);
- DBUG_ASSERT(0); /* catch recovery errors early */
+ DBUG_ASSERT(!maria_assert_if_crashed_table); /* catch recovery error early */
DBUG_RETURN((my_errno= error));
}
@@ -6494,7 +6516,7 @@ err:
PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
LSN_IMPOSSIBLE, 0, FALSE);
_ma_mark_file_crashed(share);
- DBUG_ASSERT(0);
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
DBUG_RETURN((my_errno= error));
}
@@ -6566,7 +6588,7 @@ uint _ma_apply_redo_free_blocks(MARIA_HA *info,
{
pthread_mutex_unlock(&share->bitmap.bitmap_lock);
_ma_mark_file_crashed(share);
- DBUG_ASSERT(0);
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
DBUG_RETURN(res);
}
}
@@ -6652,7 +6674,7 @@ uint _ma_apply_redo_free_head_or_tail(MARIA_HA *info, LSN lsn,
err:
_ma_mark_file_crashed(share);
- DBUG_ASSERT(0);
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
DBUG_RETURN(1);
}
@@ -6722,11 +6744,11 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
uint i;
uint res;
uint page_range;
- pgcache_page_no_t page, start_page;
+ pgcache_page_no_t page;
uchar *buff;
uint data_on_page= data_size;
- start_page= page= page_korr(header);
+ page= page_korr(header);
header+= PAGE_STORE_SIZE;
page_range= pagerange_korr(header);
header+= PAGERANGE_STORE_SIZE;
@@ -6853,7 +6875,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info,
err:
_ma_mark_file_crashed(share);
- DBUG_ASSERT(0);
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
DBUG_RETURN(1);
}
@@ -6923,6 +6945,7 @@ end:
DBUG_RETURN(res);
err:
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
res= 1;
_ma_mark_file_crashed(share);
goto end;
@@ -7161,6 +7184,7 @@ my_bool _ma_apply_undo_row_delete(MARIA_HA *info, LSN undo_lsn,
DBUG_RETURN(0);
err:
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
_ma_mark_file_crashed(share);
if (info->non_flushable_state)
_ma_bitmap_flushable(info, -1);
@@ -7336,6 +7360,7 @@ end:
DBUG_RETURN(error);
err:
+ DBUG_ASSERT(!maria_assert_if_crashed_table);
error= 1;
_ma_mark_file_crashed(share);
goto end;
diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h
index 3201998e31c..45f5613bb60 100644
--- a/storage/maria/ma_blockrec.h
+++ b/storage/maria/ma_blockrec.h
@@ -59,7 +59,6 @@
/* Minimum header size needed for a new row */
#define BASE_ROW_HEADER_SIZE FLAG_SIZE
-#define TRANS_ROW_EXTRA_HEADER_SIZE TRANSID_SIZE
#define PAGE_TYPE_MASK 7
enum en_page_type { UNALLOCATED_PAGE, HEAD_PAGE, TAIL_PAGE, BLOB_PAGE, MAX_PAGE_TYPE };
@@ -187,7 +186,8 @@ maria_page_get_lsn(uchar *page, pgcache_page_no_t page_no, uchar* data_ptr);
/* ma_bitmap.c */
extern const char *bits_to_txt[];
-my_bool _ma_bitmap_init(MARIA_SHARE *share, File file);
+my_bool _ma_bitmap_init(MARIA_SHARE *share, File file,
+ pgcache_page_no_t *last_page);
my_bool _ma_bitmap_end(MARIA_SHARE *share);
my_bool _ma_bitmap_flush(MARIA_SHARE *share);
my_bool _ma_bitmap_flush_all(MARIA_SHARE *share);
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 63e60cc8465..637303d1547 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -125,6 +125,7 @@ void maria_chk_init(HA_CHECK *param)
param->max_record_length= LONGLONG_MAX;
param->pagecache_block_size= KEY_CACHE_BLOCK_SIZE;
param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
+ param->max_stage= 1;
}
@@ -407,26 +408,34 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
size= my_seek(share->kfile.file, 0L, MY_SEEK_END, MYF(MY_THREADSAFE));
if ((skr=(my_off_t) share->state.state.key_file_length) != size)
{
- /* Don't give error if file generated by mariapack */
+ /* Don't give error if file generated by maria_pack */
if (skr > size && maria_is_any_key_active(share->state.key_map))
{
error=1;
_ma_check_print_error(param,
- "Size of indexfile is: %-8s Should be: %s",
+ "Size of indexfile is: %-8s Expected: %s",
llstr(size,buff), llstr(skr,buff2));
+ share->state.state.key_file_length= size;
}
else if (!(param->testflag & T_VERY_SILENT))
_ma_check_print_warning(param,
- "Size of indexfile is: %-8s Should be: %s",
+ "Size of indexfile is: %-8s Expected: %s",
llstr(size,buff), llstr(skr,buff2));
}
- if (!(param->testflag & T_VERY_SILENT) &&
- ! (share->options & HA_OPTION_COMPRESS_RECORD) &&
- ulonglong2double(share->state.state.key_file_length) >
- ulonglong2double(share->base.margin_key_file_length)*0.9)
+ if (size > share->base.max_key_file_length)
+ {
+ _ma_check_print_warning(param,
+ "Size of indexfile is: %-8s which is bigger than max indexfile size: %s",
+ ullstr(size,buff),
+ ullstr(share->base.max_key_file_length, buff2));
+ }
+ else if (!(param->testflag & T_VERY_SILENT) &&
+ ! (share->options & HA_OPTION_COMPRESS_RECORD) &&
+ ulonglong2double(share->state.state.key_file_length) >
+ ulonglong2double(share->base.margin_key_file_length)*0.9)
_ma_check_print_warning(param,"Keyfile is almost full, %10s of %10s used",
llstr(share->state.state.key_file_length,buff),
- llstr(share->base.max_key_file_length-1,buff));
+ llstr(share->base.max_key_file_length,buff));
size= my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0));
skr=(my_off_t) share->state.state.data_file_length;
@@ -439,28 +448,34 @@ int maria_chk_size(HA_CHECK *param, register MARIA_HA *info)
#endif
if (skr != size)
{
+ share->state.state.data_file_length=size; /* Skip other errors */
if (skr > size && skr != size + MEMMAP_EXTRA_MARGIN)
{
- share->state.state.data_file_length=size; /* Skip other errors */
error=1;
- _ma_check_print_error(param,"Size of datafile is: %-9s Should be: %s",
+ _ma_check_print_error(param,"Size of datafile is: %-9s Expected: %s",
llstr(size,buff), llstr(skr,buff2));
param->testflag|=T_RETRY_WITHOUT_QUICK;
}
else
{
_ma_check_print_warning(param,
- "Size of datafile is: %-9s Should be: %s",
+ "Size of datafile is: %-9s Expected: %s",
llstr(size,buff), llstr(skr,buff2));
}
}
- if (!(param->testflag & T_VERY_SILENT) &&
- !(share->options & HA_OPTION_COMPRESS_RECORD) &&
- ulonglong2double(share->state.state.data_file_length) >
- (ulonglong2double(share->base.max_data_file_length)*0.9))
+ if (size > share->base.max_data_file_length)
+ {
+ _ma_check_print_warning(param,
+ "Size of datafile is: %-8s which is bigger than max datafile size: %s",
+ ullstr(size,buff),
+ ullstr(share->base.max_data_file_length, buff2));
+ } else if (!(param->testflag & T_VERY_SILENT) &&
+ !(share->options & HA_OPTION_COMPRESS_RECORD) &&
+ ulonglong2double(share->state.state.data_file_length) >
+ (ulonglong2double(share->base.max_data_file_length)*0.9))
_ma_check_print_warning(param, "Datafile is almost full, %10s of %10s used",
llstr(share->state.state.data_file_length,buff),
- llstr(share->base.max_data_file_length-1,buff2));
+ llstr(share->base.max_data_file_length,buff2));
DBUG_RETURN(error);
} /* maria_chk_size */
@@ -516,6 +531,7 @@ int maria_chk_key(HA_CHECK *param, register MARIA_HA *info)
continue;
}
found_keys++;
+ _ma_report_progress(param, key, share->base.keys);
param->record_checksum=init_checksum;
@@ -1122,10 +1138,14 @@ static int check_keys_in_record(HA_CHECK *param, MARIA_HA *info, int extend,
param->tmp_record_checksum+= (ha_checksum) start_recpos;
param->records++;
- if (param->testflag & T_WRITE_LOOP && param->records % WRITE_COUNT == 0)
+ if (param->records % WRITE_COUNT == 0)
{
- printf("%s\r", llstr(param->records, llbuff));
- VOID(fflush(stdout));
+ if (param->testflag & T_WRITE_LOOP)
+ {
+ printf("%s\r", llstr(param->records, llbuff));
+ VOID(fflush(stdout));
+ }
+ _ma_report_progress(param, param->records, share->state.state.records);
}
/* Check if keys match the record */
@@ -1803,7 +1823,7 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
char llbuff[22], llbuff2[22];
uint block_size= share->block_size;
ha_rows full_page_count, tail_count;
- my_bool full_dir;
+ my_bool full_dir, now_transactional;
uint offset_page, offset, free_count;
LINT_INIT(full_dir);
@@ -1814,6 +1834,10 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
my_errno);
return 1;
}
+
+ now_transactional= info->s->now_transactional;
+ info->s->now_transactional= 0; /* Don't log changes */
+
bitmap_buff= info->scan.bitmap_buff;
page_buff= info->scan.page_buff;
full_page_count= tail_count= 0;
@@ -1833,7 +1857,8 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
if (_ma_killed_ptr(param))
{
_ma_scan_end_block_record(info);
- return -1;
+ info->s->now_transactional= now_transactional;
+ return -1; /* Interrupted */
}
if ((page % share->bitmap.pages_covered) == 0)
{
@@ -1966,14 +1991,22 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
{
/* Not at end of bitmap */
uint bitmap_pattern;
+ uint byte_offset;
+
offset_page= (uint) ((page % share->bitmap.pages_covered) -1) * 3;
offset= offset_page & 7;
- data= bitmap_buff + offset_page / 8;
+ byte_offset= offset_page / 8;
+ data= bitmap_buff + byte_offset;
bitmap_pattern= uint2korr(data);
+ if (byte_offset + 1 == share->bitmap.max_total_size)
+ {
+ /* On last byte of bitmap; Remove possible checksum */
+ bitmap_pattern&= 0xff;
+ }
if (((bitmap_pattern >> offset)) ||
- (data + 2 < bitmap_buff + share->bitmap.total_size &&
- _ma_check_if_zero(data+2, bitmap_buff + share->bitmap.total_size -
- data - 2)))
+ (byte_offset + 2 < share->bitmap.max_total_size &&
+ _ma_check_if_zero(data+2, share->bitmap.max_total_size -
+ byte_offset - 2)))
{
ulonglong bitmap_page;
bitmap_page= page / share->bitmap.pages_covered;
@@ -2001,10 +2034,12 @@ static int check_block_record(HA_CHECK *param, MARIA_HA *info, int extend,
llstr(param->tail_count, llbuff),
llstr(tail_count, llbuff2));
+ info->s->now_transactional= now_transactional;
return param->error_printed != 0;
err:
_ma_scan_end_block_record(info);
+ info->s->now_transactional= now_transactional;
return 1;
}
@@ -2084,23 +2119,23 @@ int maria_chk_data_link(HA_CHECK *param, MARIA_HA *info, my_bool extend)
llstr(share->state.state.records,llbuff2));
error=1;
}
- else if (param->record_checksum &&
+ if (param->record_checksum &&
param->record_checksum != param->tmp_record_checksum)
{
_ma_check_print_error(param,
"Key pointers and record positions doesn't match");
error=1;
}
- else if (param->glob_crc != share->state.state.checksum &&
- (share->options &
- (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)))
+ if (param->glob_crc != share->state.state.checksum &&
+ (share->options &
+ (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)))
{
_ma_check_print_warning(param,
"Record checksum is not the same as checksum "
"stored in the index file");
error=1;
}
- else if (!extend)
+ if (!extend)
{
uint key;
for (key=0 ; key < share->base.keys; key++)
@@ -2309,7 +2344,7 @@ static int initialize_variables_for_repair(HA_CHECK *param,
return 1;
}
- /* Allow us to restore state and check how state changed */
+ /* Make a copy to allow us to restore state and check how state changed */
memcpy(org_share, share, sizeof(*share));
/* Repair code relies on share->state.state so we have to update it here */
@@ -2329,6 +2364,14 @@ static int initialize_variables_for_repair(HA_CHECK *param,
param->testflag&= ~T_QUICK;
param->org_key_map= share->state.key_map;
+ /*
+ Clear check variables set by repair. This is needed to allow one to run
+ several repair's in a row with same param
+ */
+ param->retry_repair= 0;
+ param->warning_printed= 0;
+ param->error_printed= 0;
+
sort_param->sort_info= sort_info;
sort_param->fix_datafile= ! rep_quick;
sort_param->calc_checksum= test(param->testflag & T_CALC_CHECKSUM);
@@ -2347,6 +2390,7 @@ static int initialize_variables_for_repair(HA_CHECK *param,
/* calculate max_records */
sort_info->filelength= my_seek(info->dfile.file, 0L, MY_SEEK_END, MYF(0));
+ param->max_progress= sort_info->filelength;
if ((param->testflag & T_CREATE_MISSING_KEYS) ||
sort_info->org_data_file_type == COMPRESSED_RECORD)
sort_info->max_records= share->state.state.records;
@@ -2369,6 +2413,8 @@ static int initialize_variables_for_repair(HA_CHECK *param,
maria_ignore_trids(info);
/* Don't write transid's during repair */
maria_versioning(info, 0);
+ /* remember original number of rows */
+ *info->state= info->s->state.state;
return 0;
}
@@ -3601,7 +3647,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
const char * name, my_bool rep_quick)
{
int got_error;
- uint i;
+ uint i, keys_to_repair;
ha_rows start_records;
my_off_t new_header_length, org_header_length, del;
File new_file;
@@ -3727,6 +3773,17 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
del=share->state.state.del;
+ /* Calculate number of keys to repair */
+ keys_to_repair= 0;
+ for (sort_param.key=0 ; sort_param.key < share->base.keys ;
+ sort_param.key++)
+ {
+ if (maria_is_key_active(key_map, sort_param.key))
+ keys_to_repair++;
+ }
+ /* For each key we scan and merge sort the keys */
+ param->max_stage= keys_to_repair*2;
+
rec_per_key_part= param->new_rec_per_key_part;
for (sort_param.key=0 ; sort_param.key < share->base.keys ;
rec_per_key_part+=sort_param.keyinfo->keysegs, sort_param.key++)
@@ -3847,6 +3904,9 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
/* Set for next loop */
sort_info.max_records= (ha_rows) sort_info.new_info->s->state.state.records;
+ param->stage++; /* Next stage */
+ param->progress= 0;
+
if (param->testflag & T_STATISTICS)
maria_update_key_parts(sort_param.keyinfo, rec_per_key_part,
sort_param.unique,
@@ -3927,6 +3987,10 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
sort_info.org_data_file_type= share->data_file_type;
sort_info.filelength= share->state.state.data_file_length;
sort_param.fix_datafile=0;
+
+ /* Offsets are now in proportion to the new file length */
+ param->max_progress= sort_info.filelength;
+
}
else
share->state.state.data_file_length=sort_param.max_pos;
@@ -4727,6 +4791,11 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
if (_ma_killed_ptr(param))
DBUG_RETURN(1);
+ if (param->progress_counter++ >= WRITE_COUNT)
+ {
+ param->progress_counter= 0;
+ _ma_report_progress(param, param->progress, param->max_progress);
+ }
switch (sort_info->org_data_file_type) {
case BLOCK_RECORD:
@@ -4767,6 +4836,9 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
flag= HA_ERR_ROW_NOT_VISIBLE;
}
}
+ param->progress= (ma_recordpos_to_page(info->cur_row.lastpos)*
+ share->block_size);
+
share->page_type= save_page_type;
if (!flag)
{
@@ -4819,6 +4891,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
DBUG_RETURN(-1);
}
sort_param->start_recpos=sort_param->pos;
+ param->progress= sort_param->pos;
if (!sort_param->fix_datafile)
{
sort_param->current_filepos= sort_param->pos;
@@ -4846,6 +4919,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
LINT_INIT(to);
pos=sort_param->pos;
+ param->progress= pos;
searching=(sort_param->fix_datafile && (param->testflag & T_EXTEND));
parallel_flag= (sort_param->read_cache.file < 0) ? READING_NEXT : 0;
for (;;)
@@ -5155,6 +5229,7 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param)
}
}
case COMPRESSED_RECORD:
+ param->progress= sort_param->pos;
for (searching=0 ;; searching=1, sort_param->pos++)
{
if (_ma_read_cache(info, &sort_param->read_cache, block_info.header,
@@ -5275,7 +5350,10 @@ int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param)
if ((sort_param->current_filepos=
(*share->write_record_init)(info, sort_param->record)) ==
HA_OFFSET_ERROR)
+ {
+ _ma_check_print_error(param, "%d when writing to datafile", my_errno);
DBUG_RETURN(1);
+ }
/* Pointer to end of file */
sort_param->filepos= share->state.state.data_file_length;
break;
@@ -5593,7 +5671,8 @@ static my_off_t get_record_for_key(MARIA_KEYDEF *keyinfo,
MARIA_KEY key;
key.keyinfo= keyinfo;
key.data= (uchar*) key_data;
- key.data_length= _ma_keylength(keyinfo, key_data);
+ key.data_length= (_ma_keylength(keyinfo, key_data) -
+ keyinfo->share->rec_reflength);
return _ma_row_pos_from_key(&key);
} /* get_record_for_key */
@@ -5606,7 +5685,7 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
my_off_t prev_block)
{
uint a_length,t_length,nod_flag;
- my_off_t filepos,key_file_length;
+ my_off_t filepos;
uchar *anc_buff,*lastkey;
MARIA_KEY_PARAM s_temp;
MARIA_KEYDEF *keyinfo=sort_param->keyinfo;
@@ -5674,7 +5753,6 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
_ma_store_page_used(share, anc_buff, key_block->last_length);
bzero(anc_buff+key_block->last_length,
keyinfo->block_length- key_block->last_length);
- key_file_length=share->state.state.key_file_length;
if ((filepos= _ma_new(info, DFLT_INIT_HITS, &page_link)) == HA_OFFSET_ERROR)
DBUG_RETURN(1);
_ma_fast_unlock_key_del(info);
@@ -5785,7 +5863,7 @@ static int sort_delete_record(MARIA_SORT_PARAM *sort_param)
int _ma_flush_pending_blocks(MARIA_SORT_PARAM *sort_param)
{
uint nod_flag,length;
- my_off_t filepos,key_file_length;
+ my_off_t filepos;
SORT_KEY_BLOCKS *key_block;
MARIA_SORT_INFO *sort_info= sort_param->sort_info;
myf myf_rw=sort_info->param->myf_rw;
@@ -5802,7 +5880,6 @@ int _ma_flush_pending_blocks(MARIA_SORT_PARAM *sort_param)
length= _ma_get_page_used(info->s, key_block->buff);
if (nod_flag)
_ma_kpointer(info,key_block->end_pos,filepos);
- key_file_length= info->s->state.state.key_file_length;
bzero(key_block->buff+length, keyinfo->block_length-length);
if ((filepos= _ma_new(info, DFLT_INIT_HITS, &page_link)) ==
HA_OFFSET_ERROR)
@@ -5897,6 +5974,9 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
MARIA_CREATE_INFO create_info;
DBUG_ENTER("maria_recreate_table");
+ if ((!(param->testflag & T_SILENT)))
+ printf("Recreating table '%s'\n", param->isam_file_name);
+
error=1; /* Default error */
info= **org_info;
status_info= (*org_info)->state[0];
@@ -6042,7 +6122,7 @@ int maria_recreate_table(HA_CHECK *param, MARIA_HA **org_info, char *filename)
(*org_info)->s->state.state.records= info.state->records;
if (share.state.create_time)
(*org_info)->s->state.create_time=share.state.create_time;
-#ifdef EXTERNAL_LOCKING
+#ifdef MARIA_EXTERNAL_LOCKING
(*org_info)->s->state.unique= (*org_info)->this_unique= share.state.unique;
#endif
(*org_info)->s->state.state.checksum= info.state->checksum;
@@ -6522,6 +6602,17 @@ static void copy_data_file_state(MARIA_STATE_INFO *to,
}
+/* Return 1 if block is full of zero's */
+
+static my_bool zero_filled_block(uchar *tmp, uint length)
+{
+ while (length--)
+ if (*(tmp++) != 0)
+ return 0;
+ return 1;
+}
+
+
/*
Read 'safely' next record while scanning table.
@@ -6623,9 +6714,21 @@ read_next_page:
{
if (my_errno == HA_ERR_WRONG_CRC)
{
- _ma_check_print_info(sort_info->param,
- "Wrong CRC on datapage at %s",
- llstr(page, llbuff));
+ /*
+ Don't give errors for zero filled blocks. These can
+ sometimes be found at end of a bitmap when we wrote a big
+ record last that was moved to the next bitmap.
+ */
+ if (!zero_filled_block(info->scan.page_buff, share->block_size) ||
+ _ma_check_bitmap_data(info, UNALLOCATED_PAGE, 0,
+ _ma_bitmap_get_page_bits(info,
+ &share->bitmap,
+ page)))
+ {
+ _ma_check_print_info(sort_info->param,
+ "Wrong CRC on datapage at %s",
+ llstr(page, llbuff));
+ }
continue;
}
DBUG_RETURN(my_errno);
diff --git a/storage/maria/ma_check_standalone.h b/storage/maria/ma_check_standalone.h
index 8cda285bb99..f9242bbe123 100644
--- a/storage/maria/ma_check_standalone.h
+++ b/storage/maria/ma_check_standalone.h
@@ -35,6 +35,13 @@ int _ma_killed_ptr(HA_CHECK *param __attribute__((unused)))
return 0;
}
+
+void _ma_report_progress(HA_CHECK *param __attribute__((unused)),
+ ulonglong progress __attribute__((unused)),
+ ulonglong max_progress __attribute__((unused)))
+{
+}
+
/* print warnings and errors */
/* VARARGS */
diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c
index 7522514649b..602e5da3065 100644
--- a/storage/maria/ma_checkpoint.c
+++ b/storage/maria/ma_checkpoint.c
@@ -533,10 +533,13 @@ filter_flush_file_evenly(enum pagecache_page_type type,
risk could be that while a checkpoint happens no LRD flushing happens.
*/
+static ulong maria_checkpoint_min_cache_activity= 10*1024*1024;
+/* Set in ha_maria.cc */
+ulong maria_checkpoint_min_log_activity= 1*1024*1024;
+
pthread_handler_t ma_checkpoint_background(void *arg)
{
/** @brief At least this of log/page bytes written between checkpoints */
- const uint checkpoint_min_activity= 2*1024*1024;
/*
If the interval could be changed by the user while we are in this thread,
it could be annoying: for example it could cause "case 2" to be executed
@@ -576,53 +579,62 @@ pthread_handler_t ma_checkpoint_background(void *arg)
switch (sleeps % interval)
{
case 0:
+ {
/* If checkpoints are disabled, wait 1 second and try again */
if (maria_checkpoint_disabled)
{
sleep_time= 1;
break;
}
- /*
- With background flushing evenly distributed over the time
- between two checkpoints, we should have only little flushing to do
- in the checkpoint.
- */
- /*
- No checkpoint if little work of interest for recovery was done
- since last checkpoint. Such work includes log writing (lengthens
- recovery, checkpoint would shorten it), page flushing (checkpoint
- would decrease the amount of read pages in recovery).
- In case of one short statement per minute (very low load), we don't
- want to checkpoint every minute, hence the positive
- checkpoint_min_activity.
- */
-
- if (((translog_get_horizon() - log_horizon_at_last_checkpoint) +
- (maria_pagecache->global_cache_write -
- pagecache_flushes_at_last_checkpoint) *
- maria_pagecache->block_size) < checkpoint_min_activity)
{
- /* don't take checkpoint, so don't know what to flush */
- pages_to_flush_before_next_checkpoint= 0;
- sleep_time= interval;
- break;
+ TRANSLOG_ADDRESS horizon= translog_get_horizon();
+
+ /*
+ With background flushing evenly distributed over the time
+ between two checkpoints, we should have only little flushing to do
+ in the checkpoint.
+ */
+ /*
+ No checkpoint if little work of interest for recovery was done
+ since last checkpoint. Such work includes log writing (lengthens
+ recovery, checkpoint would shorten it), page flushing (checkpoint
+ would decrease the amount of read pages in recovery).
+ In case of one short statement per minute (very low load), we don't
+ want to checkpoint every minute, hence the positive
+ maria_checkpoint_min_activity.
+ */
+ if ((ulonglong) (horizon - log_horizon_at_last_checkpoint) <=
+ maria_checkpoint_min_log_activity &&
+ ((ulonglong) (maria_pagecache->global_cache_write -
+ pagecache_flushes_at_last_checkpoint) *
+ maria_pagecache->block_size) <=
+ maria_checkpoint_min_cache_activity)
+ {
+ /*
+ Not enough has happend since last checkpoint.
+ Sleep for a while and try again later
+ */
+ sleep_time= interval;
+ break;
+ }
+ sleep_time= 1;
+ ma_checkpoint_execute(CHECKPOINT_MEDIUM, TRUE);
+ /*
+ Snapshot this kind of "state" of the engine. Note that the value
+ below is possibly greater than last_checkpoint_lsn.
+ */
+ log_horizon_at_last_checkpoint= translog_get_horizon();
+ pagecache_flushes_at_last_checkpoint=
+ maria_pagecache->global_cache_write;
+ /*
+ If the checkpoint above succeeded it has set d|kfiles and
+ d|kfiles_end. If is has failed, it has set
+ pages_to_flush_before_next_checkpoint to 0 so we will skip flushing
+ and sleep until the next checkpoint.
+ */
}
- sleep_time= 1;
- ma_checkpoint_execute(CHECKPOINT_MEDIUM, TRUE);
- /*
- Snapshot this kind of "state" of the engine. Note that the value below
- is possibly greater than last_checkpoint_lsn.
- */
- log_horizon_at_last_checkpoint= translog_get_horizon();
- pagecache_flushes_at_last_checkpoint=
- maria_pagecache->global_cache_write;
- /*
- If the checkpoint above succeeded it has set d|kfiles and
- d|kfiles_end. If is has failed, it has set
- pages_to_flush_before_next_checkpoint to 0 so we will skip flushing
- and sleep until the next checkpoint.
- */
break;
+ }
case 1:
/* set up parameters for background page flushing */
filter_param.up_to_lsn= last_checkpoint_lsn;
@@ -1018,17 +1030,25 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon)
possible that Recovery does not start from before the REDO and thus
the state is not recovered. A solution may be to set
share->changed=1 under log mutex when writing log records.
- But as anyway we have another problem below, this optimization would
- be of little use.
+
+ The current solution is to keep a copy the last saved state and
+ not write the state if it was same as last time. It's ok if
+ is_of_horizon would be different on disk if all other data is
+ the same.
*/
- /** @todo flush state only if changed since last checkpoint */
DBUG_ASSERT(share->last_version != 0);
state_copy->state.is_of_horizon= share->state.is_of_horizon=
- state_copies_horizon;
- if (kfile.file >= 0)
+ share->checkpoint_state.is_of_horizon= state_copies_horizon;
+ if (kfile.file >= 0 && memcmp(&share->checkpoint_state,
+ &state_copy->state,
+ sizeof(state_copy->state)))
+ {
sync_error|=
_ma_state_info_write_sub(kfile.file, &state_copy->state,
MA_STATE_INFO_WRITE_DONT_MOVE_OFFSET);
+ memcpy(&share->checkpoint_state,
+ &state_copy->state, sizeof(state_copy->state));
+ }
/*
We don't set share->changed=0 because it may interfere with a
concurrent _ma_writeinfo() doing share->changed=1 (cancel its
diff --git a/storage/maria/ma_close.c b/storage/maria/ma_close.c
index e97664ebe42..2427dfd042d 100644
--- a/storage/maria/ma_close.c
+++ b/storage/maria/ma_close.c
@@ -28,7 +28,8 @@ int maria_close(register MARIA_HA *info)
my_bool share_can_be_freed= FALSE;
MARIA_SHARE *share= info->s;
DBUG_ENTER("maria_close");
- DBUG_PRINT("enter",("base: 0x%lx reopen: %u locks: %u",
+ DBUG_PRINT("enter",("name: '%s' base: 0x%lx reopen: %u locks: %u",
+ share->open_file_name.str,
(long) info, (uint) share->reopen,
(uint) share->tot_locks));
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 6737030cd89..b773e930e82 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -326,7 +326,15 @@ int maria_create(const char *name, enum data_file_type datafile_type,
(~(ulonglong) 0)/ci->max_rows < (ulonglong) pack_reclength)
ci->data_file_length= ~(ulonglong) 0;
else
- ci->data_file_length=(ulonglong) ci->max_rows*pack_reclength;
+ {
+ ci->data_file_length= _ma_safe_mul(ci->max_rows, pack_reclength);
+ if (datafile_type == BLOCK_RECORD)
+ {
+ /* Assume that blocks are only half full (very pessimistic!) */
+ ci->data_file_length= _ma_safe_mul(ci->data_file_length, 2);
+ set_if_bigger(ci->data_file_length, maria_block_size*2);
+ }
+ }
}
else if (!ci->max_rows)
{
@@ -338,7 +346,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
ulonglong data_file_length= ci->data_file_length;
if (!data_file_length)
data_file_length= ((((ulonglong) 1 << ((BLOCK_RECORD_POINTER_SIZE-1) *
- 8)) -1) * maria_block_size);
+ 8))/2 -1) * maria_block_size);
if (rows_per_page > 0)
{
set_if_smaller(rows_per_page, MAX_ROWS_PER_PAGE);
@@ -360,11 +368,11 @@ int maria_create(const char *name, enum data_file_type datafile_type,
{
/*
The + 1 is for record position withing page
- The / 2 is because we need one bit for knowing if there is transid's
+ The * 2 is because we need one bit for knowing if there is transid's
after the row pointer
*/
pointer= maria_get_pointer_length((ci->data_file_length /
- (maria_block_size * 2)), 3) + 1;
+ maria_block_size) * 2, 3) + 1;
set_if_smaller(pointer, BLOCK_RECORD_POINTER_SIZE);
if (!max_rows)
@@ -615,7 +623,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
to be able to put at least 2 keys on an index block for the key
algorithms to work).
*/
- if (length > maria_max_key_length())
+ if (length > _ma_max_key_length())
{
my_errno=HA_WRONG_CREATE_OPTION;
goto err_no_lock;
@@ -685,7 +693,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
share.state.dellink = HA_OFFSET_ERROR;
share.state.first_bitmap_with_space= 0;
-#ifdef EXTERNAL_LOCKING
+#ifdef MARIA_EXTERNAL_LOCKING
share.state.process= (ulong) getpid();
#endif
share.state.version= (ulong) time((time_t*) 0);
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index ab66499ecfe..a4e485066f5 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -571,6 +571,7 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
endpos= leaf_page->buff + leaf_length;
tmp_key.keyinfo= keyinfo;
tmp_key.data= keybuff;
+ next_buff= 0;
if (!(key_start= _ma_get_last_key(&tmp_key, leaf_page, endpos)))
DBUG_RETURN(-1);
@@ -597,9 +598,11 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
/* underflow writes "next_page" to disk */
ret_value= underflow(info, keyinfo, leaf_page, &next_page,
endpos);
- if (ret_value == 0 && leaf_page->size >
- share->max_index_block_size)
+ if (ret_value < 0)
+ goto err;
+ if (leaf_page->size > share->max_index_block_size)
{
+ DBUG_ASSERT(ret_value == 0);
ret_value= (_ma_split_page(info, key, leaf_page,
share->max_index_block_size,
(uchar*) 0, 0, 0,
@@ -632,6 +635,7 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
goto err;
}
my_afree(next_buff);
+ DBUG_ASSERT(leaf_page->size <= share->max_index_block_size);
DBUG_RETURN(ret_value);
}
@@ -709,10 +713,14 @@ static int del(MARIA_HA *info, MARIA_KEY *key,
KEY_OP_DEBUG_LOG_ADD_2))
goto err;
+ DBUG_ASSERT(leaf_page->size <= share->max_index_block_size);
DBUG_RETURN(new_leaf_length <=
(info->quick_mode ? MARIA_MIN_KEYBLOCK_LENGTH :
(uint) keyinfo->underflow_block_length));
err:
+ if (next_buff)
+ my_afree(next_buff);
+
DBUG_RETURN(-1);
} /* del */
@@ -731,9 +739,18 @@ err:
leaf_page is saved to disk
Caller must save anc_buff
+ For the algoritm to work, we have to ensure for packed keys that
+ key_length + (underflow_length + max_block_length + key_length) / 2
+ <= block_length.
+ From which follows that underflow_length <= block_length - key_length *3
+ For not packed keys we have:
+ (underflow_length + max_block_length + key_length) / 2 <= block_length
+ From which follows that underflow_length < block_length - key_length
+ This is ensured by setting of underflow_block_length.
+
@return
@retval 0 ok
- @retval 1 ok, but anc_buff did underflow
+ @retval 1 ok, but anc_page did underflow
@retval -1 error
*/
@@ -1153,7 +1170,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
_ma_kpointer(info,leaf_key.data + leaf_key.data_length +
leaf_key.ref_length, leaf_page->pos);
- /* Save key in anc_page */
+ /* Save parting key found by _ma_find_half_pos() in anc_page */
DBUG_DUMP("anc_buff", anc_buff, new_anc_length);
DBUG_DUMP_KEY("key_to_anc", &leaf_key);
anc_end_pos= anc_buff + new_anc_length;
@@ -1191,6 +1208,7 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
bmove(leaf_buff+p_length+t_length, half_pos, tmp_length);
(*keyinfo->store_key)(keyinfo,leaf_buff+p_length, &key_inserted);
new_leaf_length= tmp_length + t_length + p_length;
+ DBUG_ASSERT(new_leaf_length <= share->max_index_block_size);
leaf_page->size= new_leaf_length;
leaf_page->flag= page_flag;
@@ -1232,7 +1250,6 @@ static int underflow(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
/*
Log changes to next page
This contains original data with some suffix data deleted
-
*/
DBUG_ASSERT(new_buff_length <= buff_length);
if (_ma_log_suffix(&next_page, buff_length, new_buff_length))
diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c
index 7b120910a42..10d9674eca2 100644
--- a/storage/maria/ma_dynrec.c
+++ b/storage/maria/ma_dynrec.c
@@ -1741,14 +1741,19 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info,
MARIA_RECORD_POS filepos,
my_bool skip_deleted_blocks)
{
- int block_of_record, info_read;
+ int block_of_record;
+#ifdef MARIA_EXTERNAL_LOCKING
+ int info_read;
+#endif
uint left_len,b_type;
uchar *to;
MARIA_BLOCK_INFO block_info;
MARIA_SHARE *share= info->s;
DBUG_ENTER("_ma_read_rnd_dynamic_record");
+#ifdef MARIA_EXTERNAL_LOCKING
info_read=0;
+#endif
LINT_INIT(to);
if (info->lock_type == F_UNLCK)
@@ -1758,8 +1763,10 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info,
info->tmp_lock_type=F_RDLCK;
#endif
}
+#ifdef MARIA_EXTERNAL_LOCKING
else
info_read=1; /* memory-keyinfoblock is ok */
+#endif
block_of_record= 0; /* First block of record is numbered as zero. */
block_info.second_read= 0;
@@ -1768,6 +1775,7 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info,
{
if (filepos >= info->state->data_file_length)
{
+#ifdef MARIA_EXTERNAL_LOCKING
if (!info_read)
{ /* Check if changed */
info_read=1;
@@ -1780,6 +1788,10 @@ int _ma_read_rnd_dynamic_record(MARIA_HA *info,
my_errno= HA_ERR_END_OF_FILE;
goto err;
}
+#else
+ my_errno= HA_ERR_END_OF_FILE;
+ goto err;
+#endif
}
if (info->opt_flag & READ_CACHE_USED)
{
diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c
index a5c4c2ab251..183f74835b2 100644
--- a/storage/maria/ma_extra.c
+++ b/storage/maria/ma_extra.c
@@ -143,7 +143,7 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
(READ_CACHE_USED | WRITE_CACHE_USED | OPT_NO_ROWS)) &&
!share->state.header.uniques)
if (!(init_io_cache(&info->rec_cache, info->dfile.file, cache_size,
- WRITE_CACHE,share->state.state.data_file_length,
+ WRITE_CACHE, info->state->data_file_length,
(pbool) (info->lock_type != F_UNLCK),
MYF(share->write_flag & MY_WAIT_IF_FULL))))
{
@@ -319,7 +319,6 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
my_bool do_flush= test(function != HA_EXTRA_PREPARE_FOR_DROP);
my_bool save_global_changed;
enum flush_type type;
- pthread_mutex_lock(&THR_LOCK_maria);
/*
This share, to have last_version=0, needs to save all its data/index
blocks to disk if this is not for a DROP TABLE. Otherwise they would be
@@ -353,12 +352,14 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
type= do_flush ? FLUSH_RELEASE : FLUSH_IGNORE_CHANGED;
save_global_changed= share->global_changed;
share->global_changed= 1; /* Don't increment open count */
+ pthread_mutex_unlock(&share->intern_lock);
if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
type, type))
{
error=my_errno;
share->changed= 1;
}
+ pthread_mutex_lock(&share->intern_lock);
share->global_changed= save_global_changed;
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
{
@@ -395,10 +396,9 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
error= my_errno;
share->bitmap.changed_not_flushed= 0;
}
- /* For protection against Checkpoint, we set under intern_lock: */
+ /* last_version must be protected by intern_lock; See collect_tables() */
share->last_version= 0L; /* Impossible version */
pthread_mutex_unlock(&share->intern_lock);
- pthread_mutex_unlock(&THR_LOCK_maria);
break;
}
case HA_EXTRA_PREPARE_FOR_FORCED_CLOSE:
@@ -415,9 +415,8 @@ int maria_extra(MARIA_HA *info, enum ha_extra_function function,
if (!share->temporary)
error= _ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
FLUSH_KEEP, FLUSH_KEEP);
-#ifdef HAVE_PREAD
+
_ma_decrement_open_count(info, 1);
-#endif
if (share->not_flushed)
{
share->not_flushed= 0;
diff --git a/storage/maria/ma_ft_update.c b/storage/maria/ma_ft_update.c
index f38990efab9..8576746981e 100644
--- a/storage/maria/ma_ft_update.c
+++ b/storage/maria/ma_ft_update.c
@@ -319,7 +319,6 @@ my_bool _ma_ft_convert_to_ft2(MARIA_HA *info, MARIA_KEY *key)
uchar *key_ptr= (uchar*) dynamic_array_ptr(da, 0), *end;
uint length, key_length;
MARIA_PINNED_PAGE tmp_page_link, *page_link= &tmp_page_link;
- MARIA_KEY tmp_key;
MARIA_PAGE page;
DBUG_ENTER("_ma_ft_convert_to_ft2");
@@ -357,13 +356,8 @@ my_bool _ma_ft_convert_to_ft2(MARIA_HA *info, MARIA_KEY *key)
/* inserting the rest of key values */
end= (uchar*) dynamic_array_ptr(da, da->elements);
- tmp_key.keyinfo= keyinfo;
- tmp_key.data_length= keyinfo->keylength;
- tmp_key.ref_length= 0;
- tmp_key.flag= 0;
for (key_ptr+=length; key_ptr < end; key_ptr+=keyinfo->keylength)
{
- tmp_key.data= key_ptr;
if (_ma_ck_real_write_btree(info, key, &root, SEARCH_SAME))
DBUG_RETURN(1);
}
diff --git a/storage/maria/ma_info.c b/storage/maria/ma_info.c
index 1bbfa3cbf7e..af0e46ee239 100644
--- a/storage/maria/ma_info.c
+++ b/storage/maria/ma_info.c
@@ -28,6 +28,12 @@ MARIA_RECORD_POS maria_position(MARIA_HA *info)
}
+uint maria_max_key_length()
+{
+ uint tmp= (_ma_max_key_length() - 8 - HA_MAX_KEY_SEG*3);
+ return min(HA_MAX_KEY_BUFF, tmp);
+}
+
/* Get information about the table */
/* if flag == 2 one get current info (no sync from database */
diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c
index 71af3a011e3..48bb9cb13d0 100644
--- a/storage/maria/ma_key_recover.c
+++ b/storage/maria/ma_key_recover.c
@@ -944,7 +944,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
uchar *buff;
const uchar *header_end= header + head_length;
uint page_offset= 0, org_page_length;
- uint nod_flag, page_length, keypage_header, keynr;
+ uint page_length, keypage_header, keynr;
uint max_page_size= share->max_index_block_size;
int result;
MARIA_PAGE page;
@@ -972,7 +972,6 @@ uint _ma_apply_redo_index(MARIA_HA *info,
keynr= _ma_get_keynr(share, buff);
_ma_page_setup(&page, info, share->keyinfo + keynr, page_pos, buff);
- nod_flag= page.node;
org_page_length= page_length= page.size;
keypage_header= share->keypage_header;
diff --git a/storage/maria/ma_locking.c b/storage/maria/ma_locking.c
index 633fd59ef2a..acc359ff212 100644
--- a/storage/maria/ma_locking.c
+++ b/storage/maria/ma_locking.c
@@ -103,7 +103,7 @@ int maria_lock_database(MARIA_HA *info, int lock_type)
rw_unlock(&share->mmap_lock);
}
#endif
-#ifdef EXTERNAL_LOCKING
+#ifdef MARIA_EXTERNAL_LOCKING
share->state.process= share->last_process=share->this_process;
share->state.unique= info->last_unique= info->this_unique;
share->state.update_count= info->last_loop= ++info->this_loop;
@@ -303,7 +303,7 @@ int _ma_writeinfo(register MARIA_HA *info, uint operation)
{ /* Two threads can't be here */
olderror= my_errno; /* Remember last error */
-#ifdef EXTERNAL_LOCKING
+#ifdef MARIA_EXTERNAL_LOCKING
/*
The following only makes sense if we want to be allow two different
processes access the same table at the same time
@@ -341,7 +341,7 @@ int _ma_writeinfo(register MARIA_HA *info, uint operation)
int _ma_test_if_changed(register MARIA_HA *info)
{
-#ifdef EXTERNAL_LOCKING
+#ifdef MARIA_EXTERNAL_LOCKING
MARIA_SHARE *share= info->s;
if (share->state.process != share->last_process ||
share->state.unique != info->last_unique ||
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index d57b7e0be72..d54b0ed430f 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -2611,14 +2611,12 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer)
i < buffer->size;
i+= TRANSLOG_PAGE_SIZE, pg++)
{
- TRANSLOG_ADDRESS addr= (buffer->offset + i);
- TRANSLOG_VALIDATOR_DATA data;
DBUG_PRINT("info", ("send log form %lu till %lu address: (%lu,0x%lx) "
"page #: %lu buffer size: %lu buffer: 0x%lx",
(ulong) i, (ulong) (i + TRANSLOG_PAGE_SIZE),
- LSN_IN_PARTS(addr), (ulong) pg, (ulong) buffer->size,
+ LSN_IN_PARTS(buffer->offset + i), (ulong) pg,
+ (ulong) buffer->size,
(ulong) buffer));
- data.addr= &addr;
DBUG_ASSERT(log_descriptor.pagecache->block_size == TRANSLOG_PAGE_SIZE);
DBUG_ASSERT(i + TRANSLOG_PAGE_SIZE <= buffer->size);
if (translog_status != TRANSLOG_OK && translog_status != TRANSLOG_SHUTDOWN)
@@ -6564,16 +6562,12 @@ my_bool translog_scanner_init(LSN lsn,
TRANSLOG_SCANNER_DATA *scanner,
my_bool use_direct)
{
- TRANSLOG_VALIDATOR_DATA data;
DBUG_ENTER("translog_scanner_init");
DBUG_PRINT("enter", ("Scanner: 0x%lx LSN: (%lu,0x%lx)",
(ulong) scanner, LSN_IN_PARTS(lsn)));
DBUG_ASSERT(translog_status == TRANSLOG_OK ||
translog_status == TRANSLOG_READONLY);
- data.addr= &scanner->page_addr;
- data.was_recovered= 0;
-
scanner->page_offset= LSN_OFFSET(lsn) % TRANSLOG_PAGE_SIZE;
scanner->fixed_horizon= fixed_horizon;
@@ -8166,6 +8160,7 @@ int translog_assign_id_to_share(MARIA_HA *tbl_info, TRN *trn)
before it's written to the log.
*/
share->id= id;
+ share->state.logrec_file_id= lsn;
}
pthread_mutex_unlock(&share->intern_lock);
return 0;
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 1dd5a58b71c..a7287e75127 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -135,7 +135,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share, const char *name,
info.update= (short) (HA_STATE_NEXT_FOUND+HA_STATE_PREV_FOUND);
info.opt_flag=READ_CHECK_USED;
info.this_unique= (ulong) info.dfile.file; /* Uniq number in process */
-#ifdef EXTERNAL_LOCKING
+#ifdef MARIA_EXTERNAL_LOCKING
if (share->data_file_type == COMPRESSED_RECORD)
info.this_unique= share->state.unique;
info.this_loop=0; /* Update counter */
@@ -468,7 +468,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
}
key_parts+=fulltext_keys*FT_SEGS;
- if (share->base.max_key_length > maria_max_key_length() ||
+ if (share->base.max_key_length > _ma_max_key_length() ||
keys > MARIA_MAX_KEY || key_parts > MARIA_MAX_KEY * HA_MAX_KEY_SEG)
{
DBUG_PRINT("error",("Wrong key info: Max_key_length: %d keys: %d key_parts: %d", share->base.max_key_length, keys, key_parts));
@@ -509,7 +509,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
(ulonglong) 1 << (share->base.rec_reflength*8))-1);
max_key_file_length=
- _ma_safe_mul(maria_block_size,
+ _ma_safe_mul(share->base.block_size,
((ulonglong) 1 << (share->base.key_reflength*8))-1);
#if SIZEOF_OFF_T == 4
set_if_smaller(max_data_file_length, INT_MAX32);
@@ -570,21 +570,40 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->block_size= share->base.block_size; /* Convenience */
share->max_index_block_size= share->block_size - KEYPAGE_CHECKSUM_SIZE;
+ share->keypage_header= ((share->base.born_transactional ?
+ LSN_STORE_SIZE + TRANSID_SIZE :
+ 0) + KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE +
+ KEYPAGE_USED_SIZE);
{
HA_KEYSEG *pos=share->keyparts;
uint32 ftkey_nr= 1;
for (i=0 ; i < keys ; i++)
{
- share->keyinfo[i].share= share;
- disk_pos=_ma_keydef_read(disk_pos, &share->keyinfo[i]);
- share->keyinfo[i].key_nr= i;
+ MARIA_KEYDEF *keyinfo= &share->keyinfo[i];
+ keyinfo->share= share;
+ disk_pos=_ma_keydef_read(disk_pos, keyinfo);
+ keyinfo->key_nr= i;
+
+ /* See ma_delete.cc::underflow() */
+ if (!(keyinfo->flag & (HA_BINARY_PACK_KEY | HA_PACK_KEY)))
+ keyinfo->underflow_block_length= keyinfo->block_length/3;
+ else
+ {
+ /* Packed key, ensure we don't get overflow in underflow() */
+ keyinfo->underflow_block_length=
+ max((int) (share->max_index_block_size - keyinfo->maxlength * 3),
+ (int) (share->keypage_header + share->base.key_reflength));
+ set_if_smaller(keyinfo->underflow_block_length,
+ keyinfo->block_length/3);
+ }
+
disk_pos_assert(share,
- disk_pos + share->keyinfo[i].keysegs * HA_KEYSEG_SIZE,
+ disk_pos + keyinfo->keysegs * HA_KEYSEG_SIZE,
end_pos);
- if (share->keyinfo[i].key_alg == HA_KEY_ALG_RTREE)
+ if (keyinfo->key_alg == HA_KEY_ALG_RTREE)
share->have_rtree= 1;
- share->keyinfo[i].seg=pos;
- for (j=0 ; j < share->keyinfo[i].keysegs; j++,pos++)
+ keyinfo->seg=pos;
+ for (j=0 ; j < keyinfo->keysegs; j++,pos++)
{
disk_pos=_ma_keyseg_read(disk_pos, pos);
if (pos->type == HA_KEYTYPE_TEXT ||
@@ -602,25 +621,25 @@ MARIA_HA *maria_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)
+ if (keyinfo->flag & HA_SPATIAL)
{
#ifdef HAVE_SPATIAL
uint sp_segs=SPDIMS*2;
- share->keyinfo[i].seg=pos-sp_segs;
- share->keyinfo[i].keysegs--;
+ keyinfo->seg=pos-sp_segs;
+ keyinfo->keysegs--;
versioning= 0;
#else
my_errno=HA_ERR_UNSUPPORTED;
goto err;
#endif
}
- else if (share->keyinfo[i].flag & HA_FULLTEXT)
+ else if (keyinfo->flag & HA_FULLTEXT)
{
versioning= 0;
DBUG_ASSERT(fulltext_keys);
{
uint k;
- share->keyinfo[i].seg=pos;
+ keyinfo->seg=pos;
for (k=0; k < FT_SEGS; k++)
{
*pos= ft_keysegs[k];
@@ -635,8 +654,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
}
if (!share->ft2_keyinfo.seg)
{
- memcpy(&share->ft2_keyinfo, &share->keyinfo[i],
- sizeof(MARIA_KEYDEF));
+ memcpy(&share->ft2_keyinfo, keyinfo, sizeof(MARIA_KEYDEF));
share->ft2_keyinfo.keysegs=1;
share->ft2_keyinfo.flag=0;
share->ft2_keyinfo.keylength=
@@ -646,10 +664,10 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->ft2_keyinfo.end=pos;
setup_key_functions(& share->ft2_keyinfo);
}
- share->keyinfo[i].ftkey_nr= ftkey_nr++;
+ keyinfo->ftkey_nr= ftkey_nr++;
}
- setup_key_functions(share->keyinfo+i);
- share->keyinfo[i].end=pos;
+ setup_key_functions(keyinfo);
+ keyinfo->end=pos;
pos->type=HA_KEYTYPE_END; /* End */
pos->length=share->base.rec_reflength;
pos->null_bit=0;
@@ -693,10 +711,6 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->base.null_bytes +
share->base.pack_bytes +
test(share->options & HA_OPTION_CHECKSUM));
- share->keypage_header= ((share->base.born_transactional ?
- LSN_STORE_SIZE + TRANSID_SIZE :
- 0) + KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE +
- KEYPAGE_USED_SIZE);
share->kfile.file= kfile;
if (open_flags & HA_OPEN_COPY)
@@ -815,7 +829,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
_ma_set_index_pagecache_callbacks(&share->kfile, share);
share->this_process=(ulong) getpid();
-#ifdef EXTERNAL_LOCKING
+#ifdef MARIA_EXTERNAL_LOCKING
share->last_process= share->state.process;
#endif
share->base.key_parts=key_parts;
@@ -826,7 +840,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
share->base.margin_key_file_length=(share->base.max_key_file_length -
(keys ? MARIA_INDEX_BLOCK_MARGIN *
share->block_size * keys : 0));
- share->block_size= share->base.block_size;
+
my_free(disk_cache, MYF(0));
_ma_setup_functions(share);
if ((*share->once_init)(share, info.dfile.file))
@@ -933,7 +947,7 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
{
/*
We must have internal_lock before bitmap_lock because we call
- _ma_flush_tables_files() with internal_lock locked.
+ _ma_flush_table_files() with internal_lock locked.
*/
pthread_mutex_lock(&share->intern_lock);
pthread_mutex_lock(&share->bitmap.bitmap_lock);
@@ -1470,7 +1484,7 @@ static uchar *_ma_state_info_read(uchar *ptr, MARIA_STATE_INFO *state)
uint _ma_state_info_read_dsk(File file __attribute__((unused)),
MARIA_STATE_INFO *state __attribute__((unused)))
{
-#ifdef EXTERNAL_LOCKING
+#ifdef MARIA_EXTERNAL_LOCKING
uchar buff[MARIA_STATE_INFO_SIZE + MARIA_STATE_EXTRA_SIZE];
/* trick to detect transactional tables */
@@ -1607,7 +1621,6 @@ uchar *_ma_keydef_read(uchar *ptr, MARIA_KEYDEF *keydef)
keydef->keylength = mi_uint2korr(ptr); ptr+= 2;
keydef->minlength = mi_uint2korr(ptr); ptr+= 2;
keydef->maxlength = mi_uint2korr(ptr); ptr+= 2;
- keydef->underflow_block_length=keydef->block_length/3;
keydef->version = 0; /* Not saved */
keydef->parser = &ft_default_parser;
keydef->ftkey_nr = 0;
@@ -1829,7 +1842,6 @@ void _ma_set_index_pagecache_callbacks(PAGECACHE_FILE *file,
int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share, const char *org_name,
File file_to_dup __attribute__((unused)))
{
- char *data_name= share->data_file_name.str;
char real_data_name[FN_REFLEN];
if (org_name)
@@ -1843,7 +1855,6 @@ int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share, const char *org_name,
my_errno= HA_WRONG_CREATE_OPTION;
return 1;
}
- data_name= real_data_name;
}
}
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index bcd50f028ec..9f6a7406ea7 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -193,6 +193,7 @@ my_bool _ma_write_keypage(MARIA_PAGE *page, enum pagecache_page_lock lock,
nod_flag= _ma_test_if_nod(share, buff);
DBUG_ASSERT(page->size == page_length);
+ DBUG_ASSERT(page->size <= share->max_index_block_size);
DBUG_ASSERT(page->flag == _ma_get_keypage_flag(share, buff));
if (page->pos < share->base.keystart ||
diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c
index 0e44b0e7a22..e96bf0cda25 100644
--- a/storage/maria/ma_pagecache.c
+++ b/storage/maria/ma_pagecache.c
@@ -494,6 +494,7 @@ error:
#define FLUSH_CACHE 2000 /* sort this many blocks at once */
static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block);
+static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link);
#ifndef DBUG_OFF
static void test_key_cache(PAGECACHE *pagecache,
const char *where, my_bool lock);
@@ -540,7 +541,7 @@ static void pagecache_debug_print _VARARGS((const char *fmt, ...));
#define KEYCACHE_DBUG_ASSERT(a) \
{ if (! (a) && pagecache_debug_log) \
fclose(pagecache_debug_log); \
- assert(a); }
+ DBUG_ASSERT(a); }
#else
#define KEYCACHE_PRINT(l, m)
#define KEYCACHE_DBUG_PRINT(l, m) DBUG_PRINT(l, m)
@@ -1030,8 +1031,7 @@ ulong resize_pagecache(PAGECACHE *pagecache,
#ifdef THREAD
while (pagecache->cnt_for_resize_op)
{
- KEYCACHE_DBUG_PRINT("resize_pagecache: wait",
- ("suspend thread %ld", thread->id));
+ DBUG_PRINT("wait", ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock);
}
#else
@@ -1050,8 +1050,9 @@ finish:
/* Signal for the next resize request to proceeed if any */
if (wqueue->last_thread)
{
- KEYCACHE_DBUG_PRINT("resize_pagecache: signal",
- ("thread %ld", wqueue->last_thread->next->id));
+ DBUG_PRINT("signal",
+ ("thread %s %ld", wqueue->last_thread->next->name,
+ wqueue->last_thread->next->id));
pagecache_pthread_cond_signal(&wqueue->last_thread->next->suspend);
}
#endif
@@ -1075,6 +1076,7 @@ static inline void inc_counter_for_resize_op(PAGECACHE *pagecache)
Decrement counter blocking resize key cache operation;
Signal the operation to proceed when counter becomes equal zero
*/
+
static inline void dec_counter_for_resize_op(PAGECACHE *pagecache)
{
#ifdef THREAD
@@ -1083,8 +1085,9 @@ static inline void dec_counter_for_resize_op(PAGECACHE *pagecache)
if (!--pagecache->cnt_for_resize_op &&
(last_thread= pagecache->resize_queue.last_thread))
{
- KEYCACHE_DBUG_PRINT("dec_counter_for_resize_op: signal",
- ("thread %ld", last_thread->next->id));
+ DBUG_PRINT("signal",
+ ("thread %s %ld", last_thread->next->name,
+ last_thread->next->id));
pagecache_pthread_cond_signal(&last_thread->next->suspend);
}
#else
@@ -1322,6 +1325,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
{
PAGECACHE_BLOCK_LINK *ins;
PAGECACHE_BLOCK_LINK **ptr_ins;
+ DBUG_ENTER("link_block");
PCBLOCK_INFO(block);
KEYCACHE_DBUG_ASSERT(! (block->hash_link && block->hash_link->requests));
@@ -1336,6 +1340,11 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
PAGECACHE_HASH_LINK *hash_link=
(PAGECACHE_HASH_LINK *) first_thread->opt_info;
struct st_my_thread_var *thread;
+
+ DBUG_ASSERT(block->requests + block->wlocks + block->rlocks +
+ block->pins == 0);
+ DBUG_ASSERT(block->next_used == NULL);
+
do
{
thread= next_thread;
@@ -1346,7 +1355,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
*/
if ((PAGECACHE_HASH_LINK *) thread->opt_info == hash_link)
{
- KEYCACHE_DBUG_PRINT("link_block: signal", ("thread: %ld", thread->id));
+ DBUG_PRINT("signal", ("thread: %s %ld", thread->name, thread->id));
pagecache_pthread_cond_signal(&thread->suspend);
wqueue_unlink_from_queue(&pagecache->waiting_for_block, thread);
block->requests++;
@@ -1354,14 +1363,17 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
}
while (thread != last_thread);
hash_link->block= block;
- KEYCACHE_THREAD_TRACE("link_block: after signaling");
+ /* Ensure that no other thread tries to use this block */
+ block->status|= PCBLOCK_REASSIGNED;
+
+ DBUG_PRINT("signal", ("after signal"));
#if defined(PAGECACHE_DEBUG)
KEYCACHE_DBUG_PRINT("link_block",
("linked,unlinked block: %u status: %x #requests: %u #available: %u",
PCBLOCK_NUMBER(pagecache, block), block->status,
block->requests, pagecache->blocks_available));
#endif
- return;
+ DBUG_VOID_RETURN;
}
#else /* THREAD */
KEYCACHE_DBUG_ASSERT(! (!hot && pagecache->waiting_for_block.last_thread));
@@ -1381,8 +1393,6 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
else
{
/* The LRU chain is empty */
- /* QQ: Ask sanja if next line is correct; Should we really put block
- in both chain if one chain is empty ? */
pagecache->used_last= pagecache->used_ins= block->next_used= block;
block->prev_used= &block->next_used;
}
@@ -1396,6 +1406,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
KEYCACHE_DBUG_ASSERT((ulong) pagecache->blocks_available <=
pagecache->blocks_used);
#endif
+ DBUG_VOID_RETURN;
}
@@ -1404,7 +1415,7 @@ static void link_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block,
SYNOPSIS
unlink_block()
- pagecache pointer to a page cache data structure
+ pagecache pointer to a page cache data structure
block pointer to the block to unlink from the LRU chain
RETURN VALUE
@@ -1511,7 +1522,7 @@ static void unreg_request(PAGECACHE *pagecache,
PAGECACHE_BLOCK_LINK *block, int at_end)
{
DBUG_ENTER("unreg_request");
- DBUG_PRINT("enter", ("block 0x%lx (%u) status: %x reqs: %u",
+ DBUG_PRINT("enter", ("block 0x%lx (%u) status: %x requests: %u",
(ulong)block, PCBLOCK_NUMBER(pagecache, block),
block->status, block->requests));
PCBLOCK_INFO(block);
@@ -1580,18 +1591,23 @@ static inline void remove_reader(PAGECACHE_BLOCK_LINK *block)
static inline void wait_for_readers(PAGECACHE *pagecache
__attribute__((unused)),
- PAGECACHE_BLOCK_LINK *block)
+ PAGECACHE_BLOCK_LINK *block
+ __attribute__((unused)))
{
#ifdef THREAD
struct st_my_thread_var *thread= my_thread_var;
+ DBUG_ASSERT(block->condvar == NULL);
while (block->hash_link->requests)
{
- KEYCACHE_DBUG_PRINT("wait_for_readers: wait",
- ("suspend thread: %ld block: %u",
- thread->id, PCBLOCK_NUMBER(pagecache, block)));
+ DBUG_ENTER("wait_for_readers");
+ DBUG_PRINT("wait",
+ ("suspend thread: %s %ld block: %u",
+ thread->name, thread->id,
+ PCBLOCK_NUMBER(pagecache, block)));
block->condvar= &thread->suspend;
pagecache_pthread_cond_wait(&thread->suspend, &pagecache->cache_lock);
block->condvar= NULL;
+ DBUG_VOID_RETURN;
}
#else
KEYCACHE_DBUG_ASSERT(block->hash_link->requests == 0);
@@ -1600,6 +1616,30 @@ static inline void wait_for_readers(PAGECACHE *pagecache
/*
+ Wait until the flush of the page is done.
+*/
+
+static void wait_for_flush(PAGECACHE *pagecache
+ __attribute__((unused)),
+ PAGECACHE_BLOCK_LINK *block
+ __attribute__((unused)))
+{
+ struct st_my_thread_var *thread= my_thread_var;
+ DBUG_ENTER("wait_for_flush");
+ wqueue_add_to_queue(&block->wqueue[COND_FOR_SAVED], thread);
+ do
+ {
+ DBUG_PRINT("wait",
+ ("suspend thread %s %ld", thread->name, thread->id));
+ pagecache_pthread_cond_wait(&thread->suspend,
+ &pagecache->cache_lock);
+ }
+ while(thread->next);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
Add a hash link to a bucket in the hash_table
*/
@@ -1620,10 +1660,14 @@ static inline void link_hash(PAGECACHE_HASH_LINK **start,
static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link)
{
- KEYCACHE_DBUG_PRINT("unlink_hash", ("fd: %u pos_ %lu #requests=%u",
- (uint) hash_link->file.file, (ulong) hash_link->pageno,
- hash_link->requests));
- KEYCACHE_DBUG_ASSERT(hash_link->requests == 0);
+ DBUG_ENTER("unlink_hash");
+ DBUG_PRINT("enter", ("hash_link: %p fd: %u pos: %lu requests: %u",
+ hash_link, (uint) hash_link->file.file,
+ (ulong) hash_link->pageno,
+ hash_link->requests));
+ DBUG_ASSERT(hash_link->requests == 0);
+ DBUG_ASSERT(!hash_link->block || hash_link->block->pins == 0);
+
if ((*hash_link->prev= hash_link->next))
hash_link->next->prev= hash_link->prev;
hash_link->block= NULL;
@@ -1654,23 +1698,32 @@ static void unlink_hash(PAGECACHE *pagecache, PAGECACHE_HASH_LINK *hash_link)
if (page->file.file == hash_link->file.file &&
page->pageno == hash_link->pageno)
{
- KEYCACHE_DBUG_PRINT("unlink_hash: signal", ("thread %ld", thread->id));
+ DBUG_PRINT("signal", ("thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_signal(&thread->suspend);
wqueue_unlink_from_queue(&pagecache->waiting_for_hash_link, thread);
}
}
while (thread != last_thread);
+
+ /*
+ Add this to the hash, so that the waiting threads can find it
+ when they retry the call to get_hash_link(). This entry is special
+ in that it has no associated block.
+ */
link_hash(&pagecache->hash_root[PAGECACHE_HASH(pagecache,
hash_link->file,
hash_link->pageno)],
hash_link);
- return;
+ DBUG_VOID_RETURN;
}
#else /* THREAD */
KEYCACHE_DBUG_ASSERT(! (pagecache->waiting_for_hash_link.last_thread));
#endif /* THREAD */
+
+ /* Add hash to free hash list */
hash_link->next= pagecache->free_hash_list;
pagecache->free_hash_list= hash_link;
+ DBUG_VOID_RETURN;
}
@@ -1701,8 +1754,6 @@ static PAGECACHE_HASH_LINK *get_present_hash_link(PAGECACHE *pagecache,
#endif
DBUG_ENTER("get_present_hash_link");
DBUG_PRINT("enter", ("fd: %u pos: %lu", (uint) file->file, (ulong) pageno));
- KEYCACHE_PRINT("get_present_hash_link", ("fd: %u pos: %lu",
- (uint) file->file, (ulong) pageno));
/*
Find the bucket in the hash table for the pair (file, pageno);
@@ -1737,6 +1788,7 @@ static PAGECACHE_HASH_LINK *get_present_hash_link(PAGECACHE *pagecache,
}
if (hash_link)
{
+ DBUG_PRINT("exit", ("hash_link: %p", hash_link));
/* Register the request for the page */
hash_link->requests++;
}
@@ -1758,9 +1810,7 @@ static PAGECACHE_HASH_LINK *get_hash_link(PAGECACHE *pagecache,
{
reg1 PAGECACHE_HASH_LINK *hash_link;
PAGECACHE_HASH_LINK **start;
-
- KEYCACHE_DBUG_PRINT("get_hash_link", ("fd: %u pos: %lu",
- (uint) file->file, (ulong) pageno));
+ DBUG_ENTER("get_hash_link");
restart:
/* try to find the page in the cache */
@@ -1771,6 +1821,9 @@ restart:
/* There is no hash link in the hash table for the pair (file, pageno) */
if (pagecache->free_hash_list)
{
+ DBUG_PRINT("info", ("free_hash_list: %p free_hash_list->next: %p",
+ pagecache->free_hash_list,
+ pagecache->free_hash_list->next));
hash_link= pagecache->free_hash_list;
pagecache->free_hash_list= hash_link->next;
}
@@ -1784,21 +1837,20 @@ restart:
/* Wait for a free hash link */
struct st_my_thread_var *thread= my_thread_var;
PAGECACHE_PAGE page;
- KEYCACHE_DBUG_PRINT("get_hash_link", ("waiting"));
page.file= *file;
page.pageno= pageno;
thread->opt_info= (void *) &page;
wqueue_link_into_queue(&pagecache->waiting_for_hash_link, thread);
- KEYCACHE_DBUG_PRINT("get_hash_link: wait",
- ("suspend thread %ld", thread->id));
+ DBUG_PRINT("wait",
+ ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock);
thread->opt_info= NULL;
+ DBUG_PRINT("thread", ("restarting..."));
+ goto restart;
#else
- KEYCACHE_DBUG_ASSERT(0);
+ DBUG_ASSERT(0);
#endif
- DBUG_PRINT("info", ("restarting..."));
- goto restart;
}
hash_link->file= *file;
DBUG_ASSERT(pageno < ((ULL(1)) << 40));
@@ -1807,9 +1859,19 @@ restart:
/* Register the request for the page */
hash_link->requests++;
DBUG_ASSERT(hash_link->block == 0);
+ DBUG_ASSERT(hash_link->requests == 1);
}
-
- return hash_link;
+ else
+ {
+ /*
+ We have to copy the flush_log callback, as it may change if the table
+ goes from non_transactional to transactional during recovery
+ */
+ hash_link->file.flush_log_callback= file->flush_log_callback;
+ }
+ DBUG_PRINT("exit", ("hash_link: %p block: %p", hash_link,
+ hash_link->block));
+ DBUG_RETURN(hash_link);
}
@@ -1923,16 +1985,7 @@ restart:
hash_link->requests--;
{
#ifdef THREAD
- struct st_my_thread_var *thread= my_thread_var;
- wqueue_add_to_queue(&block->wqueue[COND_FOR_SAVED], thread);
- do
- {
- KEYCACHE_DBUG_PRINT("find_block: wait",
- ("suspend thread %ld", thread->id));
- pagecache_pthread_cond_wait(&thread->suspend,
- &pagecache->cache_lock);
- }
- while(thread->next);
+ wait_for_flush(pagecache, block);
#else
KEYCACHE_DBUG_ASSERT(0);
/*
@@ -1945,6 +1998,7 @@ restart:
#endif
}
/* Invalidate page in the block if it has not been done yet */
+ DBUG_ASSERT(block->status); /* Should always be true */
if (block->status)
free_block(pagecache, block);
return 0;
@@ -1983,8 +2037,8 @@ restart:
/* Wait until the request can be resubmitted */
do
{
- KEYCACHE_DBUG_PRINT("find_block: wait",
- ("suspend thread %ld", thread->id));
+ DBUG_PRINT("wait",
+ ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock);
}
@@ -2056,32 +2110,39 @@ restart:
/* There are no never used blocks, use a block from the LRU chain */
/*
- Wait until a new block is added to the LRU chain;
- several threads might wait here for the same page,
- all of them must get the same block
+ Ensure that we are going to register the block.
+ (This should be true as a new block could not have been
+ pinned by caller).
*/
+ DBUG_ASSERT(reg_req);
#ifdef THREAD
if (! pagecache->used_last)
{
+ /*
+ Wait until a new block is added to the LRU chain;
+ several threads might wait here for the same page,
+ all of them must get the same block.
+
+ The block is given to us by the next thread executing
+ link_block().
+ */
+
struct st_my_thread_var *thread= my_thread_var;
thread->opt_info= (void *) hash_link;
wqueue_link_into_queue(&pagecache->waiting_for_block, thread);
do
{
- KEYCACHE_DBUG_PRINT("find_block: wait",
- ("suspend thread %ld", thread->id));
+ DBUG_PRINT("wait",
+ ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock);
}
while (thread->next);
thread->opt_info= NULL;
block= hash_link->block;
- /*
- Ensure that we are register this block (all blocks not used by this
- thread has to be registered).
- */
- DBUG_ASSERT(reg_req);
+ /* Ensure that the block is registered */
+ DBUG_ASSERT(block->requests >= 1);
}
else
#else
@@ -2093,21 +2154,24 @@ restart:
unlinking it from the chain
*/
block= pagecache->used_last->next_used;
- block->hits_left= init_hits_left;
- block->last_hit_time= 0;
if (reg_req)
reg_requests(pagecache, block, 1);
hash_link->block= block;
+ DBUG_ASSERT(block->requests == 1);
}
+
PCBLOCK_INFO(block);
- DBUG_ASSERT(block->wlocks == 0);
- DBUG_ASSERT(block->rlocks == 0);
- DBUG_ASSERT(block->rlocks_queue == 0);
- DBUG_ASSERT(block->pins == 0);
+
+ DBUG_ASSERT(block->hash_link == hash_link ||
+ !(block->status & PCBLOCK_IN_SWITCH));
if (block->hash_link != hash_link &&
! (block->status & PCBLOCK_IN_SWITCH) )
{
+ /* If another thread is flushing the block, wait for it. */
+ if (block->status & PCBLOCK_IN_FLUSH)
+ wait_for_flush(pagecache, block);
+
/* this is a primary request for a new page */
DBUG_ASSERT(block->wlocks == 0);
DBUG_ASSERT(block->rlocks == 0);
@@ -2154,15 +2218,20 @@ restart:
/* Remove the hash link for this page from the hash table */
unlink_hash(pagecache, block->hash_link);
- /* All pending requests for this page must be resubmitted */
+
#ifdef THREAD
+ /* All pending requests for this page must be resubmitted. */
if (block->wqueue[COND_FOR_SAVED].last_thread)
wqueue_release_queue(&block->wqueue[COND_FOR_SAVED]);
#endif
}
link_to_file_list(pagecache, block, file,
(my_bool)(block->hash_link ? 1 : 0));
+
+ block->hash_link= hash_link;
PCBLOCK_INFO(block);
+ block->hits_left= init_hits_left;
+ block->last_hit_time= 0;
block->status= error ? PCBLOCK_ERROR : 0;
block->error= error ? (int16) my_errno : 0;
#ifndef DBUG_OFF
@@ -2170,7 +2239,6 @@ restart:
if (error)
my_debug_put_break_here();
#endif
- block->hash_link= hash_link;
page_status= PAGE_TO_BE_READ;
DBUG_PRINT("info", ("page to be read set for page 0x%lx",
(ulong)block));
@@ -2193,12 +2261,24 @@ restart:
}
else
{
+ /*
+ The block was found in the cache. It's either a already read
+ block or a block waiting to be read by another thread.
+ */
if (reg_req)
reg_requests(pagecache, block, 1);
KEYCACHE_DBUG_PRINT("find_block",
("block->hash_link: %p hash_link: %p "
"block->status: %u", block->hash_link,
hash_link, block->status ));
+ /*
+ block->hash_link != hash_link can only happen when
+ the block is in PCBLOCK_IN_SWITCH above (is flushed out
+ to be replaced by another block). The SWITCH code will change
+ block->hash_link to point to hash_link.
+ */
+ KEYCACHE_DBUG_ASSERT(block->hash_link == hash_link ||
+ block->status & PCBLOCK_IN_SWITCH);
page_status= (((block->hash_link == hash_link) &&
(block->status & PCBLOCK_READ)) ?
PAGE_READ : PAGE_WAIT_TO_BE_READ);
@@ -2332,8 +2412,8 @@ static my_bool pagecache_wait_lock(PAGECACHE *pagecache,
dec_counter_for_resize_op(pagecache);
do
{
- KEYCACHE_DBUG_PRINT("get_wrlock: wait",
- ("suspend thread %ld", thread->id));
+ DBUG_PRINT("wait",
+ ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock);
}
@@ -2575,6 +2655,7 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache,
DBUG_ASSERT(!any ||
((lock == PAGECACHE_LOCK_LEFT_UNLOCKED) &&
(pin == PAGECACHE_UNPIN)));
+ DBUG_ASSERT(block->hash_link->block == block);
switch (lock) {
case PAGECACHE_LOCK_WRITE: /* free -> write */
@@ -2702,6 +2783,7 @@ static void read_block(PAGECACHE *pagecache,
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
if (error)
{
+ DBUG_ASSERT(maria_in_recovery || !maria_assert_if_crashed_table);
block->status|= PCBLOCK_ERROR;
block->error= (int16) my_errno;
my_debug_put_break_here();
@@ -2741,8 +2823,8 @@ static void read_block(PAGECACHE *pagecache,
wqueue_add_to_queue(&block->wqueue[COND_FOR_REQUESTED], thread);
do
{
- DBUG_PRINT("read_block: wait",
- ("suspend thread %ld", thread->id));
+ DBUG_PRINT("wait",
+ ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock);
}
@@ -3444,7 +3526,7 @@ restart:
}
else
{
- if (!(status & PCBLOCK_ERROR))
+ if (status & PCBLOCK_READ)
{
#if !defined(SERIALIZED_READ_FROM_CACHE)
pagecache_pthread_mutex_unlock(&pagecache->cache_lock);
@@ -3458,7 +3540,7 @@ restart:
pagecache_pthread_mutex_lock(&pagecache->cache_lock);
#endif
}
- else
+ if (status & PCBLOCK_ERROR)
my_errno= block->error;
}
@@ -3627,7 +3709,7 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache,
DBUG_ASSERT(0);
DBUG_ASSERT(block->hash_link->requests > 0);
page_link->requests--;
- /* See NOTE for pagecache_unlock about registering requests. */
+ /* See NOTE for pagecache_unlock() about registering requests. */
free_block(pagecache, block);
dec_counter_for_resize_op(pagecache);
return 0;
@@ -4232,6 +4314,7 @@ end:
static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block)
{
+ uint status= block->status;
KEYCACHE_THREAD_TRACE("free block");
KEYCACHE_DBUG_PRINT("free_block",
("block: %u hash_link 0x%lx",
@@ -4257,29 +4340,43 @@ static void free_block(PAGECACHE *pagecache, PAGECACHE_BLOCK_LINK *block)
DBUG_ASSERT(block->rlocks_queue == 0);
DBUG_ASSERT(block->pins == 0);
DBUG_ASSERT((block->status & ~(PCBLOCK_ERROR | PCBLOCK_READ | PCBLOCK_IN_FLUSH | PCBLOCK_CHANGED | PCBLOCK_REASSIGNED | PCBLOCK_DEL_WRITE)) == 0);
+ DBUG_ASSERT(block->requests >= 1);
+ DBUG_ASSERT(block->next_used == NULL);
block->status= 0;
#ifndef DBUG_OFF
block->type= PAGECACHE_EMPTY_PAGE;
#endif
block->rec_lsn= LSN_MAX;
+ block->hash_link= NULL;
+ if (block->temperature == PCBLOCK_WARM)
+ pagecache->warm_blocks--;
+ block->temperature= PCBLOCK_COLD;
KEYCACHE_THREAD_TRACE("free block");
KEYCACHE_DBUG_PRINT("free_block",
("block is freed"));
unreg_request(pagecache, block, 0);
- DBUG_ASSERT(block->requests == 0);
- DBUG_ASSERT(block->next_used != 0);
- block->hash_link= NULL;
- /* Remove the free block from the LRU ring. */
- unlink_block(pagecache, block);
- if (block->temperature == PCBLOCK_WARM)
- pagecache->warm_blocks--;
- block->temperature= PCBLOCK_COLD;
- /* Insert the free block in the free list. */
- block->next_used= pagecache->free_block_list;
- pagecache->free_block_list= block;
- /* Keep track of the number of currently unused blocks. */
- pagecache->blocks_unused++;
+ /*
+ Block->requests is != 0 if unreg_requests()/link_block() gave the block
+ to a waiting thread
+ */
+ if (!block->requests)
+ {
+ DBUG_ASSERT(block->next_used != 0);
+
+ /* Remove the free block from the LRU ring. */
+ unlink_block(pagecache, block);
+ /* Insert the free block in the free list. */
+ block->next_used= pagecache->free_block_list;
+ pagecache->free_block_list= block;
+ /* Keep track of the number of currently unused blocks. */
+ pagecache->blocks_unused++;
+ }
+ else
+ {
+ /* keep flag set by link_block() */
+ block->status= status & PCBLOCK_REASSIGNED;
+ }
#ifdef THREAD
/* All pending requests for this page must be resubmitted. */
@@ -4537,8 +4634,9 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
wqueue_add_to_queue(&other_flusher->flush_queue, thread);
do
{
- KEYCACHE_DBUG_PRINT("flush_pagecache_blocks_int: wait1",
- ("suspend thread %ld", thread->id));
+ DBUG_PRINT("wait",
+ ("(1) suspend thread %s %ld",
+ thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock);
}
@@ -4699,8 +4797,9 @@ restart:
wqueue_add_to_queue(&block->wqueue[COND_FOR_SAVED], thread);
do
{
- KEYCACHE_DBUG_PRINT("flush_pagecache_blocks_int: wait2",
- ("suspend thread %ld", thread->id));
+ DBUG_PRINT("wait",
+ ("(2) suspend thread %s %ld",
+ thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock);
}
@@ -4910,8 +5009,8 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache,
wqueue_add_to_queue(&other_flusher->flush_queue, thread);
do
{
- KEYCACHE_DBUG_PRINT("pagecache_collect_changed_blocks_with_lsn: wait",
- ("suspend thread %ld", thread->id));
+ DBUG_PRINT("wait",
+ ("suspend thread %s %ld", thread->name, thread->id));
pagecache_pthread_cond_wait(&thread->suspend,
&pagecache->cache_lock);
}
@@ -5055,7 +5154,7 @@ static void pagecache_dump(PAGECACHE *pagecache)
PAGECACHE_PAGE *page;
uint i;
- fprintf(pagecache_dump_file, "thread:%u\n", thread->id);
+ fprintf(pagecache_dump_file, "thread: %s %ld\n", thread->name, thread->id);
i=0;
thread=last=waiting_for_hash_link.last_thread;
@@ -5066,8 +5165,9 @@ static void pagecache_dump(PAGECACHE *pagecache)
thread= thread->next;
page= (PAGECACHE_PAGE *) thread->opt_info;
fprintf(pagecache_dump_file,
- "thread:%u, (file,pageno)=(%u,%lu)\n",
- thread->id,(uint) page->file.file,(ulong) page->pageno);
+ "thread: %s %ld, (file,pageno)=(%u,%lu)\n",
+ thread->name, thread->id,
+ (uint) page->file.file,(ulong) page->pageno);
if (++i == MAX_QUEUE_LEN)
break;
}
@@ -5082,8 +5182,9 @@ static void pagecache_dump(PAGECACHE *pagecache)
thread=thread->next;
hash_link= (PAGECACHE_HASH_LINK *) thread->opt_info;
fprintf(pagecache_dump_file,
- "thread:%u hash_link:%u (file,pageno)=(%u,%lu)\n",
- thread->id, (uint) PAGECACHE_HASH_LINK_NUMBER(pagecache, hash_link),
+ "thread: %s %u hash_link:%u (file,pageno)=(%u,%lu)\n",
+ thread->name, thread->id,
+ (uint) PAGECACHE_HASH_LINK_NUMBER(pagecache, hash_link),
(uint) hash_link->file.file,(ulong) hash_link->pageno);
if (++i == MAX_QUEUE_LEN)
break;
@@ -5112,7 +5213,7 @@ static void pagecache_dump(PAGECACHE *pagecache)
{
thread=thread->next;
fprintf(pagecache_dump_file,
- "thread:%u\n", thread->id);
+ "thread: %s %ld\n", thread->name, thread->id);
if (++i == MAX_QUEUE_LEN)
break;
}
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index 697d6ac7803..33112a1ec5e 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -60,6 +60,7 @@ static int (*save_error_handler_hook)(uint, const char *,myf);
static uint recovery_warnings; /**< count of warnings */
static uint recovery_found_crashed_tables;
HASH tables_to_redo; /* For maria_read_log */
+ulong maria_recovery_force_crash_counter;
#define prototype_redo_exec_hook(R) \
static int exec_REDO_LOGREC_ ## R(const TRANSLOG_HEADER_BUFFER *rec)
@@ -319,25 +320,32 @@ int maria_apply_log(LSN from_lsn, LSN end_lsn,
skip_DDLs= skip_DDLs_arg;
skipped_undo_phase= 0;
+ trnman_init(max_trid_in_control_file);
+
if (from_lsn == LSN_IMPOSSIBLE)
{
if (last_checkpoint_lsn == LSN_IMPOSSIBLE)
{
from_lsn= translog_first_lsn_in_log();
if (unlikely(from_lsn == LSN_ERROR))
+ {
+ trnman_destroy();
goto err;
+ }
}
else
{
from_lsn= parse_checkpoint_record(last_checkpoint_lsn);
if (from_lsn == LSN_ERROR)
+ {
+ trnman_destroy();
goto err;
+ }
}
}
now= microsecond_interval_timer();
in_redo_phase= TRUE;
- trnman_init(max_trid_in_control_file);
if (run_redo_phase(from_lsn, end_lsn, apply))
{
ma_message_no_user(0, "Redo phase failed");
@@ -2939,6 +2947,12 @@ static int run_undo_phase(uint uncommitted)
translog_free_record_header(&rec);
}
+ /* Force a crash to test recovery of recovery */
+ if (maria_recovery_force_crash_counter)
+ {
+ DBUG_ASSERT(--maria_recovery_force_crash_counter > 0);
+ }
+
if (trnman_rollback_trn(trn))
DBUG_RETURN(1);
/* We could want to span a few threads (4?) instead of 1 */
@@ -3201,9 +3215,11 @@ static LSN parse_checkpoint_record(LSN lsn)
tprint(tracef, "Loading data from checkpoint record at LSN (%lu,0x%lx)\n",
LSN_IN_PARTS(lsn));
- if ((len= translog_read_record_header(lsn, &rec)) == RECHEADER_READ_ERROR)
+ if ((len= translog_read_record_header(lsn, &rec)) == RECHEADER_READ_ERROR ||
+ rec.type != LOGREC_CHECKPOINT)
{
- tprint(tracef, "Cannot find checkpoint record where it should be\n");
+ eprint(tracef, "Cannot find checkpoint record at LSN (%lu,0x%lx)",
+ LSN_IN_PARTS(lsn));
return LSN_ERROR;
}
@@ -3436,6 +3452,12 @@ static int close_all_tables(void)
prepare_table_for_close(info, addr);
error|= maria_close(info);
pthread_mutex_lock(&THR_LOCK_maria);
+
+ /* Force a crash to test recovery of recovery */
+ if (maria_recovery_force_crash_counter)
+ {
+ DBUG_ASSERT(--maria_recovery_force_crash_counter > 0);
+ }
}
end:
pthread_mutex_unlock(&THR_LOCK_maria);
@@ -3510,7 +3532,7 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
/*
Reset state pointers. This is needed as in ALTER table we may do
- commit fllowed by _ma_renable_logging_for_table and then
+ commit followed by _ma_renable_logging_for_table and then
info->state may point to a state that was deleted by
_ma_trnman_end_trans_hook()
*/
diff --git a/storage/maria/ma_recovery.h b/storage/maria/ma_recovery.h
index 5b22c4fd9b2..45dba0e86b3 100644
--- a/storage/maria/ma_recovery.h
+++ b/storage/maria/ma_recovery.h
@@ -32,4 +32,5 @@ int maria_apply_log(LSN lsn, LSN lsn_end, enum maria_apply_log_way apply,
my_bool take_checkpoints, uint *warnings_count);
/* Table of tables to recover */
extern HASH tables_to_redo;
+extern ulong maria_recovery_force_crash_counter;
C_MODE_END
diff --git a/storage/maria/ma_rt_split.c b/storage/maria/ma_rt_split.c
index 6f32a60c073..ea90b60ce12 100644
--- a/storage/maria/ma_rt_split.c
+++ b/storage/maria/ma_rt_split.c
@@ -380,7 +380,6 @@ int maria_rtree_split_page(const MARIA_KEY *key, MARIA_PAGE *page,
SplitStruct *stop;
double *coord_buf;
double *next_coord;
- double *old_coord;
int n_dim;
uchar *source_cur, *cur1, *cur2;
uchar *new_page_buff, *log_internal_copy, *log_internal_copy_ptr,
@@ -426,7 +425,6 @@ int maria_rtree_split_page(const MARIA_KEY *key, MARIA_PAGE *page,
maria_rtree_d_mbr(keyinfo->seg, key->data, key_data_length, cur->coords);
cur->key= key->data;
- old_coord= next_coord;
if (split_maria_rtree_node(task, max_keys + 1,
page->size + full_length + 2,
diff --git a/storage/maria/ma_sort.c b/storage/maria/ma_sort.c
index a36bb980145..7bfb53ca0a1 100644
--- a/storage/maria/ma_sort.c
+++ b/storage/maria/ma_sort.c
@@ -191,6 +191,9 @@ int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
&tempfile,&tempfile_for_exceptions))
== HA_POS_ERROR)
goto err; /* purecov: tested */
+
+ info->sort_info->param->stage++; /* Merge stage */
+
if (maxbuffer == 0)
{
if (!no_messages)
@@ -769,6 +772,8 @@ static int write_index(MARIA_SORT_PARAM *info,
if ((*info->key_write)(info, *sort_keys++))
DBUG_RETURN(-1); /* purecov: inspected */
}
+ if (info->sort_info->param->max_stage != 1) /* If not parallel */
+ _ma_report_progress(info->sort_info->param, 1, 1);
DBUG_RETURN(0);
} /* write_index */
@@ -779,7 +784,7 @@ static int merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
uchar **sort_keys, BUFFPEK *buffpek,
int *maxbuffer, IO_CACHE *t_file)
{
- register int i;
+ int tmp, merges, max_merges;
IO_CACHE t_file2, *from_file, *to_file, *temp;
BUFFPEK *lastbuff;
DBUG_ENTER("merge_many_buff");
@@ -791,9 +796,21 @@ static int merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
DISK_BUFFER_SIZE, info->sort_info->param->myf_rw))
DBUG_RETURN(1); /* purecov: inspected */
+ /* Calculate how many merges are needed */
+ max_merges= 1; /* Count merge_index */
+ tmp= *maxbuffer;
+ while (tmp >= MERGEBUFF2)
+ {
+ merges= (tmp-MERGEBUFF*3/2 + 1) / MERGEBUFF + 1;
+ max_merges+= merges;
+ tmp= merges;
+ }
+ merges= 0;
+
from_file= t_file ; to_file= &t_file2;
while (*maxbuffer >= MERGEBUFF2)
{
+ int i;
reinit_io_cache(from_file,READ_CACHE,0L,0,0);
reinit_io_cache(to_file,WRITE_CACHE,0L,0,0);
lastbuff=buffpek;
@@ -802,6 +819,8 @@ static int merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
buffpek+i,buffpek+i+MERGEBUFF-1))
goto cleanup;
+ if (info->sort_info->param->max_stage != 1) /* If not parallel */
+ _ma_report_progress(info->sort_info->param, merges++, max_merges);
}
if (merge_buffers(info,keys,from_file,to_file,sort_keys,lastbuff++,
buffpek+i,buffpek+ *maxbuffer))
@@ -810,6 +829,8 @@ static int merge_many_buff(MARIA_SORT_PARAM *info, uint keys,
break; /* purecov: inspected */
temp=from_file; from_file=to_file; to_file=temp;
*maxbuffer= (int) (lastbuff-buffpek)-1;
+ if (info->sort_info->param->max_stage != 1) /* If not parallel */
+ _ma_report_progress(info->sort_info->param, merges++, max_merges);
}
cleanup:
close_cached_file(to_file); /* This holds old result */
@@ -1066,6 +1087,8 @@ merge_index(MARIA_SORT_PARAM *info, uint keys, uchar **sort_keys,
if (merge_buffers(info,keys,tempfile,(IO_CACHE*) 0,sort_keys,buffpek,buffpek,
buffpek+maxbuffer))
DBUG_RETURN(1); /* purecov: inspected */
+ if (info->sort_info->param->max_stage != 1) /* If not parallel */
+ _ma_report_progress(info->sort_info->param, 1, 1);
DBUG_RETURN(0);
} /* merge_index */
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index f3357bfb921..7b80ca5a5b8 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -1079,7 +1079,6 @@ int _ma_split_page(MARIA_HA *info, MARIA_KEY *key, MARIA_PAGE *split_page,
Returns pointer to start of key.
key will contain the key.
- return_key_length will contain the length of key
after_key will contain the position to where the next key starts
*/
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index b687484b0eb..34e9ed108ba 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -436,7 +436,7 @@ static struct my_option my_long_options[] =
static void print_version(void)
{
- printf("%s Ver 1.0 for %s at %s\n", my_progname, SYSTEM_TYPE,
+ printf("%s Ver 1.1 for %s at %s\n", my_progname, SYSTEM_TYPE,
MACHINE_TYPE);
NETWARE_SET_SCREEN_MODE(1);
}
@@ -878,9 +878,9 @@ static void get_options(register int *argc,register char ***argv)
load_defaults("my", load_default_groups, argc, argv);
default_argv= *argv;
+ check_param.testflag= T_UPDATE_STATE;
if (isatty(fileno(stdout)))
check_param.testflag|=T_WRITE_LOOP;
- check_param.testflag= T_UPDATE_STATE;
if ((ho_error=handle_options(argc, argv, my_long_options, get_one_option)))
exit(ho_error);
@@ -949,6 +949,7 @@ static void get_options(register int *argc,register char ***argv)
static int maria_chk(HA_CHECK *param, char *filename)
{
int error,lock_type,recreate;
+ uint warning_printed_by_chk_status;
my_bool rep_quick= test(param->testflag & (T_QUICK | T_FORCE_UNIQUENESS));
MARIA_HA *info;
File datafile;
@@ -961,6 +962,7 @@ static int maria_chk(HA_CHECK *param, char *filename)
recreate=0;
datafile=0;
param->isam_file_name=filename; /* For error messages */
+ warning_printed_by_chk_status= 0;
if (!(info=maria_open(filename,
(param->testflag & (T_DESCRIPT | T_READONLY)) ?
O_RDONLY : O_RDWR,
@@ -1303,7 +1305,12 @@ static int maria_chk(HA_CHECK *param, char *filename)
maria_chk_init_for_check(param, info);
if (opt_warning_for_wrong_transid == 0)
param->max_trid= ~ (ulonglong) 0;
+
error= maria_chk_status(param,info);
+ /* Forget warning printed by maria_chk_status if no problems found */
+ warning_printed_by_chk_status= param->warning_printed;
+ param->warning_printed= 0;
+
maria_intersect_keys_active(share->state.key_map, param->keys_in_use);
error|= maria_chk_size(param,info);
if (!error || !(param->testflag & (T_FAST | T_FORCE_CREATE)))
@@ -1371,8 +1378,12 @@ static int maria_chk(HA_CHECK *param, char *filename)
(state_updated ? UPDATE_STAT : 0) |
((param->testflag & T_SORT_RECORDS) ?
UPDATE_SORT : 0)));
- if (!(param->testflag & T_SILENT))
+ if (warning_printed_by_chk_status)
+ _ma_check_print_info(param, "Aria table '%s' was ok. Status updated",
+ filename);
+ else if (!(param->testflag & T_SILENT))
printf("State updated\n");
+ warning_printed_by_chk_status= 0;
}
info->update&= ~HA_STATE_CHANGED;
_ma_reenable_logging_for_table(info, FALSE);
@@ -1426,7 +1437,7 @@ end2:
"Aria table '%s' is corrupted\nFix it using switch \"-r\" or \"-o\"\n",
filename));
}
- else if (param->warning_printed &&
+ else if ((param->warning_printed || warning_printed_by_chk_status) &&
! (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX |
T_FORCE_CREATE)))
{
@@ -1435,6 +1446,7 @@ end2:
VOID(fprintf(stderr, "Aria table '%s' is usable but should be fixed\n",
filename));
}
+
VOID(fflush(stderr));
DBUG_RETURN(error);
} /* maria_chk */
@@ -1464,7 +1476,7 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
DBUG_VOID_RETURN;
}
- printf("Aria file: %s\n",name);
+ printf("Aria file: %s\n",name);
printf("Record format: %s\n", record_formats[share->data_file_type]);
printf("Crashsafe: %s\n",
share->base.born_transactional ? "yes" : "no");
@@ -1564,8 +1576,8 @@ static void descript(HA_CHECK *param, register MARIA_HA *info, char *name)
if (share->base.max_data_file_length != HA_OFFSET_ERROR ||
share->base.max_key_file_length != HA_OFFSET_ERROR)
printf("Max datafile length: %16s Max keyfile length: %18s\n",
- llstr(share->base.max_data_file_length-1,llbuff),
- llstr(share->base.max_key_file_length-1,llbuff2));
+ ullstr(share->base.max_data_file_length,llbuff),
+ ullstr(share->base.max_key_file_length,llbuff2));
}
}
printf("Block_size: %16d\n",(int) share->block_size);
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index eeb72c83287..d21d438d64b 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -126,6 +126,8 @@ typedef struct st_maria_state_info
increased.
*/
LSN skip_redo_lsn;
+ /* LSN when we wrote file id to the log */
+ LSN logrec_file_id;
/* the following isn't saved on disk */
uint state_diff_length; /* Should be 0 */
@@ -245,9 +247,10 @@ typedef struct st_maria_file_bitmap
{
uchar *map;
pgcache_page_no_t page; /* Page number for current bitmap */
- uint used_size; /* Size of bitmap head that is not 0 */
+ pgcache_page_no_t last_bitmap_page; /* Last possible bitmap page */
my_bool changed; /* 1 if page needs to be written */
my_bool changed_not_flushed; /* 1 if some bitmap is not flushed */
+ uint used_size; /* Size of bitmap head that is not 0 */
uint flush_all_requested; /**< If _ma_bitmap_flush_all waiting */
uint waiting_for_flush_all_requested; /* If someone is waiting for above */
uint non_flushable; /**< 0 if bitmap and log are in sync */
@@ -261,6 +264,8 @@ typedef struct st_maria_file_bitmap
/* Constants, allocated when initiating bitmaps */
uint sizes[8]; /* Size per bit combination */
uint total_size; /* Total usable size of bitmap page */
+ uint max_total_size; /* Max value for total_size */
+ uint last_total_size; /* Size of bitmap on last_bitmap_page */
uint block_size; /* Block size of file */
ulong pages_covered; /* Pages covered by bitmap + 1 */
DYNAMIC_ARRAY pinned_pages; /**< not-yet-flushable bitmap pages */
@@ -273,6 +278,7 @@ typedef struct st_maria_file_bitmap
typedef struct st_maria_share
{ /* Shared between opens */
MARIA_STATE_INFO state;
+ MARIA_STATE_INFO checkpoint_state; /* Copy of saved state by checkpoint */
MARIA_BASE_INFO base;
MARIA_STATE_HISTORY *state_history;
MARIA_KEYDEF ft2_keyinfo; /* Second-level ft-key definition */
@@ -741,7 +747,7 @@ struct st_maria_handler
{ length=mi_uint2korr((key)+1)+3; } \
}
-#define maria_max_key_length() ((maria_block_size - MAX_KEYPAGE_HEADER_SIZE)/2 - MARIA_INDEX_OVERHEAD_SIZE)
+#define _ma_max_key_length() ((maria_block_size - MAX_KEYPAGE_HEADER_SIZE)/3 - MARIA_INDEX_OVERHEAD_SIZE)
#define get_pack_length(length) ((length) >= 255 ? 3 : 1)
#define _ma_have_versioning(info) ((info)->row_flag & ROW_FLAG_TRANSID)
@@ -822,6 +828,7 @@ extern uchar maria_zero_string[];
extern my_bool maria_inited, maria_in_ha_maria, maria_recovery_changed_data;
extern my_bool maria_recovery_verbose, maria_checkpoint_disabled;
extern my_bool maria_assert_if_crashed_table;
+extern ulong maria_checkpoint_min_log_activity;
extern HASH maria_stored_state;
extern int (*maria_create_trn_hook)(MARIA_HA *);
extern my_bool (*ma_killed)(MARIA_HA *);
@@ -1220,6 +1227,8 @@ int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index,
See ma_check_standalone.h .
*/
int _ma_killed_ptr(HA_CHECK *param);
+void _ma_report_progress(HA_CHECK *param, ulonglong progress,
+ ulonglong max_progress);
void _ma_check_print_error _VARARGS((HA_CHECK *param, const char *fmt, ...))
ATTRIBUTE_FORMAT(printf, 2, 3);
void _ma_check_print_warning _VARARGS((HA_CHECK *param, const char *fmt, ...))
diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c
index 8332af60de5..350bfa1914c 100644
--- a/storage/maria/maria_pack.c
+++ b/storage/maria/maria_pack.c
@@ -3062,7 +3062,6 @@ static int mrg_rrnd(PACK_MRG_INFO *info,uchar *buf)
{
int error;
MARIA_HA *isam_info;
- my_off_t filepos;
if (!info->current)
{
@@ -3087,7 +3086,6 @@ static int mrg_rrnd(PACK_MRG_INFO *info,uchar *buf)
return(HA_ERR_END_OF_FILE);
info->current++;
isam_info= *info->current;
- filepos=isam_info->s->pack.header_length;
maria_reset(isam_info);
maria_extra(isam_info,HA_EXTRA_CACHE, 0);
if ((error= maria_scan_init(isam_info)))
diff --git a/storage/maria/maria_read_log.c b/storage/maria/maria_read_log.c
index b335aa3692e..b3f3eb345be 100644
--- a/storage/maria/maria_read_log.c
+++ b/storage/maria/maria_read_log.c
@@ -32,7 +32,7 @@ const char *default_dbug_option= "d:t:o,/tmp/aria_read_log.trace";
static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent;
static my_bool opt_check;
static const char *opt_tmpdir;
-static ulong opt_page_buffer_size;
+static ulong opt_page_buffer_size, opt_translog_buffer_size;
static ulonglong opt_start_from_lsn, opt_end_lsn, opt_start_from_checkpoint;
static MY_TMPDIR maria_chk_tmpdir;
@@ -80,9 +80,8 @@ int main(int argc, char **argv)
But if it finds a log and this log was crashed, it will create a new log,
which is useless. TODO: start log handler in read-only mode.
*/
- if (init_pagecache(maria_log_pagecache,
- TRANSLOG_PAGECACHE_SIZE, 0, 0,
- TRANSLOG_PAGE_SIZE, MY_WME) == 0 ||
+ if (init_pagecache(maria_log_pagecache, opt_translog_buffer_size,
+ 0, 0, TRANSLOG_PAGE_SIZE, MY_WME) == 0 ||
translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
0, 0, maria_log_pagecache, TRANSLOG_DEFAULT_FLAGS,
opt_display_only))
@@ -166,7 +165,7 @@ err:
#include "ma_check_standalone.h"
enum options_mc {
- OPT_CHARSETS_DIR=256
+ OPT_CHARSETS_DIR=256, OPT_FORCE_CRASH, OPT_TRANSLOG_BUFFER_SIZE
};
static struct my_option my_long_options[] =
@@ -186,6 +185,9 @@ static struct my_option my_long_options[] =
#ifndef DBUG_OFF
{"debug", '#', "Output debug log. Often the argument is 'd:t:o,filename'.",
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"force-crash", OPT_FORCE_CRASH, "Force crash after # recovery events",
+ &maria_recovery_force_crash_counter, 0,0, GET_ULONG, REQUIRED_ARG,
+ 0, 0, ~(long) 0, 0, 0, 0},
#endif
{"help", '?', "Display this help and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -225,6 +227,12 @@ static struct my_option my_long_options[] =
"colon (:)"
#endif
, (char**) &opt_tmpdir, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ { "translog-buffer-size", OPT_TRANSLOG_BUFFER_SIZE,
+ "The size of the buffer used for transaction log for Aria tables",
+ &opt_translog_buffer_size, &opt_translog_buffer_size, 0,
+ GET_ULONG, REQUIRED_ARG, (long) TRANSLOG_PAGECACHE_SIZE,
+ 1024L*1024L, (long) ~(ulong) 0, (long) MALLOC_OVERHEAD,
+ (long) IO_SIZE, 0},
{"undo", 'u', "Apply UNDO records to tables. (disable with --disable-undo)",
(uchar **) &opt_apply_undo, (uchar **) &opt_apply_undo, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
diff --git a/storage/maria/plug.in b/storage/maria/plug.in
index c48928be44f..609adcb2f66 100644
--- a/storage/maria/plug.in
+++ b/storage/maria/plug.in
@@ -1,6 +1,5 @@
MYSQL_STORAGE_ENGINE(aria,, [Aria Storage Engine],
[Crash-safe tables with MyISAM heritage], [default,max,max-no-ndb])
-MYSQL_PLUGIN_DIRECTORY(aria, [storage/maria])
MYSQL_PLUGIN_STATIC(aria, [libaria_s.la], [libaria_embedded.la])
MYSQL_PLUGIN_ACTIONS(aria, [
diff --git a/storage/maria/trnman.c b/storage/maria/trnman.c
index 05330baed76..36880a59b51 100644
--- a/storage/maria/trnman.c
+++ b/storage/maria/trnman.c
@@ -179,6 +179,7 @@ int trnman_init(TrID initial_trid)
trnman_allocated_transactions= 0;
/* This is needed for recovery and repair */
dummy_transaction_object.min_read_from= ~(TrID) 0;
+ dummy_transaction_object.first_undo_lsn= TRANSACTION_LOGGED_LONG_ID;
pool= 0;
global_trid_generator= initial_trid;
diff --git a/storage/maria/unittest/CMakeLists.txt b/storage/maria/unittest/CMakeLists.txt
index a6e8736daab..715a6199185 100644
--- a/storage/maria/unittest/CMakeLists.txt
+++ b/storage/maria/unittest/CMakeLists.txt
@@ -13,10 +13,9 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
${CMAKE_SOURCE_DIR}/unittest/mytap)
-LINK_LIBRARIES(maria myisam mytap mysys dbug strings wsock32 zlib)
+LINK_LIBRARIES(libmaria_s libmyisam_s mytap mysys dbug strings wsock32 zlib)
ADD_EXECUTABLE(ma_control_file-t ma_control_file-t.c)
ADD_EXECUTABLE(trnman-t trnman-t.c)
diff --git a/storage/myisam/CMakeLists.txt b/storage/myisam/CMakeLists.txt
index e7e3de64cf3..ce27c209418 100644
--- a/storage/myisam/CMakeLists.txt
+++ b/storage/myisam/CMakeLists.txt
@@ -32,31 +32,31 @@ MYSQL_STORAGE_ENGINE(MYISAM)
IF(NOT SOURCE_SUBLIBS)
MYSQL_ADD_EXECUTABLE(myisam_ftdump myisam_ftdump.c DESTINATION bin)
- TARGET_LINK_LIBRARIES(myisam_ftdump myisam mysys debug dbug strings zlib wsock32)
+ TARGET_LINK_LIBRARIES(myisam_ftdump libmyisam_s mysys debug dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(myisamchk myisamchk.c DESTINATION bin)
- TARGET_LINK_LIBRARIES(myisamchk myisam mysys debug dbug strings zlib wsock32)
+ TARGET_LINK_LIBRARIES(myisamchk libmyisam_s mysys debug dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(myisamlog myisamlog.c DESTINATION bin)
- TARGET_LINK_LIBRARIES(myisamlog myisam mysys debug dbug strings zlib wsock32)
+ TARGET_LINK_LIBRARIES(myisamlog libmyisam_s mysys debug dbug strings zlib wsock32)
MYSQL_ADD_EXECUTABLE(myisampack myisampack.c DESTINATION bin)
- TARGET_LINK_LIBRARIES(myisampack myisam mysys debug dbug strings zlib wsock32)
+ TARGET_LINK_LIBRARIES(myisampack libmyisam_s mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(mi_test1 mi_test1.c)
- TARGET_LINK_LIBRARIES(mi_test1 myisam mysys debug dbug strings zlib wsock32)
+ TARGET_LINK_LIBRARIES(mi_test1 libmyisam_s mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(mi_test2 mi_test2.c)
- TARGET_LINK_LIBRARIES(mi_test2 myisam mysys debug dbug strings zlib wsock32)
+ TARGET_LINK_LIBRARIES(mi_test2 libmyisam_s mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(mi_test3 mi_test3.c)
- TARGET_LINK_LIBRARIES(mi_test3 myisam mysys debug dbug strings zlib wsock32)
+ TARGET_LINK_LIBRARIES(mi_test3 libmyisam_s mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(sp_test sp_test.c)
- TARGET_LINK_LIBRARIES(sp_test myisam mysys debug dbug strings zlib wsock32)
+ TARGET_LINK_LIBRARIES(sp_test libmyisam_s mysys debug dbug strings zlib wsock32)
ADD_EXECUTABLE(rt_test rt_test.c)
- TARGET_LINK_LIBRARIES(rt_test myisam mysys debug dbug strings zlib wsock32)
+ TARGET_LINK_LIBRARIES(rt_test libmyisam_s mysys debug dbug strings zlib wsock32)
SET_TARGET_PROPERTIES(myisamchk myisampack PROPERTIES LINK_FLAGS "setargv.obj")
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 8f3b05a7a51..2ee516bf9ec 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -91,14 +91,16 @@ static void mi_check_print_msg(HA_CHECK *param, const char* msg_type,
if (!thd->vio_ok())
{
- sql_print_error("%s", msgbuf);
+ sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf);
return;
}
if (param->testflag & (T_CREATE_MISSING_KEYS | T_SAFE_REPAIR |
T_AUTO_REPAIR))
{
- my_message(ER_NOT_KEYFILE,msgbuf,MYF(MY_WME));
+ my_message(ER_NOT_KEYFILE, msgbuf, MYF(MY_WME));
+ if (thd->variables.log_warnings > 2 && ! thd->log_all_errors)
+ sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf);
return;
}
length=(uint) (strxmov(name, param->db_name,".",param->table_name,NullS) -
@@ -123,6 +125,9 @@ static void mi_check_print_msg(HA_CHECK *param, const char* msg_type,
if (protocol->write())
sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
msgbuf);
+ else if (thd->variables.log_warnings > 2)
+ sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf);
+
#ifdef THREAD
if (param->need_print_msg_lock)
pthread_mutex_unlock(&param->print_msg_mutex);
@@ -523,6 +528,7 @@ void mi_check_print_info(HA_CHECK *param, const char *fmt,...)
va_list args;
va_start(args, fmt);
mi_check_print_msg(param, "info", fmt, args);
+ param->note_printed= 1;
va_end(args);
}
@@ -545,7 +551,6 @@ my_bool mi_killed_in_mariadb(MI_INFO *info)
}
-
ha_myisam::ha_myisam(handlerton *hton, TABLE_SHARE *table_arg)
:handler(hton, table_arg), file(0),
int_table_flags(HA_NULL_IN_KEY | HA_CAN_FULLTEXT | HA_CAN_SQL_HANDLER |
@@ -1095,7 +1100,7 @@ int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt)
param.testflag&= ~(T_RETRY_WITHOUT_QUICK | T_QUICK);
/* Ensure we don't loose any rows when retrying without quick */
param.testflag|= T_SAFE_REPAIR;
- sql_print_information("Retrying repair of: '%s' without quick",
+ sql_print_information("Retrying repair of: '%s' including modifying data file",
table->s->path.str);
continue;
}
@@ -1696,16 +1701,19 @@ bool ha_myisam::check_and_repair(THD *thd)
if ((marked_crashed= mi_is_crashed(file)) || check(thd, &check_opt))
{
+ bool save_log_all_errors;
sql_print_warning("Recovering table: '%s'",table->s->path.str);
- if (myisam_recover_options & (HA_RECOVER_FULL_BACKUP | HA_RECOVER_BACKUP))
+ save_log_all_errors= thd->log_all_errors;
+ thd->log_all_errors|= (thd->variables.log_warnings > 2);
+ if (myisam_recover_options & HA_RECOVER_FULL_BACKUP)
{
char buff[MY_BACKUP_NAME_EXTRA_LENGTH+1];
my_create_backup_name(buff, "", check_opt.start_time);
- sql_print_information("Making backup of data with extension '%s'", buff);
- }
- if (myisam_recover_options & HA_RECOVER_FULL_BACKUP)
+ sql_print_information("Making backup of index file with extension '%s'",
+ buff);
mi_make_backup_of_index(file, check_opt.start_time,
MYF(MY_WME | ME_JUST_WARNING));
+ }
check_opt.flags=
(((myisam_recover_options &
(HA_RECOVER_BACKUP | HA_RECOVER_FULL_BACKUP)) ? T_BACKUP_DATA : 0) |
@@ -1714,6 +1722,7 @@ bool ha_myisam::check_and_repair(THD *thd)
T_AUTO_REPAIR);
if (repair(thd, &check_opt))
error=1;
+ thd->log_all_errors= save_log_all_errors;
}
thd->set_query(old_query, old_query_length);
DBUG_RETURN(error);
@@ -1790,7 +1799,14 @@ int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
- return mi_rkey(file, buf, index, key, keypart_map, find_flag);
+ int res;
+ /* Use the pushed index condition if it matches the index we're scanning */
+ end_range= NULL;
+ if (index == pushed_idx_cond_keyno)
+ mi_set_index_cond_func(file, index_cond_func_myisam, this);
+ res= mi_rkey(file, buf, index, key, keypart_map, find_flag);
+ mi_set_index_cond_func(file, NULL, 0);
+ return res;
}
int ha_myisam::index_next(uchar *buf)
@@ -1955,9 +1971,6 @@ int ha_myisam::extra(enum ha_extra_function operation)
int ha_myisam::reset(void)
{
- pushed_idx_cond= NULL;
- pushed_idx_cond_keyno= MAX_KEY;
- in_range_check_pushed_down= FALSE;
mi_set_index_cond_func(file, NULL, 0);
ds_mrr.dsmrr_close();
return mi_reset(file);
@@ -1988,6 +2001,13 @@ int ha_myisam::delete_table(const char *name)
return mi_delete_table(name);
}
+void ha_myisam::change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
+{
+ handler::change_table_ptr(table_arg, share);
+ if (file)
+ file->external_ref= table_arg;
+}
+
int ha_myisam::external_lock(THD *thd, int lock_type)
{
diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h
index f895a5bf449..e25cbee03e6 100644
--- a/storage/myisam/ha_myisam.h
+++ b/storage/myisam/ha_myisam.h
@@ -68,7 +68,7 @@ class ha_myisam: public handler
uint max_supported_key_length() const { return HA_MAX_KEY_LENGTH; }
uint max_supported_key_part_length() const { return HA_MAX_KEY_LENGTH; }
uint checksum() const;
-
+ void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
int open(const char *name, int mode, uint test_if_locked);
int close(void);
int write_row(uchar * buf);
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index 8dc73443f50..eb4592f4459 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -85,6 +85,8 @@ static SORT_KEY_BLOCKS *alloc_key_blocks(HA_CHECK *param, uint blocks,
uint buffer_length);
static ha_checksum mi_byte_checksum(const uchar *buf, uint length);
static void set_data_file_type(MI_SORT_INFO *sort_info, MYISAM_SHARE *share);
+static int replace_data_file(HA_CHECK *param, MI_INFO *info,
+ const char *name, File new_file);
void myisamchk_init(HA_CHECK *param)
{
@@ -947,7 +949,6 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend)
char llbuff[22],llbuff2[22],llbuff3[22];
ha_checksum intern_record_checksum;
ha_checksum key_checksum[HA_MAX_POSSIBLE_KEY];
- my_bool static_row_size;
MI_KEYDEF *keyinfo;
MI_BLOCK_INFO block_info;
DBUG_ENTER("chk_data_link");
@@ -972,7 +973,6 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend)
empty=info->s->pack.header_length;
/* Check how to calculate checksum of rows */
- static_row_size=1;
if (info->s->data_file_type == COMPRESSED_RECORD)
{
for (field=0 ; field < info->s->base.fields ; field++)
@@ -980,7 +980,6 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend)
if (info->s->rec[field].base_type == FIELD_BLOB ||
info->s->rec[field].base_type == FIELD_VARCHAR)
{
- static_row_size=0;
break;
}
}
@@ -1344,7 +1343,7 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend)
}
if (param->testflag & T_INFO)
{
- if (param->warning_printed || param->error_printed)
+ if (param->warning_printed || param->error_printed || param->note_printed)
puts("");
if (used != 0 && ! param->error_printed)
{
@@ -1537,6 +1536,8 @@ int mi_repair(HA_CHECK *param, register MI_INFO *info,
got_error=1;
new_file= -1;
sort_param.sort_info=&sort_info;
+ param->retry_repair= 0;
+ param->warning_printed= param->error_printed= param->note_printed= 0;
if (!(param->testflag & T_SILENT))
{
@@ -1681,7 +1682,7 @@ int mi_repair(HA_CHECK *param, register MI_INFO *info,
if (rep_quick && del+sort_info.dupp != info->state->del)
{
mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
- mi_check_print_error(param,"Run recovery again without -q");
+ mi_check_print_error(param,"Run recovery again without --quick");
got_error=1;
param->retry_repair=1;
param->testflag|=T_RETRY_WITHOUT_QUICK;
@@ -1733,17 +1734,8 @@ err:
/* Replace the actual file with the temporary file */
if (new_file >= 0)
{
- my_close(new_file,MYF(0));
- info->dfile=new_file= -1;
- if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
- DATA_TMP_EXT,
- param->backup_time,
- share->base.raid_chunks,
- (param->testflag & T_BACKUP_DATA ?
- MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
- mi_open_datafile(info,share,name,-1))
- got_error=1;
-
+ got_error= replace_data_file(param, info, name, new_file);
+ new_file= -1;
param->retry_repair= 0;
}
}
@@ -1921,7 +1913,7 @@ int flush_blocks(HA_CHECK *param, KEY_CACHE *key_cache, File file,
{
if (flush_key_blocks(key_cache, file, dirty_part_map, FLUSH_RELEASE))
{
- mi_check_print_error(param,"%d when trying to write bufferts",my_errno);
+ mi_check_print_error(param,"%d when trying to write buffers",my_errno);
return(1);
}
if (!param->using_global_keycache)
@@ -2235,7 +2227,7 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
MYISAM_SHARE *share=info->s;
HA_KEYSEG *keyseg;
ulong *rec_per_key_part;
- char llbuff[22];
+ char llbuff[22], llbuff2[22];
MI_SORT_INFO sort_info;
ulonglong UNINIT_VAR(key_map);
DBUG_ENTER("mi_repair_by_sort");
@@ -2251,12 +2243,15 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
printf("Data records: %s\n", llstr(start_records,llbuff));
}
param->testflag|=T_REP; /* for easy checking */
+ param->retry_repair= 0;
+ param->warning_printed= param->error_printed= param->note_printed= 0;
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|=T_CALC_CHECKSUM;
bzero((char*)&sort_info,sizeof(sort_info));
bzero((char *)&sort_param, sizeof(sort_param));
+
if (!(sort_info.key_block=
alloc_key_blocks(param,
(uint) param->sort_key_blocks,
@@ -2268,7 +2263,7 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
init_io_cache(&info->rec_cache,info->dfile,
(uint) param->write_buffer_length,
WRITE_CACHE,new_header_length,1,
- MYF(MY_WME | MY_WAIT_IF_FULL) & param->myf_rw)))
+ MYF((param->myf_rw & MY_WAIT_IF_FULL) | MY_WME))))
goto err;
sort_info.key_block_end=sort_info.key_block+param->sort_key_blocks;
info->opt_flag|=WRITE_CACHE_USED;
@@ -2440,7 +2435,10 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
(my_bool) (!(param->testflag & T_VERBOSE)),
(uint) param->sort_buffer_length))
{
- param->retry_repair=1;
+ param->retry_repair= 1;
+ if (! param->error_printed)
+ mi_check_print_error(param, "Couldn't fix table with create_index_by_sort(). Error: %d",
+ my_errno);
goto err;
}
/* No need to calculate checksum again. */
@@ -2469,7 +2467,10 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
/* Don't repair if we loosed more than one row */
if (info->state->records+1 < start_records)
{
- info->state->records=start_records;
+ mi_check_print_error(param,
+ "Couldn't fix table as SAFE_REPAIR was requested and we would loose too many rows. %s -> %s",
+ llstr(start_records, llbuff), llstr(info->state->records, llbuff2));
+ info->state->records= start_records;
goto err;
}
}
@@ -2499,7 +2500,7 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info,
if (rep_quick && del+sort_info.dupp != info->state->del)
{
mi_check_print_error(param,"Couldn't fix table with quick recovery: Found wrong number of deleted records");
- mi_check_print_error(param,"Run recovery again without -q");
+ mi_check_print_error(param,"Run recovery again without --quick");
got_error=1;
param->retry_repair=1;
param->testflag|=T_RETRY_WITHOUT_QUICK;
@@ -2553,15 +2554,8 @@ err:
/* Replace the actual file with the temporary file */
if (new_file >= 0)
{
- my_close(new_file,MYF(0));
- info->dfile=new_file= -1;
- if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
- DATA_TMP_EXT, param->backup_time,
- share->base.raid_chunks,
- (param->testflag & T_BACKUP_DATA ?
- MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
- mi_open_datafile(info,share,name,-1))
- got_error=1;
+ got_error= replace_data_file(param, info, name, new_file);
+ new_file= -1;
}
}
if (got_error)
@@ -2578,6 +2572,8 @@ err:
param->retry_repair= 0; /* Safety */
}
mi_mark_crashed_on_repair(info);
+ if (killed_ptr(param))
+ param->retry_repair= 0; /* No use to retry repair */
}
else if (key_map == share->state.key_map)
share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
@@ -2678,6 +2674,9 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info,
printf("Data records: %s\n", llstr(start_records,llbuff));
}
param->testflag|=T_REP; /* for easy checking */
+ param->retry_repair= 0;
+ param->warning_printed= 0;
+ param->error_printed= 0;
if (info->s->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
param->testflag|=T_CALC_CHECKSUM;
@@ -3092,15 +3091,8 @@ err:
/* Replace the actual file with the temporary file */
if (new_file >= 0)
{
- my_close(new_file,MYF(0));
- info->dfile=new_file= -1;
- if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
- DATA_TMP_EXT, param->backup_time,
- share->base.raid_chunks,
- (param->testflag & T_BACKUP_DATA ?
- MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
- mi_open_datafile(info,share,name,-1))
- got_error=1;
+ got_error= replace_data_file(param, info, name, new_file);
+ new_file= -1;
}
}
if (got_error)
@@ -3117,6 +3109,8 @@ err:
param->retry_repair= 0; /* Safety */
}
mi_mark_crashed_on_repair(info);
+ if (killed_ptr(param))
+ param->retry_repair= 0;
}
else if (key_map == share->state.key_map)
share->state.changed&= ~STATE_NOT_OPTIMIZED_KEYS;
@@ -3152,7 +3146,13 @@ static int sort_key_read(MI_SORT_PARAM *sort_param, void *key)
DBUG_ENTER("sort_key_read");
if ((error=sort_get_next_record(sort_param)))
+ {
+ DBUG_ASSERT(error < 0 ||
+ sort_info->param->error_printed ||
+ sort_info->param->warning_printed ||
+ sort_info->param->note_printed);
DBUG_RETURN(error);
+ }
if (info->state->records == sort_info->max_records)
{
mi_check_print_error(sort_info->param,
@@ -3269,7 +3269,12 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
DBUG_ENTER("sort_get_next_record");
if (killed_ptr(param))
+ {
+ mi_check_print_error(param, "Repair killed by user with cause: %d",
+ (int) killed_ptr(param));
+ param->retry_repair= 0;
DBUG_RETURN(1);
+ }
switch (share->data_file_type) {
case STATIC_RECORD:
@@ -3355,6 +3360,8 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
}
if (searching && ! sort_param->fix_datafile)
{
+ mi_check_print_info(param,
+ "Datafile is corrupted; Restart repair with option to copy datafile");
param->error_printed=1;
param->retry_repair=1;
param->testflag|=T_RETRY_WITHOUT_QUICK;
@@ -3416,6 +3423,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
}
if (error)
{
+ DBUG_ASSERT(param->note_printed);
if (found_record)
goto try_next;
searching=1;
@@ -3456,7 +3464,11 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
share->state.split++;
}
if (found_record)
+ {
+ mi_check_print_info(param,
+ "Found row block followed by deleted block");
goto try_next;
+ }
if (searching)
{
pos+=MI_DYN_ALIGN_SIZE;
@@ -3490,6 +3502,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
mi_check_print_error(param,"Not enough memory for blob at %s (need %lu)",
llstr(sort_param->start_recpos,llbuff),
(ulong) block_info.rec_len);
+ DBUG_ASSERT(param->error_printed);
DBUG_RETURN(1);
}
else
@@ -3571,8 +3584,6 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
if (_mi_rec_unpack(info,sort_param->record,sort_param->rec_buff,
sort_param->find_length) != MY_FILE_ERROR)
{
- if (sort_param->read_cache.error < 0)
- DBUG_RETURN(1);
if (sort_param->calc_checksum)
info->checksum= (*info->s->calc_check_checksum)(info,
sort_param->record);
@@ -3598,6 +3609,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
sort_param->key+1,
llstr(sort_param->start_recpos,llbuff));
try_next:
+ DBUG_ASSERT(param->error_printed || param->note_printed);
pos=(sort_param->start_recpos+=MI_DYN_ALIGN_SIZE);
searching=1;
}
@@ -3669,6 +3681,7 @@ static int sort_get_next_record(MI_SORT_PARAM *sort_param)
DBUG_ASSERT(0); /* Impossible */
break;
}
+ DBUG_ASSERT(0); /* Impossible */
DBUG_RETURN(1); /* Impossible */
}
@@ -3727,7 +3740,7 @@ int sort_write_record(MI_SORT_PARAM *sort_param)
if (sort_info->buff_length < reclength)
{
if (!(sort_info->buff=my_realloc(sort_info->buff, (uint) reclength,
- MYF(MY_FREE_ON_ERROR |
+ MYF(MY_FREE_ON_ERROR | MY_WME |
MY_ALLOW_ZERO_PTR))))
DBUG_RETURN(1);
sort_info->buff_length=reclength;
@@ -4765,3 +4778,29 @@ int mi_make_backup_of_index(MI_INFO *info, time_t backup_time, myf flags)
my_create_backup_name(backup_name, info->s->index_file_name, backup_time);
return my_copy(info->s->index_file_name, backup_name, flags);
}
+
+static int replace_data_file(HA_CHECK *param, MI_INFO *info,
+ const char *name, File new_file)
+{
+ MYISAM_SHARE *share=info->s;
+
+ my_close(new_file,MYF(0));
+ info->dfile= -1;
+ if (param->testflag & T_BACKUP_DATA)
+ {
+ char buff[MY_BACKUP_NAME_EXTRA_LENGTH+1];
+ my_create_backup_name(buff, "", param->backup_time);
+ my_printf_error(0, /* No error, just info */
+ "Making backup of data file with extension '%s'",
+ MYF(ME_JUST_INFO | ME_NOREFRESH), buff);
+ }
+
+ if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
+ DATA_TMP_EXT, param->backup_time,
+ share->base.raid_chunks,
+ (param->testflag & T_BACKUP_DATA ?
+ MYF(MY_REDEL_MAKE_BACKUP): MYF(0))) ||
+ mi_open_datafile(info, share, name, -1))
+ return 1;
+ return 0;
+}
diff --git a/storage/myisam/mi_dbug.c b/storage/myisam/mi_dbug.c
index ab85ece07ab..76d5d13fc5b 100644
--- a/storage/myisam/mi_dbug.c
+++ b/storage/myisam/mi_dbug.c
@@ -173,6 +173,7 @@ my_bool check_table_is_closed(const char *name, const char *where)
DBUG_ENTER("check_table_is_closed");
(void) fn_format(filename,name,"",MI_NAME_IEXT,4+16+32);
+ pthread_mutex_lock(&THR_LOCK_myisam);
for (pos=myisam_open_list ; pos ; pos=pos->next)
{
MI_INFO *info=(MI_INFO*) pos->data;
@@ -183,10 +184,12 @@ my_bool check_table_is_closed(const char *name, const char *where)
{
fprintf(stderr,"Warning: Table: %s is open on %s\n", name,where);
DBUG_PRINT("warning",("Table: %s is open on %s", name,where));
+ pthread_mutex_unlock(&THR_LOCK_myisam);
DBUG_RETURN(1);
}
}
}
+ pthread_mutex_unlock(&THR_LOCK_myisam);
DBUG_RETURN(0);
}
#endif /* EXTRA_DEBUG */
diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c
index 97011831af8..17c1fc83f13 100644
--- a/storage/myisam/mi_locking.c
+++ b/storage/myisam/mi_locking.c
@@ -239,7 +239,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
break; /* Impossible */
}
}
-#ifdef __WIN__
+#ifdef _WIN32
else
{
/*
@@ -521,11 +521,11 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
share->state.update_count= info->last_loop= ++info->this_loop;
if ((error=mi_state_info_write(share->kfile, &share->state, 1)))
olderror=my_errno;
-#ifdef __WIN__
+#ifdef _WIN32
if (myisam_flush)
{
- _commit(share->kfile);
- _commit(info->dfile);
+ my_sync(share->kfile,0);
+ my_sync(info->dfile,0);
}
#endif
}
diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c
index c463f0e3daa..444d1970913 100644
--- a/storage/myisam/mi_test2.c
+++ b/storage/myisam/mi_test2.c
@@ -836,6 +836,7 @@ end:
puts("Locking used");
if (use_blob)
puts("blobs used");
+ bzero(&stats, sizeof(stats));
get_key_cache_statistics(dflt_key_cache, 0, &stats);
printf("key cache status: \n\
blocks used:%10lu\n\
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index 8c54d7f0411..83a106c7941 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -1757,6 +1757,7 @@ void mi_check_print_info(HA_CHECK *param __attribute__((unused)),
{
va_list args;
+ param->note_printed=1;
va_start(args,fmt);
VOID(vfprintf(stdout, fmt, args));
VOID(fputc('\n',stdout));
diff --git a/storage/myisam/plug.in b/storage/myisam/plug.in
index 95b29336493..0ec7ea1e1d2 100644
--- a/storage/myisam/plug.in
+++ b/storage/myisam/plug.in
@@ -1,6 +1,5 @@
dnl MYSQL_STORAGE_ENGINE(myisam,no, [MyISAM Storage Engine],
dnl [Traditional non-transactional MySQL tables])
-dnl MYSQL_PLUGIN_DIRECTORY(myisam, [storage/myisam])
dnl MYSQL_PLUGIN_STATIC(myisam, [libmyisam_s.la], [libmyisam_embedded.la])
dnl MYSQL_PLUGIN_MANDATORY(myisam) dnl Default
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index 2b6d5167c93..db589759128 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -151,6 +151,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
{
mi_check_print_error(info->sort_info->param,
"myisam_sort_buffer_size is too small");
+ my_errno= ENOMEM;
goto err;
}
}
@@ -175,7 +176,8 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages,
if (memavl < MIN_SORT_BUFFER)
{
mi_check_print_error(info->sort_info->param,"MyISAM sort buffer too small"); /* purecov: tested */
- goto err; /* purecov: tested */
+ my_errno= ENOMEM; /* purecov: tested */
+ goto err; /* purecov: tested */
}
(*info->lock_in_memory)(info->sort_info->param);/* Everything is allocated */
diff --git a/storage/myisammrg/plug.in b/storage/myisammrg/plug.in
index a2654373fba..22cd5b17cb4 100644
--- a/storage/myisammrg/plug.in
+++ b/storage/myisammrg/plug.in
@@ -1,5 +1,4 @@
MYSQL_STORAGE_ENGINE(myisammrg,no,[MyISAM MERGE Engine],
[Merge multiple MySQL tables into one])
-MYSQL_PLUGIN_DIRECTORY(myisammrg,[storage/myisammrg])
MYSQL_PLUGIN_STATIC(myisammrg, [libmyisammrg_s.la], [libmyisammrg_embedded.la])
MYSQL_PLUGIN_MANDATORY(myisammrg)
diff --git a/storage/mysql_storage_engine.cmake b/storage/mysql_storage_engine.cmake
index 07b4151c50c..b29ba961179 100644
--- a/storage/mysql_storage_engine.cmake
+++ b/storage/mysql_storage_engine.cmake
@@ -10,41 +10,41 @@
# ${engine}_LIBS variable containing extra libraries to link with may be set
-MACRO(MYSQL_STORAGE_ENGINE engine)
+MACRO(MYSQL_PLUGIN engine)
IF(NOT SOURCE_SUBLIBS)
# Add common include directories
- INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/zlib
- ${CMAKE_SOURCE_DIR}/sql
- ${CMAKE_SOURCE_DIR}/regex
- ${CMAKE_SOURCE_DIR}/extra/yassl/include
- ${CMAKE_BINARY_DIR}/include
- ${CMAKE_BINARY_DIR}/sql
- )
+ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/include)
STRING(TOUPPER ${engine} engine)
- STRING(TOLOWER ${engine} libname)
IF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC")
- ADD_DEFINITIONS(-DWITH_${engine}_STORAGE_ENGINE -DMYSQL_SERVER)
- #Create static library. The name of the library is <storage_engine>.lib
- ADD_LIBRARY(${libname} ${${engine}_SOURCES})
- ADD_DEPENDENCIES(${libname} GenError)
+ ADD_LIBRARY(${${engine}_LIB} ${${engine}_SOURCES})
+ ADD_DEPENDENCIES(${${engine}_LIB} GenError)
IF(${engine}_LIBS)
- TARGET_LINK_LIBRARIES(${libname} ${${engine}_LIBS})
+ TARGET_LINK_LIBRARIES(${${engine}_LIB} ${${engine}_LIBS})
ENDIF(${engine}_LIBS)
- MESSAGE("build ${engine} as static library")
+ MESSAGE("build ${engine} as static library (${${engine}_LIB}.lib)")
ELSEIF(${ENGINE_BUILD_TYPE} STREQUAL "DYNAMIC")
ADD_DEFINITIONS(-DMYSQL_DYNAMIC_PLUGIN)
- #Create a DLL.The name of the dll is ha_<storage_engine>.dll
- #The dll is linked to the mysqld executable
- SET(dyn_libname ha_${libname})
- ADD_VERSION_INFO(${dyn_libname} SHARED ${engine}_SOURCES)
- ADD_LIBRARY(${dyn_libname} MODULE ${${engine}_SOURCES})
- TARGET_LINK_LIBRARIES (${dyn_libname} mysqlservices mysqld)
+ ADD_VERSION_INFO(${${engine}_LIB} SHARED ${engine}_SOURCES)
+ ADD_LIBRARY(${${engine}_LIB} MODULE ${${engine}_SOURCES})
+ TARGET_LINK_LIBRARIES (${${engine}_LIB} mysqlservices mysqld)
IF(${engine}_LIBS)
- TARGET_LINK_LIBRARIES(${dyn_libname} ${${engine}_LIBS})
+ TARGET_LINK_LIBRARIES(${${engine}_LIB} ${${engine}_LIBS})
ENDIF(${engine}_LIBS)
# Install the plugin
- MYSQL_INSTALL_TARGETS(${dyn_libname} DESTINATION lib/plugin COMPONENT Server)
- MESSAGE("build ${engine} as DLL")
+ MYSQL_INSTALL_TARGETS(${${engine}_LIB} DESTINATION lib/plugin COMPONENT Server)
+ MESSAGE("build ${engine} as DLL (${${engine}_LIB}.dll)")
+ ENDIF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC")
+ENDIF(NOT SOURCE_SUBLIBS)
+ENDMACRO(MYSQL_PLUGIN)
+
+MACRO(MYSQL_STORAGE_ENGINE engine)
+IF(NOT SOURCE_SUBLIBS)
+ MYSQL_PLUGIN(${engine})
+ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/zlib ${CMAKE_SOURCE_DIR}/sql
+ ${CMAKE_SOURCE_DIR}/regex ${CMAKE_BINARY_DIR}/sql
+ ${CMAKE_SOURCE_DIR}/extra/yassl/include)
+ IF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC")
+ ADD_DEFINITIONS(-DWITH_${engine}_STORAGE_ENGINE -DMYSQL_SERVER)
ENDIF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC")
ENDIF(NOT SOURCE_SUBLIBS)
ENDMACRO(MYSQL_STORAGE_ENGINE)
diff --git a/storage/ndb/plug.in b/storage/ndb/plug.in
index 3d3349f7a8b..d5f30d1e4b2 100644
--- a/storage/ndb/plug.in
+++ b/storage/ndb/plug.in
@@ -1,6 +1,5 @@
MYSQL_STORAGE_ENGINE(ndbcluster, ndbcluster, [Cluster Storage Engine],
[High Availability Clustered tables],)
-MYSQL_PLUGIN_DIRECTORY(ndbcluster,[storage/ndb])
MYSQL_PLUGIN_STATIC(ndbcluster, [[\$(ndbcluster_libs) \$(ndbcluster_system_libs) \$(NDB_SCI_LIBS)]])
MYSQL_PLUGIN_ACTIONS(ndbcluster,[MYSQL_SETUP_NDBCLUSTER])
MYSQL_PLUGIN_DEPENDS(ndbcluster, [partition])
diff --git a/storage/pbxt/plug.in b/storage/pbxt/plug.in
index c0dc06d9702..2d79ad61b3a 100644
--- a/storage/pbxt/plug.in
+++ b/storage/pbxt/plug.in
@@ -1,6 +1,5 @@
MYSQL_STORAGE_ENGINE(pbxt,no, [PBXT Storage Engine],
[MVCC-based transactional engine], [max,max-no-ndb])
-MYSQL_PLUGIN_DIRECTORY(pbxt, [storage/pbxt])
MYSQL_PLUGIN_STATIC(pbxt, [src/libpbxt_s.la], [src/libpbxt_s_embedded.la])
MYSQL_PLUGIN_ACTIONS(pbxt, [
# AC_CONFIG_FILES(storage/pbxt/src/Makefile)
diff --git a/storage/pbxt/src/database_xt.cc b/storage/pbxt/src/database_xt.cc
index 8d1b4e46da9..635cb63224a 100644
--- a/storage/pbxt/src/database_xt.cc
+++ b/storage/pbxt/src/database_xt.cc
@@ -87,7 +87,7 @@ xtPublic void xt_lock_installation(XTThreadPtr self, char *installation_path)
char file_path[PATH_MAX];
char buffer[101];
size_t red_size;
- llong pid;
+ llong pid __attribute__ ((unused));
xtBool cd = pbxt_crash_debug;
xt_strcpy(PATH_MAX, file_path, installation_path);
diff --git a/storage/pbxt/src/ha_pbxt.cc b/storage/pbxt/src/ha_pbxt.cc
index b5cc7d7f34a..bca4f017e7d 100644
--- a/storage/pbxt/src/ha_pbxt.cc
+++ b/storage/pbxt/src/ha_pbxt.cc
@@ -1594,7 +1594,7 @@ static int pbxt_rollback(handlerton *hton, THD *thd, bool all)
if (!all)
self->st_stat_trans = FALSE;
}
- return 0;
+ return err;
}
#ifdef DRIZZLED
@@ -2898,7 +2898,7 @@ int ha_pbxt::update_row(const byte * old_data, byte * new_data)
* insert into t1 (val) values (1);
*/
if (table->found_next_number_field && new_data == table->record[0]) {
- MX_LONGLONG_T nr;
+ MX_LONGLONG_T nr __attribute__ ((unused));
my_bitmap_map *old_map;
old_map = mx_tmp_use_all_columns(table, table->read_set);
diff --git a/storage/pbxt/src/memory_xt.cc b/storage/pbxt/src/memory_xt.cc
index b2f6c248b3c..d498336e814 100644
--- a/storage/pbxt/src/memory_xt.cc
+++ b/storage/pbxt/src/memory_xt.cc
@@ -558,7 +558,7 @@ static size_t mm_checkmem(XTThreadPtr self, MissingMemoryPtr mm_ptr, void *p, xt
unsigned char *ptr = (unsigned char *) p - MEM_DEBUG_HDR_SIZE;
MemoryDebugPtr debug_ptr = (MemoryDebugPtr) ptr;
size_t size = debug_ptr->size;
- long a_value; /* Added to simplfy debugging. */
+ long a_value __attribute__ ((unused)); /* Added to simplfy debugging. */
if (!ASSERT(p))
return(0);
diff --git a/storage/pbxt/src/myxt_xt.cc b/storage/pbxt/src/myxt_xt.cc
index 410bf2d2f3c..b7b81823383 100644
--- a/storage/pbxt/src/myxt_xt.cc
+++ b/storage/pbxt/src/myxt_xt.cc
@@ -830,7 +830,10 @@ xtPublic xtBool myxt_create_row_from_key(XTOpenTablePtr XT_UNUSED(ot), XTIndexPt
{
byte *record = (byte *) dest_buff;
register byte *key;
- byte *pos,*key_end;
+ byte *pos;
+#ifdef CHECK_KEYS
+ byte *key_end;
+#endif
register XTIndexSegRec *keyseg = ind->mi_seg;
/* GOTCHA: When selecting from multiple
@@ -843,7 +846,9 @@ xtPublic xtBool myxt_create_row_from_key(XTOpenTablePtr XT_UNUSED(ot), XTIndexPt
memset(dest_buff, 0xFF, table->s->null_bytes);
*/
key = (byte *) b_value;
+#ifdef CHECK_KEYS
key_end = key + key_len;
+#endif
for (u_int i=0; i<ind->mi_seg_count; i++, keyseg++) {
if (keyseg->null_bit) {
if (!*key++)
@@ -1021,7 +1026,8 @@ xtPublic u_int myxt_get_key_length(XTIndexPtr ind, xtWord1 *key_buf)
register XTIndexSegRec *keyseg = ind->mi_seg;
register uchar *key_data = (uchar *) key_buf;
uint seg_len;
- uint pack_len;
+ uint pack_len
+ __attribute__ ((unused));
for (u_int i=0; i<ind->mi_seg_count; i++, keyseg++) {
/* Handle NULL part */
@@ -1506,7 +1512,7 @@ xtPublic u_int myxt_key_seg_length(XTIndexSegRec *keyseg, u_int key_offset, xtWo
xtPublic xtWord4 myxt_store_row_length(XTOpenTablePtr ot, char *rec_buff)
{
TABLE *table = ot->ot_table->tab_dic.dic_my_table;
- char *sdata;
+ char *sdata __attribute__ ((unused));
xtWord4 dlen;
xtWord4 item_size;
xtWord4 row_size = 0;
@@ -1886,7 +1892,8 @@ xtPublic void myxt_print_key(XTIndexPtr ind, xtWord1 *key_value)
register XTIndexSegRec *keyseg = ind->mi_seg;
register uchar *b = (uchar *) key_value;
uint b_length;
- uint pack_len;
+ uint pack_len
+ __attribute__ ((unused));
for (u_int i = 0; i < ind->mi_seg_count; i++, keyseg++) {
if (i!=0)
diff --git a/storage/pbxt/src/pthread_xt.cc b/storage/pbxt/src/pthread_xt.cc
index 9f35f50b8c7..d704e977c21 100755
--- a/storage/pbxt/src/pthread_xt.cc
+++ b/storage/pbxt/src/pthread_xt.cc
@@ -506,44 +506,23 @@ xtPublic void xt_p_init_threading(void)
xtPublic int xt_p_set_low_priority(pthread_t thr)
{
- if (pth_min_priority == pth_max_priority) {
- /* Under Linux the priority of normal (non-runtime)
- * threads are set using the standard methods
- * for setting process priority.
- */
-
- /* We could set who == 0 because it should have the same affect
- * as using the PID.
- */
-
- /* -20 = highest, 20 = lowest */
-#ifdef SET_GLOBAL_PRIORITY
- if (setpriority(PRIO_PROCESS, getpid(), 20) == -1)
- return errno;
-#endif
- return 0;
- }
- return pth_set_priority(thr, pth_min_priority);
+ if (pth_min_priority != pth_max_priority)
+ return pth_set_priority(thr, pth_min_priority);
+ return 0;
}
xtPublic int xt_p_set_normal_priority(pthread_t thr)
{
- if (pth_min_priority == pth_max_priority) {
- if (setpriority(PRIO_PROCESS, getpid(), 0) == -1)
- return errno;
- return 0;
- }
- return pth_set_priority(thr, pth_normal_priority);
+ if (pth_min_priority != pth_max_priority)
+ return pth_set_priority(thr, pth_normal_priority);
+ return 0;
}
xtPublic int xt_p_set_high_priority(pthread_t thr)
{
- if (pth_min_priority == pth_max_priority) {
- if (setpriority(PRIO_PROCESS, getpid(), -20) == -1)
- return errno;
- return 0;
- }
- return pth_set_priority(thr, pth_max_priority);
+ if (pth_min_priority != pth_max_priority)
+ return pth_set_priority(thr, pth_max_priority);
+ return 0;
}
#ifdef DEBUG_LOCKING
diff --git a/storage/pbxt/src/restart_xt.cc b/storage/pbxt/src/restart_xt.cc
index 93720f2b113..868c97de020 100644
--- a/storage/pbxt/src/restart_xt.cc
+++ b/storage/pbxt/src/restart_xt.cc
@@ -94,17 +94,21 @@ void xt_print_log_record(xtLogID log, xtLogOffset offset, XTXactLogBufferDPtr re
xtBool xn_set = FALSE;
xtXactID xn_id = 0;
char buffer[200];
+#ifdef TRACE_RECORD_DATA
XTTabRecExtDPtr rec_buf;
- XTTabRecExtDPtr ext_rec;
XTTabRecFixDPtr fix_rec;
u_int rec_len;
+#endif
+ XTTabRecExtDPtr ext_rec;
xtLogID log_id = 0;
xtLogOffset log_offset = 0;
+#ifdef TRACE_RECORD_DATA
rec_buf = NULL;
- ext_rec = NULL;
fix_rec = NULL;
rec_len = 0;
+#endif
+ ext_rec = NULL;
switch (record->xl.xl_status_1) {
case XT_LOG_ENT_REC_MODIFIED:
case XT_LOG_ENT_UPDATE:
@@ -118,10 +122,12 @@ void xt_print_log_record(xtLogID log, xtLogOffset offset, XTXactLogBufferDPtr re
rec_id = XT_GET_DISK_4(record->xu.xu_rec_id_4);
xn_id = XT_GET_DISK_4(record->xu.xu_xact_id_4);
row_id = XT_GET_DISK_4(record->xu.xu_row_id_4);
- rec_len = XT_GET_DISK_2(record->xu.xu_size_2);
xn_set = TRUE;
type="rec";
+#ifdef TRACE_RECORD_DATA
+ rec_len = XT_GET_DISK_2(record->xu.xu_size_2);
rec_buf = (XTTabRecExtDPtr) &record->xu.xu_rec_type_1;
+#endif
ext_rec = (XTTabRecExtDPtr) &record->xu.xu_rec_type_1;
if (XT_REC_IS_EXT_DLOG(ext_rec->tr_rec_type_1)) {
log_id = XT_GET_DISK_2(ext_rec->re_log_id_2);
@@ -129,7 +135,9 @@ void xt_print_log_record(xtLogID log, xtLogOffset offset, XTXactLogBufferDPtr re
}
else {
ext_rec = NULL;
+#ifdef TRACE_RECORD_DATA
fix_rec = (XTTabRecFixDPtr) &record->xu.xu_rec_type_1;
+#endif
}
break;
case XT_LOG_ENT_UPDATE_FL:
@@ -143,10 +151,12 @@ void xt_print_log_record(xtLogID log, xtLogOffset offset, XTXactLogBufferDPtr re
rec_id = XT_GET_DISK_4(record->xf.xf_rec_id_4);
xn_id = XT_GET_DISK_4(record->xf.xf_xact_id_4);
row_id = XT_GET_DISK_4(record->xf.xf_row_id_4);
- rec_len = XT_GET_DISK_2(record->xf.xf_size_2);
xn_set = TRUE;
type="rec";
+#ifdef TRACE_RECORD_DATA
+ rec_len = XT_GET_DISK_2(record->xf.xf_size_2);
rec_buf = (XTTabRecExtDPtr) &record->xf.xf_rec_type_1;
+#endif
ext_rec = (XTTabRecExtDPtr) &record->xf.xf_rec_type_1;
if (XT_REC_IS_EXT_DLOG(ext_rec->tr_rec_type_1)) {
log_id = XT_GET_DISK_2(ext_rec->re_log_id_2);
@@ -154,7 +164,9 @@ void xt_print_log_record(xtLogID log, xtLogOffset offset, XTXactLogBufferDPtr re
}
else {
ext_rec = NULL;
+#ifdef TRACE_RECORD_DATA
fix_rec = (XTTabRecFixDPtr) &record->xf.xf_rec_type_1;
+#endif
}
break;
case XT_LOG_ENT_REC_FREED:
@@ -173,10 +185,12 @@ void xt_print_log_record(xtLogID log, xtLogOffset offset, XTXactLogBufferDPtr re
rec_id = XT_GET_DISK_4(record->rb.rb_rec_id_4);
xn_id = XT_GET_DISK_4(record->rb.rb_xact_id_4);
row_id = XT_GET_DISK_4(record->rb.rb_row_id_4);
- rec_len = XT_GET_DISK_2(record->rb.rb_size_2);
xn_set = TRUE;
type="rec";
+#ifdef TRACE_RECORD_DATA
+ rec_len = XT_GET_DISK_2(record->rb.rb_size_2);
rec_buf = (XTTabRecExtDPtr) &record->rb.rb_rec_type_1;
+#endif
ext_rec = (XTTabRecExtDPtr) &record->rb.rb_rec_type_1;
if (XT_REC_IS_EXT_DLOG(record->rb.rb_rec_type_1)) {
log_id = XT_GET_DISK_2(ext_rec->re_log_id_2);
@@ -184,7 +198,9 @@ void xt_print_log_record(xtLogID log, xtLogOffset offset, XTXactLogBufferDPtr re
}
else {
ext_rec = NULL;
+#ifdef TRACE_RECORD_DATA
fix_rec = (XTTabRecFixDPtr) &record->rb.rb_rec_type_1;
+#endif
}
break;
case XT_LOG_ENT_REC_MOVED:
@@ -967,7 +983,8 @@ static void xres_apply_change(XTThreadPtr self, XTOpenTablePtr ot, XTXactLogBuff
xtLogID data_log_id = 0;
xtLogOffset data_log_offset = 0;
u_int cols_required = 0;
- xtBool record_loaded;
+ xtBool record_loaded
+ __attribute__ ((unused));
size_t rec_size;
rec_id = XT_GET_DISK_4(record->rb.rb_rec_id_4);
diff --git a/storage/pbxt/src/tabcache_xt.cc b/storage/pbxt/src/tabcache_xt.cc
index 92958f2da49..c5374b400c3 100644
--- a/storage/pbxt/src/tabcache_xt.cc
+++ b/storage/pbxt/src/tabcache_xt.cc
@@ -393,7 +393,8 @@ void XTTabCache::xt_tc_release_page(XT_ROW_REC_FILE_PTR XT_UNUSED(file), XTTabCa
TAB_CAC_WRITE_LOCK(&seg->tcs_lock, thread->t_id);
#ifdef DEBUG
- XTTabCachePagePtr lpage, ppage;
+ XTTabCachePagePtr lpage;
+ XTTabCachePagePtr ppage __attribute__ ((unused));
ppage = NULL;
lpage = seg->tcs_hash_table[page->tcp_hash_idx];
@@ -1202,7 +1203,7 @@ static void tabc_fr_main(XTThreadPtr self)
static void *tabc_fr_run_thread(XTThreadPtr self)
{
int count;
- void *mysql_thread;
+ void *mysql_thread __attribute__ ((unused));
myxt_wait_pbxt_plugin_slot_assigned(self);
diff --git a/storage/pbxt/src/table_xt.cc b/storage/pbxt/src/table_xt.cc
index 35b4ea3be3d..df9c157c2b6 100644
--- a/storage/pbxt/src/table_xt.cc
+++ b/storage/pbxt/src/table_xt.cc
@@ -1976,8 +1976,10 @@ xtPublic void xt_check_table(XTThreadPtr self, XTOpenTablePtr ot)
xtLogOffset log_offset;
#endif
xtRecordID rec_id;
+#ifdef DUMP_CHECK_TABLE
xtRecordID prev_rec_id;
xtXactID xn_id;
+#endif
xtRowID row_id;
u_llong free_rec_count = 0, free_count2 = 0;
u_llong delete_rec_count = 0;
@@ -2104,8 +2106,10 @@ xtPublic void xt_check_table(XTThreadPtr self, XTOpenTablePtr ot)
else
printf(" ");
#endif
+#ifdef DUMP_CHECK_TABLE
prev_rec_id = XT_GET_DISK_4(rec_buf->tr_prev_rec_id_4);
xn_id = XT_GET_DISK_4(rec_buf->tr_xact_id_4);
+#endif
row_id = XT_GET_DISK_4(rec_buf->tr_row_id_4);
switch (rec_buf->tr_rec_type_1 & XT_TAB_STATUS_MASK) {
case XT_TAB_STATUS_FREED:
diff --git a/storage/pbxt/src/thread_xt.cc b/storage/pbxt/src/thread_xt.cc
index eb9941f13fb..07f642e34b6 100644
--- a/storage/pbxt/src/thread_xt.cc
+++ b/storage/pbxt/src/thread_xt.cc
@@ -488,7 +488,8 @@ static void thr_free_resources(XTThreadPtr self, XTResourcePtr top)
xtPublic void xt_bug(XTThreadPtr XT_UNUSED(self))
{
- static int *bug_ptr = NULL;
+ static int *bug_ptr __attribute__ ((unused));
+ bug_ptr= NULL;
bug_ptr = NULL;
}
@@ -1178,7 +1179,7 @@ xtPublic XTThreadPtr xt_init_threading(u_int max_threads)
#ifdef XT_TRACK_CONNECTIONS
if (xt_thr_maximum_threads > XT_TRACK_MAX_CONNS) {
xt_log_error(XT_NS_CONTEXT, XT_LOG_FATAL, XT_ERR_TOO_MANY_THREADS, 0,
- "XT_TRACK_CONNECTIONS is enabled and xt_thr_maximum_threads > XT_TRACK_MAX_CONNS");
+ "XT_TRACK_CONNECTIONS (debugging aid) is enabled and xt_thr_maximum_threads > XT_TRACK_MAX_CONNS. To continue restart with a smaller value for --max-connections");
goto failed;
}
#endif
diff --git a/storage/pbxt/src/xactlog_xt.cc b/storage/pbxt/src/xactlog_xt.cc
index addc14ff5d8..69059046067 100644
--- a/storage/pbxt/src/xactlog_xt.cc
+++ b/storage/pbxt/src/xactlog_xt.cc
@@ -2117,7 +2117,7 @@ xtBool XTDatabaseLog::xlog_seq_next(XTXactSeqReadPtr seq, XTXactLogBufferDPtr *r
size_t rec_offset;
size_t max_rec_len;
size_t size;
- u_int check_size = 1;
+ u_int check_size __attribute__ ((unused))= 1;
/* Go to the next record (xseq_record_len must be initialized
* to 0 for this to work.
@@ -2629,7 +2629,7 @@ static void *xlog_wr_run_thread(XTThreadPtr self)
{
XTDatabaseHPtr db = (XTDatabaseHPtr) self->t_data;
int count;
- void *mysql_thread;
+ void *mysql_thread __attribute__ ((unused));
mysql_thread = myxt_create_thread();
diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc
index 6f4f12a318c..0d9f3a381c0 100644
--- a/storage/sphinx/ha_sphinx.cc
+++ b/storage/sphinx/ha_sphinx.cc
@@ -703,7 +703,7 @@ static int sphinx_done_func ( void * )
pthread_mutex_destroy ( &sphinx_mutex );
}
- SPH_RET(0);
+ SPH_RET(error);
}
diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
index 509f7f0fe73..8426804615d 100644
--- a/storage/xtradb/CMakeLists.txt
+++ b/storage/xtradb/CMakeLists.txt
@@ -13,22 +13,14 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-# This is the CMakeLists for InnoDB Plugin
+# This is the CMakeLists for XtraDB
-
-
-# Starting at 5.1.38, MySQL CMake files are simplified. But the plugin
-# CMakeLists.txt still needs to work with previous versions of MySQL.
-IF (MYSQL_VERSION_ID GREATER "50137")
- INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
-ENDIF (MYSQL_VERSION_ID GREATER "50137")
+INCLUDE("${PROJECT_SOURCE_DIR}/storage/mysql_storage_engine.cmake")
IF (CMAKE_SIZEOF_VOID_P MATCHES 8)
SET(WIN64 TRUE)
ENDIF (CMAKE_SIZEOF_VOID_P MATCHES 8)
-ADD_DEFINITIONS(-D_WIN32 -D_LIB -DMYSQL_SERVER)
-
# Include directories under xtradb
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/storage/xtradb/include
${CMAKE_SOURCE_DIR}/storage/xtradb/handler)
@@ -89,9 +81,6 @@ SET(XTRADB_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea.c
usr/usr0sess.c
ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rbt.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c
ut/ut0list.c ut/ut0wqueue.c)
-# Windows atomics do not perform well. Disable Windows atomics by default.
-# See bug#52102 for details.
-#ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DINNODB_RW_LOCKS_USE_ATOMICS -DHAVE_IB_PAUSE_INSTRUCTION)
-ADD_DEFINITIONS(-DHAVE_IB_PAUSE_INSTRUCTION)
+
MYSQL_STORAGE_ENGINE(XTRADB)
diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c
index 9b306ea2864..d16522731c4 100644
--- a/storage/xtradb/btr/btr0cur.c
+++ b/storage/xtradb/btr/btr0cur.c
@@ -3301,7 +3301,7 @@ static
void
btr_record_not_null_field_in_rec(
/*=============================*/
- rec_t* rec, /*!< in: physical record */
+ rec_t* rec __attribute__ ((unused)),/*!< in: physical record */
ulint n_unique, /*!< in: dict_index_get_n_unique(index),
number of columns uniquely determine
an index entry */
@@ -3321,9 +3321,8 @@ btr_record_not_null_field_in_rec(
for (i = 0; i < n_unique; i++) {
ulint rec_len;
- byte* field;
- field = rec_get_nth_field(rec, offsets, i, &rec_len);
+ rec_get_nth_field_offs(offsets, i, &rec_len);
if (rec_len != UNIV_SQL_NULL) {
n_not_null[i]++;
diff --git a/storage/xtradb/buf/buf0buf.c b/storage/xtradb/buf/buf0buf.c
index 5ea8056bed4..8f9c40878f7 100644
--- a/storage/xtradb/buf/buf0buf.c
+++ b/storage/xtradb/buf/buf0buf.c
@@ -3895,7 +3895,7 @@ buf_page_io_complete(
enum buf_io_fix io_type;
const ibool uncompressed = (buf_page_get_state(bpage)
== BUF_BLOCK_FILE_PAGE);
- enum buf_flush flush_type;
+ //enum buf_flush flush_type;
mutex_t* block_mutex;
ut_a(buf_page_in_file(bpage));
@@ -4051,7 +4051,7 @@ corrupt:
//buf_pool_mutex_enter();
if (io_type == BUF_IO_WRITE) {
- flush_type = buf_page_get_flush_type(bpage);
+ //flush_type = buf_page_get_flush_type(bpage);
/* to keep consistency at buf_LRU_insert_zip_clean() */
//if (flush_type == BUF_FLUSH_LRU) { /* optimistic! */
mutex_enter(&LRU_list_mutex);
diff --git a/storage/xtradb/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c
index 18880a5c72c..8d4bd76c32c 100644
--- a/storage/xtradb/dict/dict0dict.c
+++ b/storage/xtradb/dict/dict0dict.c
@@ -472,10 +472,12 @@ Looks for column n in an 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 */
+dict_index_get_nth_col_or_prefix_pos(
+/*=================================*/
+ const dict_index_t* index, /*!< in: index */
+ ulint n, /*!< in: column number */
+ ibool inc_prefix) /*!< in: TRUE=consider
+ column prefixes too */
{
const dict_field_t* field;
const dict_col_t* col;
@@ -497,7 +499,8 @@ dict_index_get_nth_col_pos(
for (pos = 0; pos < n_fields; pos++) {
field = dict_index_get_nth_field(index, pos);
- if (col == field->col && field->prefix_len == 0) {
+ if (col == field->col
+ && (inc_prefix || field->prefix_len == 0)) {
return(pos);
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index c4e6fa0df0d..4eee85db06b 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -56,7 +56,9 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <m_ctype.h>
#include <mysys_err.h>
#include <mysql/plugin.h>
-
+#ifdef _WIN32
+#include <io.h>
+#endif
/** @file ha_innodb.cc */
/* Include necessary InnoDB headers */
@@ -124,11 +126,6 @@ static pthread_cond_t commit_cond;
static pthread_mutex_t commit_cond_m;
static bool innodb_inited = 0;
-C_MODE_START
-static xtradb_icp_result_t index_cond_func_innodb(void *arg);
-C_MODE_END
-
-
#define INSIDE_HA_INNOBASE_CC
@@ -248,7 +245,6 @@ static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
static INNOBASE_SHARE *get_share(const char *table_name);
static void free_share(INNOBASE_SHARE *share);
static int innobase_close_connection(handlerton *hton, THD* thd);
-static void innobase_prepare_ordered(handlerton *hton, THD* thd, bool all);
static void innobase_commit_ordered(handlerton *hton, THD* thd, bool all);
static int innobase_commit(handlerton *hton, THD* thd, bool all);
static int innobase_rollback(handlerton *hton, THD* thd, bool all);
@@ -1240,7 +1236,28 @@ innobase_mysql_tmpfile(void)
will be passed to fdopen(), it will be closed by invoking
fclose(), which in turn will invoke close() instead of
my_close(). */
+#ifdef _WIN32
+ /* Note that on Windows, the integer returned by mysql_tmpfile
+ has no relation to C runtime file descriptor. Here, we need
+ to call my_get_osfhandle to get the HANDLE and then convert it
+ to C runtime filedescriptor. */
+ {
+ HANDLE hFile = my_get_osfhandle(fd);
+ HANDLE hDup;
+ BOOL bOK =
+ DuplicateHandle(GetCurrentProcess(), hFile, GetCurrentProcess(),
+ &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS);
+ if(bOK) {
+ fd2 = _open_osfhandle((intptr_t)hDup,0);
+ }
+ else {
+ my_osmaperr(GetLastError());
+ fd2 = -1;
+ }
+ }
+#else
fd2 = dup(fd);
+#endif
if (fd2 < 0) {
DBUG_PRINT("error",("Got error %d on dup",fd2));
my_errno=errno;
@@ -1986,14 +2003,24 @@ trx_is_strict(
/**************************************************************//**
Resets some fields of a prebuilt struct. The template is used in fast
retrieval of just those column values MySQL needs in its processing. */
-static
void
-reset_template(
-/*===========*/
- row_prebuilt_t* prebuilt) /*!< in/out: prebuilt struct */
+inline
+ha_innobase::reset_template(void)
+/*=============================*/
{
+ ut_ad(prebuilt->magic_n == ROW_PREBUILT_ALLOCATED);
+ ut_ad(prebuilt->magic_n2 == prebuilt->magic_n);
+
prebuilt->keep_other_fields_on_keyread = 0;
prebuilt->read_just_key = 0;
+ /* Reset index condition pushdown state. */
+ if (prebuilt->idx_cond) {
+ prebuilt->idx_cond = NULL;
+ prebuilt->idx_cond_n_cols = 0;
+ /* Invalidate prebuilt->mysql_template
+ in ha_innobase::write_row(). */
+ prebuilt->template_type = ROW_MYSQL_NO_TEMPLATE;
+ }
}
/*****************************************************************//**
@@ -2055,7 +2082,7 @@ ha_innobase::init_table_handle_for_HANDLER(void)
we???? */
prebuilt->used_in_HANDLER = TRUE;
- reset_template(prebuilt);
+ reset_template();
}
/*********************************************************************//**
@@ -2084,10 +2111,6 @@ innobase_init(
innobase_hton->savepoint_set=innobase_savepoint;
innobase_hton->savepoint_rollback=innobase_rollback_to_savepoint;
innobase_hton->savepoint_release=innobase_release_savepoint;
- if (innobase_release_locks_early)
- innobase_hton->prepare_ordered=innobase_prepare_ordered;
- else
- innobase_hton->prepare_ordered=NULL;
innobase_hton->commit_ordered=innobase_commit_ordered;
innobase_hton->commit=innobase_commit;
innobase_hton->rollback=innobase_rollback;
@@ -2801,54 +2824,6 @@ innobase_start_trx_and_assign_read_view(
DBUG_RETURN(0);
}
-/*****************************************************************//**
-Release row locks early during prepare phase.
-
-Only enabled if --innodb-release-locks-early=1. In this case, a prepared
-transaction is treated as committed to memory (but not to disk), and we
-release row locks at the end of the prepare phase.
-
-The consistent commit ordering guarantees of prepare_ordered() calls means
-that transactions will not be binlogged in different order than locks are
-released (which would cause trouble for statement-based replication).
-
-This optimisation is not 100% safe, so is not enabled by default. But some
-applications may decide to enable it to reduce contention on hotspot rows.
-
-The consequences of enabling this are:
-
- - It is not possible to rollback after successful prepare(). If there is
- a need to rollback (ie. failure to binlog the transaction), we crash the
- server (!)
-
- - If we crash during commit, it is possible that an application/user can have
- seen another transaction committed that is not recovered by XA crash
- recovery. Thus durability is partially lost. However, consistency is still
- guaranteed, we never recover a transaction and not recover another
- transaction that committed before. */
-static
-void
-innobase_prepare_ordered(
-/*============*/
- handlerton *hton, /*!< in: Innodb handlerton */
- THD* thd, /*!< in: MySQL thread handle of the user for whom
- the transaction should be committed */
- bool all) /*!< in: TRUE - commit transaction
- FALSE - the current SQL statement ended */
-{
- trx_t* trx;
- DBUG_ENTER("innobase_prepare_ordered");
- DBUG_ASSERT(hton == innodb_hton_ptr);
-
- trx = check_trx_exists(thd);
-
- mutex_enter(&kernel_mutex);
- lock_release_off_kernel(trx);
- mutex_exit(&kernel_mutex);
-
- DBUG_VOID_RETURN;
-}
-
static
void
innobase_commit_ordered_2(
@@ -3088,16 +3063,6 @@ innobase_rollback(
row_unlock_table_autoinc_for_mysql(trx);
- /* if transaction has already released locks, it is too late to
- rollback */
- if (innobase_release_locks_early && trx->conc_state == TRX_PREPARED
- && UT_LIST_GET_LEN(trx->trx_locks) == 0) {
- sql_print_error("Rollback after releasing locks! "
- "errno=%d, dberr="ULINTPF,
- errno, trx->error_state);
- ut_error;
- }
-
if (all
|| !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
@@ -4243,8 +4208,8 @@ static inline
uint
get_field_offset(
/*=============*/
- TABLE* table, /*!< in: MySQL table object */
- Field* field) /*!< in: MySQL field object */
+ const TABLE* table, /*!< in: MySQL table object */
+ const Field* field) /*!< in: MySQL field object */
{
return((uint) (field->ptr - table->record[0]));
}
@@ -4807,44 +4772,170 @@ ha_innobase::store_key_val_for_row(
}
/**************************************************************//**
+Determines if a field is needed in a prebuilt struct 'template'.
+@return field to use, or NULL if the field is not needed */
+static
+const Field*
+build_template_needs_field(
+/*=======================*/
+ ibool index_contains, /*!< in:
+ dict_index_contains_col_or_prefix(
+ index, i) */
+ ibool read_just_key, /*!< in: TRUE when MySQL calls
+ ha_innobase::extra with the
+ argument HA_EXTRA_KEYREAD; it is enough
+ to read just columns defined in
+ the index (i.e., no read of the
+ clustered index record necessary) */
+ ibool fetch_all_in_key,
+ /*!< in: true=fetch all fields in
+ the index */
+ ibool fetch_primary_key_cols,
+ /*!< in: true=fetch the
+ primary key columns */
+ dict_index_t* index, /*!< in: InnoDB index to use */
+ const TABLE* table, /*!< in: MySQL table object */
+ ulint i, /*!< in: field index in InnoDB table */
+ ulint sql_idx) /*!< in: field index in SQL table */
+{
+ const Field* field = table->field[sql_idx];
+
+ ut_ad(index_contains == dict_index_contains_col_or_prefix(index, i));
+
+ if (!index_contains) {
+ if (read_just_key) {
+ /* If this is a 'key read', we do not need
+ columns that are not in the key */
+
+ return(NULL);
+ }
+ } else if (fetch_all_in_key) {
+ /* This field is needed in the query */
+
+ return(field);
+ }
+
+ if (bitmap_is_set(table->read_set, sql_idx)
+ || bitmap_is_set(table->write_set, sql_idx)) {
+ /* This field is needed in the query */
+
+ return(field);
+ }
+
+ if (fetch_primary_key_cols
+ && dict_table_col_in_clustered_key(index->table, i)) {
+ /* This field is needed in the query */
+
+ return(field);
+ }
+
+ /* This field is not needed in the query, skip it */
+
+ return(NULL);
+}
+
+/**************************************************************//**
+Adds a field is to a prebuilt struct 'template'.
+@return the field template */
+static
+mysql_row_templ_t*
+build_template_field(
+/*=================*/
+ row_prebuilt_t* prebuilt, /*!< in/out: template */
+ dict_index_t* clust_index, /*!< in: InnoDB clustered index */
+ dict_index_t* index, /*!< in: InnoDB index to use */
+ TABLE* table, /*!< in: MySQL table object */
+ const Field* field, /*!< in: field in MySQL table */
+ ulint i) /*!< in: field index in InnoDB table */
+{
+ mysql_row_templ_t* templ;
+ const dict_col_t* col;
+
+ ut_ad(field == table->field[i]);
+ ut_ad(clust_index->table == index->table);
+
+ col = dict_table_get_nth_col(index->table, i);
+
+ templ = prebuilt->mysql_template + prebuilt->n_template++;
+ UNIV_MEM_INVALID(templ, sizeof *templ);
+ templ->col_no = i;
+ templ->clust_rec_field_no = dict_col_get_clust_pos(col, clust_index);
+ ut_a(templ->clust_rec_field_no != ULINT_UNDEFINED);
+
+ if (dict_index_is_clust(index)) {
+ templ->rec_field_no = templ->clust_rec_field_no;
+ } else {
+ templ->rec_field_no = dict_index_get_nth_col_pos(index, i);
+ }
+
+ if (field->null_ptr) {
+ templ->mysql_null_byte_offset =
+ (ulint) ((char*) field->null_ptr
+ - (char*) table->record[0]);
+
+ templ->mysql_null_bit_mask = (ulint) field->null_bit;
+ } else {
+ templ->mysql_null_bit_mask = 0;
+ }
+
+ templ->mysql_col_offset = (ulint) get_field_offset(table, field);
+
+ templ->mysql_col_len = (ulint) field->pack_length();
+ templ->type = col->mtype;
+ templ->mysql_type = (ulint)field->type();
+
+ if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
+ templ->mysql_length_bytes = (ulint)
+ (((Field_varstring*)field)->length_bytes);
+ }
+
+ templ->charset = dtype_get_charset_coll(col->prtype);
+ templ->mbminlen = col->mbminlen;
+ templ->mbmaxlen = col->mbmaxlen;
+ templ->is_unsigned = col->prtype & DATA_UNSIGNED;
+
+ if (!dict_index_is_clust(index)
+ && templ->rec_field_no == ULINT_UNDEFINED) {
+ prebuilt->need_to_access_clustered = TRUE;
+ }
+
+ if (prebuilt->mysql_prefix_len < templ->mysql_col_offset
+ + templ->mysql_col_len) {
+ prebuilt->mysql_prefix_len = templ->mysql_col_offset
+ + templ->mysql_col_len;
+ }
+
+ if (templ->type == DATA_BLOB) {
+ prebuilt->templ_contains_blob = TRUE;
+ }
+
+ return(templ);
+}
+
+/**************************************************************//**
Builds a 'template' to the prebuilt struct. The template is used in fast
retrieval of just those column values MySQL needs in its processing. */
-static
+UNIV_INTERN
void
-build_template(
-/*===========*/
- row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct */
- THD* thd, /*!< in: current user thread, used
- only if templ_type is
- ROW_MYSQL_REC_FIELDS */
- TABLE* table, /* in: MySQL table */
- ha_innobase* file, /* in: ha_innobase handler */
- uint templ_type) /* in: ROW_MYSQL_WHOLE_ROW or
- ROW_MYSQL_REC_FIELDS */
+ha_innobase::build_template(
+/*========================*/
+ bool whole_row) /*!< in: true=ROW_MYSQL_WHOLE_ROW,
+ false=ROW_MYSQL_REC_FIELDS */
{
dict_index_t* index;
dict_index_t* clust_index;
- mysql_row_templ_t* templ;
- Field* field;
- ulint n_fields, n_stored_fields;
- ulint n_requested_fields = 0;
+ ulint n_stored_fields;
ibool fetch_all_in_key = FALSE;
ibool fetch_primary_key_cols = FALSE;
- ulint sql_idx, innodb_idx=0;
- /* byte offset of the end of last requested column */
- ulint mysql_prefix_len = 0;
- ibool do_idx_cond_push= FALSE;
- ibool need_second_pass= FALSE;
-
+ ulint i, sql_idx;
+
if (prebuilt->select_lock_type == LOCK_X) {
/* We always retrieve the whole clustered index record if we
use exclusive row level locks, for example, if the read is
done in an UPDATE statement. */
- templ_type = ROW_MYSQL_WHOLE_ROW;
- }
-
- if (templ_type == ROW_MYSQL_REC_FIELDS) {
+ whole_row = true;
+ } else if (!whole_row) {
if (prebuilt->hint_need_to_fetch_extra_cols
== ROW_RETRIEVE_ALL_COLS) {
@@ -4861,7 +4952,7 @@ build_template(
fetch_all_in_key = TRUE;
} else {
- templ_type = ROW_MYSQL_WHOLE_ROW;
+ whole_row = true;
}
} else if (prebuilt->hint_need_to_fetch_extra_cols
== ROW_RETRIEVE_PRIMARY_KEY) {
@@ -4878,21 +4969,13 @@ build_template(
clust_index = dict_table_get_first_index(prebuilt->table);
- if (templ_type == ROW_MYSQL_REC_FIELDS) {
- index = prebuilt->index;
- } else {
- index = clust_index;
- }
+ index = whole_row ? clust_index : prebuilt->index;
- if (index == clust_index) {
- prebuilt->need_to_access_clustered = TRUE;
- } else {
- prebuilt->need_to_access_clustered = FALSE;
- /* Below we check column by column if we need to access
- the clustered index */
- }
+ prebuilt->need_to_access_clustered = (index == clust_index);
+
+ /* Below we check column by column if we need to access
+ the clustered index. */
- n_fields = (ulint)table->s->fields; /* number of columns */
n_stored_fields= (ulint)table->s->stored_fields; /* number of stored columns */
if (!prebuilt->mysql_template) {
@@ -4900,160 +4983,206 @@ build_template(
mem_alloc(n_stored_fields * sizeof(mysql_row_templ_t));
}
- prebuilt->template_type = templ_type;
+ prebuilt->template_type = whole_row
+ ? ROW_MYSQL_WHOLE_ROW : ROW_MYSQL_REC_FIELDS;
prebuilt->null_bitmap_len = table->s->null_bytes;
+ /* Prepare to build prebuilt->mysql_template[]. */
prebuilt->templ_contains_blob = FALSE;
+ prebuilt->mysql_prefix_len = 0;
+ prebuilt->n_template = 0;
+ prebuilt->idx_cond_n_cols = 0;
+
+ /* Note that in InnoDB, i is the column number in the table.
+ MySQL calls columns 'fields'. */
+
+ if (active_index != MAX_KEY && active_index == pushed_idx_cond_keyno) {
+ /* Push down an index condition or an end_range check. */
+ for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
+
+ while (!table->field[sql_idx]->stored_in_db) {
+ sql_idx++;
+ }
+
+ const ibool index_contains
+ = dict_index_contains_col_or_prefix(index, i);
+
+ /* Test if an end_range or an index condition
+ refers to the field. Note that "index" and
+ "index_contains" may refer to the clustered index.
+ Index condition pushdown is relative to prebuilt->index
+ (the index that is being looked up first). */
+
+ /* When join_read_always_key() invokes this
+ code via handler::ha_index_init() and
+ ha_innobase::index_init(), end_range is not
+ yet initialized. Because of that, we must
+ always check for index_contains, instead of
+ the subset
+ field->part_of_key.is_set(active_index)
+ which would be acceptable if end_range==NULL. */
+ if (index == prebuilt->index
+ ? index_contains
+ : dict_index_contains_col_or_prefix(
+ prebuilt->index, i)) {
+ /* Needed in ICP */
+ const Field* field;
+ mysql_row_templ_t* templ;
+
+ if (whole_row) {
+ field = table->field[sql_idx];
+ } else {
+ field = build_template_needs_field(
+ index_contains,
+ prebuilt->read_just_key,
+ fetch_all_in_key,
+ fetch_primary_key_cols,
+ index, table, i, sql_idx);
+ if (!field) {
+ continue;
+ }
+ }
-
- /*
- Setup index condition pushdown (note: we don't need to check if
- this is a scan on primary key as that is checked in idx_cond_push)
- */
- if (file->active_index == file->pushed_idx_cond_keyno &&
- file->active_index != MAX_KEY &&
- templ_type == ROW_MYSQL_REC_FIELDS)
- do_idx_cond_push= need_second_pass= TRUE;
-
- /* Note that in InnoDB, i is the column number. MySQL calls columns
- 'fields'. */
- for (sql_idx = 0; sql_idx < n_fields; sql_idx++) {
- templ = prebuilt->mysql_template + n_requested_fields;
- field = table->field[sql_idx];
- if (!field->stored_in_db)
- goto skip_field;
-
- if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) {
- /* Decide which columns we should fetch
- and which we can skip. */
- register const ibool index_contains_field =
- dict_index_contains_col_or_prefix(index, innodb_idx);
- register const ibool index_covers_field =
- field->part_of_key.is_set(file->active_index);
-
- if (!index_contains_field && prebuilt->read_just_key) {
- /* If this is a 'key read', we do not need
- columns that are not in the key */
-
- goto skip_field;
- }
-
- if (index_contains_field && fetch_all_in_key) {
- /* This field is needed in the query */
-
- goto include_field;
- }
-
- if (bitmap_is_set(table->read_set, sql_idx) ||
- bitmap_is_set(table->write_set, sql_idx)) {
- /* This field is needed in the query */
-
- goto include_field;
- }
+ templ = build_template_field(
+ prebuilt, clust_index, index,
+ table, field, i);
+ prebuilt->idx_cond_n_cols++;
+ ut_ad(prebuilt->idx_cond_n_cols
+ == prebuilt->n_template);
+
+ if (index == prebuilt->index) {
+ templ->icp_rec_field_no
+ = templ->rec_field_no;
+ } else {
+ templ->icp_rec_field_no
+ = dict_index_get_nth_col_pos(
+ prebuilt->index, i);
+ }
- if (fetch_primary_key_cols
- && dict_table_col_in_clustered_key(
- index->table, innodb_idx)) {
- /* This field is needed in the query */
+ if (dict_index_is_clust(prebuilt->index)) {
+ ut_ad(templ->icp_rec_field_no
+ != ULINT_UNDEFINED);
+ /* If the primary key includes
+ a column prefix, use it in
+ index condition pushdown,
+ because the condition is
+ evaluated before fetching any
+ off-page (externally stored)
+ columns. */
+ if (templ->icp_rec_field_no
+ < prebuilt->index->n_uniq) {
+ /* This is a key column;
+ all set. */
+ continue;
+ }
+ } else if (templ->icp_rec_field_no
+ != ULINT_UNDEFINED) {
+ continue;
+ }
- goto include_field;
+ /* This is a column prefix index.
+ The column prefix can be used in
+ an end_range comparison. */
+
+ templ->icp_rec_field_no
+ = dict_index_get_nth_col_or_prefix_pos(
+ prebuilt->index, i, TRUE);
+ ut_ad(templ->icp_rec_field_no
+ != ULINT_UNDEFINED);
+
+ /* Index condition pushdown can be used on
+ all columns of a secondary index, and on
+ the PRIMARY KEY columns. */
+ /* TODO: enable this assertion
+ (but first ensure that end_range is
+ valid here and use an accurate condition
+ for end_range)
+ ut_ad(!dict_index_is_clust(prebuilt->index)
+ || templ->rec_field_no
+ < prebuilt->index->n_uniq);
+ */
}
-
- /* This field is not needed in the query, skip it */
-
- goto skip_field;
-include_field:
- if (do_idx_cond_push &&
- ((need_second_pass && !index_covers_field) ||
- (!need_second_pass && index_covers_field)))
- goto skip_field;
}
- n_requested_fields++;
- templ->col_no = innodb_idx;
- templ->clust_rec_field_no = dict_col_get_clust_pos(
- &index->table->cols[innodb_idx], clust_index);
- ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED);
+ ut_ad(prebuilt->idx_cond_n_cols > 0);
+ ut_ad(prebuilt->idx_cond_n_cols == prebuilt->n_template);
+
+ /* Include the fields that are not needed in index condition
+ pushdown. */
+ for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
+
+ while (!table->field[sql_idx]->stored_in_db) {
+ sql_idx++;
+ }
+
+ const ibool index_contains
+ = dict_index_contains_col_or_prefix(index, i);
+
+ if (index == prebuilt->index
+ ? !index_contains
+ : !dict_index_contains_col_or_prefix(
+ prebuilt->index, i)) {
+ /* Not needed in ICP */
+ const Field* field;
+
+ if (whole_row) {
+ field = table->field[sql_idx];
+ } else {
+ field = build_template_needs_field(
+ index_contains,
+ prebuilt->read_just_key,
+ fetch_all_in_key,
+ fetch_primary_key_cols,
+ index, table, i, sql_idx);
+ if (!field) {
+ continue;
+ }
+ }
- if (index == clust_index) {
- templ->rec_field_no = templ->clust_rec_field_no;
- } else {
- templ->rec_field_no = dict_index_get_nth_col_pos(
- index, innodb_idx);
- if (templ->rec_field_no == ULINT_UNDEFINED) {
- prebuilt->need_to_access_clustered = TRUE;
+ build_template_field(prebuilt,
+ clust_index, index,
+ table, field, i);
}
}
- if (field->null_ptr) {
- templ->mysql_null_byte_offset =
- (ulint) ((char*) field->null_ptr
- - (char*) table->record[0]);
+ prebuilt->idx_cond = this;
+ } else {
+ /* No index condition pushdown */
+ prebuilt->idx_cond = NULL;
- templ->mysql_null_bit_mask = (ulint) field->null_bit;
- } else {
- templ->mysql_null_bit_mask = 0;
- }
+ for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
+ const Field* field;
- templ->mysql_col_offset = (ulint)
- get_field_offset(table, field);
+ while (!table->field[sql_idx]->stored_in_db) {
+ sql_idx++;
+ }
- templ->mysql_col_len = (ulint) field->pack_length();
- if (mysql_prefix_len < templ->mysql_col_offset
- + templ->mysql_col_len) {
- mysql_prefix_len = templ->mysql_col_offset
- + templ->mysql_col_len;
- }
- templ->type = index->table->cols[innodb_idx].mtype;
- templ->mysql_type = (ulint)field->type();
-
- if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
- templ->mysql_length_bytes = (ulint)
- (((Field_varstring*)field)->length_bytes);
- }
+ if (whole_row) {
+ field = table->field[sql_idx];
+ } else {
+ field = build_template_needs_field(
+ dict_index_contains_col_or_prefix(
+ index, i),
+ prebuilt->read_just_key,
+ fetch_all_in_key,
+ fetch_primary_key_cols,
+ index, table, i, sql_idx);
+ if (!field) {
+ continue;
+ }
+ }
- templ->charset = dtype_get_charset_coll(
- index->table->cols[innodb_idx].prtype);
- templ->mbminlen = index->table->cols[innodb_idx].mbminlen;
- templ->mbmaxlen = index->table->cols[innodb_idx].mbmaxlen;
- templ->is_unsigned = index->table->cols[innodb_idx].prtype
- & DATA_UNSIGNED;
- if (templ->type == DATA_BLOB) {
- prebuilt->templ_contains_blob = TRUE;
- }
-skip_field:
- if (need_second_pass && (sql_idx+1 == n_fields))
- {
- prebuilt->n_index_fields= n_requested_fields;
- need_second_pass= FALSE;
- sql_idx= (~(ulint)0); /* to start from 0 */
- innodb_idx= (~(ulint)0); /* to start from 0 */ ///psergey-merge-merge-last-change
+ build_template_field(prebuilt, clust_index, index,
+ table, field, i);
}
- if (field->stored_in_db) {
- innodb_idx++;
- }
- }
-
- prebuilt->n_template = n_requested_fields;
- prebuilt->mysql_prefix_len = mysql_prefix_len;
-
- if (do_idx_cond_push)
- {
- prebuilt->idx_cond_func= index_cond_func_innodb;
- prebuilt->idx_cond_func_arg= file;
- }
- else
- {
- prebuilt->idx_cond_func= NULL;
- prebuilt->n_index_fields= n_requested_fields;
}
if (index != clust_index && prebuilt->need_to_access_clustered) {
/* Change rec_field_no's to correspond to the clustered index
record */
- for (ulint i = do_idx_cond_push? prebuilt->n_index_fields : 0;
- i < n_requested_fields; i++) {
- templ = prebuilt->mysql_template + i;
+ for (i = 0; i < prebuilt->n_template; i++) {
+ mysql_row_templ_t* templ
+ = &prebuilt->mysql_template[i];
templ->rec_field_no = templ->clust_rec_field_no;
}
}
@@ -5316,7 +5445,7 @@ no_commit:
/* Build the template used in converting quickly between
the two database formats */
- build_template(prebuilt, NULL, table, this, ROW_MYSQL_WHOLE_ROW);
+ build_template(true);
}
innodb_srv_conc_enter_innodb(prebuilt->trx);
@@ -6017,8 +6146,7 @@ ha_innobase::index_read(
necessarily prebuilt->index, but can also be the clustered index */
if (prebuilt->sql_stat_start) {
- build_template(prebuilt, user_thd, table, this,
- ROW_MYSQL_REC_FIELDS);
+ build_template(false);
}
if (key_ptr) {
@@ -6233,7 +6361,7 @@ ha_innobase::change_active_index(
the flag ROW_MYSQL_WHOLE_ROW below, but that caused unnecessary
copying. Starting from MySQL-4.1 we use a more efficient flag here. */
- build_template(prebuilt, user_thd, table, this, ROW_MYSQL_REC_FIELDS);
+ build_template(false);
DBUG_RETURN(0);
}
@@ -8628,7 +8756,7 @@ ha_innobase::check(
/* Build the template; we will use a dummy template
in index scans done in checking */
- build_template(prebuilt, NULL, table, this, ROW_MYSQL_WHOLE_ROW);
+ build_template(true);
}
if (prebuilt->table->ibd_file_missing) {
@@ -9120,12 +9248,7 @@ ha_innobase::extra(
}
break;
case HA_EXTRA_RESET_STATE:
- reset_template(prebuilt);
- /* Reset index condition pushdown state */
- pushed_idx_cond= FALSE;
- pushed_idx_cond_keyno= MAX_KEY;
- prebuilt->idx_cond_func= NULL;
- in_range_check_pushed_down= FALSE;
+ reset_template();
break;
case HA_EXTRA_NO_KEYREAD:
prebuilt->read_just_key = 0;
@@ -9171,14 +9294,8 @@ ha_innobase::reset()
row_mysql_prebuilt_free_blob_heap(prebuilt);
}
- reset_template(prebuilt);
-
- /* Reset index condition pushdown state */
- pushed_idx_cond_keyno= MAX_KEY;
- pushed_idx_cond= NULL;
- in_range_check_pushed_down= FALSE;
+ reset_template();
ds_mrr.dsmrr_close();
- prebuilt->idx_cond_func= NULL;
/* TODO: This should really be reset in reset_template() but for now
it's safer to do it explicitly here. */
@@ -9228,7 +9345,7 @@ ha_innobase::start_stmt(
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
- reset_template(prebuilt);
+ reset_template();
if (!prebuilt->mysql_has_locked) {
/* This handle is for a temporary table created inside
@@ -9347,7 +9464,7 @@ ha_innobase::external_lock(
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
- reset_template(prebuilt);
+ reset_template();
if (lock_type == F_WRLCK) {
@@ -9530,7 +9647,7 @@ ha_innobase::transactional_table_lock(
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
- reset_template(prebuilt);
+ reset_template();
if (lock_type == F_WRLCK) {
prebuilt->select_lock_type = LOCK_X;
@@ -11968,11 +12085,6 @@ static MYSQL_SYSVAR_ULINT(pass_corrupt_table, srv_pass_corrupt_table,
"except for the deletion.",
NULL, NULL, 0, 0, 1, 0);
-static MYSQL_SYSVAR_BOOL(release_locks_early, innobase_release_locks_early,
- PLUGIN_VAR_READONLY,
- "Release row locks in the prepare stage instead of in the commit stage",
- NULL, NULL, FALSE);
-
static MYSQL_SYSVAR_ULINT(lazy_drop_table, srv_lazy_drop_table,
PLUGIN_VAR_RQCMDARG,
"At deleting tablespace, only miminum needed processes at the time are done. "
@@ -12070,7 +12182,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(auto_lru_dump),
MYSQL_SYSVAR(use_purge_thread),
MYSQL_SYSVAR(pass_corrupt_table),
- MYSQL_SYSVAR(release_locks_early),
MYSQL_SYSVAR(lazy_drop_table),
NULL
};
@@ -12352,39 +12463,47 @@ bool ha_innobase::is_thd_killed()
* Index Condition Pushdown interface implementation
*/
-C_MODE_START
-
-/*
- Index condition check function to be called from within Innobase.
- See note on ICP_RESULT for return values description.
-*/
-
-static xtradb_icp_result_t index_cond_func_innodb(void *arg)
+/*************************************************************//**
+InnoDB index push-down condition check
+@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */
+extern "C" UNIV_INTERN
+enum icp_result
+innobase_index_cond(
+/*================*/
+ void* file) /*!< in/out: pointer to ha_innobase */
{
- ha_innobase *h= (ha_innobase*)arg;
+ ha_innobase *h= (ha_innobase*) file;
+
if (h->is_thd_killed())
- return XTRADB_ICP_ABORTED_BY_USER;
+ return ICP_ABORTED_BY_USER;
if (h->end_range)
{
if (h->compare_key2(h->end_range) > 0)
- return XTRADB_ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */
+ return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */
}
- return h->pushed_idx_cond->val_int()? XTRADB_ICP_MATCH : XTRADB_ICP_NO_MATCH;
+ return h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH;
}
-C_MODE_END
-
-
-Item *ha_innobase::idx_cond_push(uint keyno_arg, Item* idx_cond_arg)
-{
- if (keyno_arg != primary_key && prebuilt->select_lock_type != LOCK_X)
- {
- pushed_idx_cond_keyno= keyno_arg;
- pushed_idx_cond= idx_cond_arg;
- in_range_check_pushed_down= TRUE;
- return NULL; /* Table handler will check the entire condition */
- }
- return idx_cond_arg; /* Table handler will not make any checks */
+/** Attempt to push down an index condition.
+* @param[in] keyno MySQL key number
+* @param[in] idx_cond Index condition to be checked
+* @return idx_cond if pushed; NULL if not pushed
+*/
+UNIV_INTERN
+class Item*
+ha_innobase::idx_cond_push(
+ uint keyno,
+ class Item* idx_cond)
+{
+ DBUG_ENTER("ha_innobase::idx_cond_push");
+ DBUG_ASSERT(keyno != MAX_KEY);
+ DBUG_ASSERT(idx_cond != NULL);
+
+ pushed_idx_cond = idx_cond;
+ pushed_idx_cond_keyno = keyno;
+ in_range_check_pushed_down = TRUE;
+ /* Table handler will check the entire condition */
+ DBUG_RETURN(NULL);
}
diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h
index 599b48287e3..7b263db2537 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -223,27 +223,81 @@ class ha_innobase: public handler
bool check_if_incompatible_data(HA_CREATE_INFO *info,
uint table_changes);
bool check_if_supported_virtual_columns(void) { return TRUE; }
+private:
+ /** Builds a 'template' to the prebuilt struct.
+
+ The template is used in fast retrieval of just those column
+ values MySQL needs in its processing.
+ @param whole_row true if access is needed to a whole row,
+ false if accessing individual fields is enough */
+ void build_template(bool whole_row);
+ /** Resets a query execution 'template'.
+ @see build_template() */
+ inline void reset_template();
+
public:
- /**
- * Multi Range Read interface
- */
- int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
- uint n_ranges, uint mode, HANDLER_BUFFER *buf);
- int multi_range_read_next(range_id_t *range_info);
- ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
- void *seq_init_param,
- uint n_ranges, uint *bufsz,
+ /** @name Multi Range Read interface @{ */
+ /** Initialize multi range read @see DsMrr_impl::dsmrr_init
+ * @param seq
+ * @param seq_init_param
+ * @param n_ranges
+ * @param mode
+ * @param buf
+ */
+ int multi_range_read_init(RANGE_SEQ_IF* seq,
+ void* seq_init_param,
+ uint n_ranges, uint mode,
+ HANDLER_BUFFER *buf);
+ /** Process next multi range read @see DsMrr_impl::dsmrr_next
+ * @param range_info
+ */
+ int multi_range_read_next(range_id_t *range_info);
+ /** Initialize multi range read and get information.
+ * @see ha_myisam::multi_range_read_info_const
+ * @see DsMrr_impl::dsmrr_info_const
+ * @param keyno
+ * @param seq
+ * @param seq_init_param
+ * @param n_ranges
+ * @param bufsz
+ * @param flags
+ * @param cost
+ */
+ ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
+ void *seq_init_param,
+ uint n_ranges, uint *bufsz,
+ uint *flags, COST_VECT *cost);
+ /** Initialize multi range read and get information.
+ * @see DsMrr_impl::dsmrr_info
+ * @param keyno
+ * @param n_ranges
+ * @param keys
+ * @param key_parts
+ * @param bufsz
+ * @param flags
+ * @param cost
+ */
+ ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
+ uint key_parts, uint *bufsz,
uint *flags, COST_VECT *cost);
- ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
- uint key_parts, uint *bufsz,
- uint *flags, COST_VECT *cost);
- int multi_range_read_explain_info(uint mrr_mode, char *str, size_t size);
- DsMrr_impl ds_mrr;
+ int multi_range_read_explain_info(uint mrr_mode,
+ char *str, size_t size);
+
+ /** Attempt to push down an index condition.
+ * @param[in] keyno MySQL key number
+ * @param[in] idx_cond Index condition to be checked
+ * @return idx_cond if pushed; NULL if not pushed
+ */
+ class Item* idx_cond_push(uint keyno, class Item* idx_cond);
+
+ /* An helper function for index_cond_func_innodb: */
+ bool is_thd_killed();
- Item *idx_cond_push(uint keyno, Item* idx_cond);
+private:
+ /** The multi range read session object */
+ DsMrr_impl ds_mrr;
- /* An helper function for index_cond_func_innodb: */
- bool is_thd_killed();
+ /* @} */
};
/* Some accessor functions which the InnoDB plugin needs, but which
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h
index 2baecdc958a..9c5925c1301 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -832,13 +832,25 @@ 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_INTERN
+UNIV_INLINE
ulint
dict_index_get_nth_col_pos(
/*=======================*/
const dict_index_t* index, /*!< in: index */
ulint n); /*!< in: column number */
/********************************************************************//**
+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_or_prefix_pos(
+/*=================================*/
+ const dict_index_t* index, /*!< in: index */
+ ulint n, /*!< in: column number */
+ ibool inc_prefix); /*!< in: TRUE=consider
+ column prefixes too */
+/********************************************************************//**
Returns TRUE if the index contains a column or a prefix of that column.
@return TRUE if contains the column or its prefix */
UNIV_INTERN
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic
index bd7534dc7e2..02527d8edd2 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -656,6 +656,20 @@ 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/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index 445d94eeabb..db71c37afc3 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -247,6 +247,15 @@ innobase_get_at_most_n_mbchars(
ulint data_len, /*!< in: length of the string in bytes */
const char* str); /*!< in: character string */
+/*************************************************************//**
+InnoDB index push-down condition check
+@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */
+UNIV_INTERN
+enum icp_result
+innobase_index_cond(
+/*================*/
+ void* file) /*!< in/out: pointer to ha_innobase */
+ __attribute__((nonnull, warn_unused_result));
/******************************************************************//**
Returns true if the thread supports XA,
global value of innodb_supports_xa if thd is NULL.
diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h
index 732e930517b..46bda4c6b45 100644
--- a/storage/xtradb/include/os0file.h
+++ b/storage/xtradb/include/os0file.h
@@ -152,8 +152,8 @@ log. */
#define OS_FILE_LOG 256 /* This can be ORed to type */
/* @} */
-#define OS_AIO_N_PENDING_IOS_PER_THREAD 32 /*!< Win NT does not allow more
- than 64 */
+#define OS_AIO_N_PENDING_IOS_PER_THREAD 256 /*!< Windows might be able to handle
+more */
/** Modes for aio operations @{ */
#define OS_AIO_NORMAL 21 /*!< Normal asynchronous i/o not for ibuf
@@ -183,6 +183,10 @@ log. */
#define OS_WIN95 2 /*!< Microsoft Windows 95 */
#define OS_WINNT 3 /*!< Microsoft Windows NT 3.x */
#define OS_WIN2000 4 /*!< Microsoft Windows 2000 */
+#define OS_WINXP 5 /*!< Microsoft Windows XP */
+#define OS_WINVISTA 6 /*!< Microsoft Windows Vista */
+#define OS_WIN7 7 /*!< Microsoft Windows 7 */
+
extern ulint os_n_file_reads;
extern ulint os_n_file_writes;
diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h
index 7366e2c3402..002abebcb0b 100644
--- a/storage/xtradb/include/os0sync.h
+++ b/storage/xtradb/include/os0sync.h
@@ -37,29 +37,19 @@ Created 9/6/1995 Heikki Tuuri
#include "univ.i"
#include "ut0lst.h"
-#ifdef __WIN__
-
+#ifdef _WIN32
+/** Native event (slow)*/
+typedef HANDLE os_native_event_t;
/** Native mutex */
-#define os_fast_mutex_t CRITICAL_SECTION
-
-/** Native event */
-typedef HANDLE os_native_event_t;
-
-/** Operating system event */
-typedef struct os_event_struct os_event_struct_t;
-/** Operating system event handle */
-typedef os_event_struct_t* os_event_t;
-
-/** An asynchronous signal sent between threads */
-struct os_event_struct {
- os_native_event_t handle;
- /*!< Windows event */
- UT_LIST_NODE_T(os_event_struct_t) os_event_list;
- /*!< list of all created events */
-};
+typedef CRITICAL_SECTION os_fast_mutex_t;
+/** Native condition variable */
+typedef CONDITION_VARIABLE os_cond_t;
#else
/** Native mutex */
typedef pthread_mutex_t os_fast_mutex_t;
+/** Native condition variable */
+typedef pthread_cond_t os_cond_t;
+#endif
/** Operating system event */
typedef struct os_event_struct os_event_struct_t;
@@ -68,6 +58,9 @@ typedef os_event_struct_t* os_event_t;
/** An asynchronous signal sent between threads */
struct os_event_struct {
+#ifdef _WIN32
+ HANDLE handle; /*!< kernel event object, slow, used on older Windows */
+#endif
os_fast_mutex_t os_mutex; /*!< this mutex protects the next
fields */
ibool is_set; /*!< this is TRUE when the event is
@@ -76,12 +69,14 @@ struct os_event_struct {
this event */
ib_int64_t signal_count; /*!< this is incremented each time
the event becomes signaled */
- pthread_cond_t cond_var; /*!< condition variable is used in
+ os_cond_t cond_var; /*!< condition variable is used in
waiting for the event */
UT_LIST_NODE_T(os_event_struct_t) os_event_list;
/*!< list of all created events */
};
-#endif
+
+
+
/** Operating system mutex */
typedef struct os_mutex_struct os_mutex_str_t;
@@ -186,33 +181,23 @@ os_event_wait_low(
os_event_reset(). */
#define os_event_wait(event) os_event_wait_low(event, 0)
-
+#define os_event_wait_time(event, t) os_event_wait_time_low(event, t, 0)
/**********************************************************//**
Waits for an event object until it is in the signaled state or
-a timeout is exceeded.
+a timeout is exceeded. In Unix the timeout is always infinite.
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
UNIV_INTERN
ulint
-os_event_wait_time(
-/*===============*/
- os_event_t event, /*!< in: event to wait */
- ulint wtime); /*!< in: timeout in microseconds, or
- OS_SYNC_INFINITE_TIME */
-#ifdef __WIN__
-/**********************************************************//**
-Waits for any event in an OS native event array. Returns if even a single
-one is signaled or becomes signaled.
-@return index of the event which was signaled */
-UNIV_INTERN
-ulint
-os_event_wait_multiple(
+os_event_wait_time_low(
/*===================*/
- ulint n, /*!< in: number of events in the
- array */
- os_native_event_t* native_event_array);
- /*!< in: pointer to an array of event
- handles */
-#endif
+ os_event_t event, /*!< in: event to wait */
+ ulint time_in_usec, /*!< in: timeout in
+ microseconds, or
+ OS_SYNC_INFINITE_TIME */
+ ib_int64_t reset_sig_count); /*!< in: zero or the value
+ returned by previous call of
+ os_event_reset(). */
+
/*********************************************************//**
Creates an operating system mutex semaphore. Because these are slow, the
mutex semaphore of InnoDB itself (mutex_t) should be used where possible.
@@ -385,7 +370,7 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
# define os_atomic_test_and_set_byte(ptr, new_val) \
atomic_swap_uchar(ptr, new_val)
-#elif defined(HAVE_WINDOWS_ATOMICS)
+#elif defined(_WIN32)
#define HAVE_ATOMIC_BUILTINS
diff --git a/storage/xtradb/include/os0sync.ic b/storage/xtradb/include/os0sync.ic
index 1f3ce38fa65..2c6c1dbe629 100644
--- a/storage/xtradb/include/os0sync.ic
+++ b/storage/xtradb/include/os0sync.ic
@@ -28,8 +28,7 @@ Created 9/6/1995 Heikki Tuuri
#endif
/**********************************************************//**
-Acquires ownership of a fast mutex. Currently in Windows this is the same
-as os_fast_mutex_lock!
+Acquires ownership of a fast mutex.
@return 0 if success, != 0 if was reserved by another thread */
UNIV_INLINE
ulint
@@ -38,9 +37,9 @@ os_fast_mutex_trylock(
os_fast_mutex_t* fast_mutex) /*!< in: mutex to acquire */
{
#ifdef __WIN__
- EnterCriticalSection(fast_mutex);
-
- return(0);
+ if (TryEnterCriticalSection(fast_mutex))
+ return 0;
+ return(1);
#else
/* NOTE that the MySQL my_pthread.h redefines pthread_mutex_trylock
so that it returns 0 on success. In the operating system
diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h
index cd9dec2f089..b18e1fca5dc 100644
--- a/storage/xtradb/include/row0mysql.h
+++ b/storage/xtradb/include/row0mysql.h
@@ -547,6 +547,10 @@ struct mysql_row_templ_struct {
Innobase record in the clustered index;
not defined if template_type is
ROW_MYSQL_WHOLE_ROW */
+ ulint icp_rec_field_no; /*!< field number of the column in an
+ Innobase record in the current index;
+ not defined unless
+ index condition pushdown is used */
ulint mysql_col_offset; /*!< offset of the column in the MySQL
row format */
ulint mysql_col_len; /*!< length of the column in the MySQL
@@ -585,16 +589,6 @@ struct mysql_row_templ_struct {
#define ROW_PREBUILT_ALLOCATED 78540783
#define ROW_PREBUILT_FREED 26423527
-
-typedef enum xtradb_icp_result {
- XTRADB_ICP_ERROR=-1,
- XTRADB_ICP_NO_MATCH=0,
- XTRADB_ICP_MATCH=1,
- XTRADB_ICP_OUT_OF_RANGE=2,
- XTRADB_ICP_ABORTED_BY_USER=3,
-} xtradb_icp_result_t;
-
-typedef xtradb_icp_result_t (*index_cond_func_t)(void *param);
/** A struct for (sometimes lazily) prebuilt structures in an Innobase table
handle used within MySQL; these are used to save CPU time. */
@@ -792,16 +786,15 @@ struct row_prebuilt_struct {
store it here so that we can return
it to MySQL */
/*----------------------*/
+ void* idx_cond; /*!< In ICP, pointer to a ha_innobase,
+ passed to innobase_index_cond().
+ NULL if index condition pushdown is
+ not used. */
+ ulint idx_cond_n_cols;/*!< Number of fields in idx_cond_cols.
+ 0 if and only if idx_cond == NULL. */
+ /*----------------------*/
ulint magic_n2; /*!< this should be the same as
magic_n */
- /*----------------------*/
- index_cond_func_t idx_cond_func;/* Index Condition Pushdown function,
- or NULL if there is none set */
- void* idx_cond_func_arg;/* ICP function argument */
- ulint n_index_fields; /* Number of fields at the start of
- mysql_template. Valid only when using
- ICP. */
- /*----------------------*/
};
#define ROW_PREBUILT_FETCH_MAGIC_N 465765687
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 8bcf215c7ac..29d88331532 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -112,7 +112,9 @@ extern ulint srv_check_file_format_at_startup;
on duplicate key checking and foreign key checking */
extern ibool srv_locks_unsafe_for_binlog;
#endif /* !UNIV_HOTBACKUP */
-
+#ifdef __WIN__
+extern ibool srv_use_native_conditions;
+#endif
extern ulint srv_n_data_files;
extern char** srv_data_file_names;
extern ulint* srv_data_file_sizes;
@@ -351,9 +353,6 @@ extern ulint srv_buf_pool_reads;
/** Time in seconds between automatic buffer pool dumps */
extern uint srv_auto_lru_dump;
-/** Release row locks already in the prepare phase */
-extern my_bool innobase_release_locks_early;
-
/** Status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
diff --git a/storage/xtradb/include/sync0sync.h b/storage/xtradb/include/sync0sync.h
index f2ff83101ab..6aaab1cc7d7 100644
--- a/storage/xtradb/include/sync0sync.h
+++ b/storage/xtradb/include/sync0sync.h
@@ -45,7 +45,7 @@ Created 9/5/1995 Heikki Tuuri
extern my_bool timed_mutexes;
#endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */
-#ifdef HAVE_WINDOWS_ATOMICS
+#ifdef _WIN32
typedef LONG lock_word_t; /*!< On Windows, InterlockedExchange operates
on LONG variable */
#else
diff --git a/storage/xtradb/include/trx0sys.ic b/storage/xtradb/include/trx0sys.ic
index f39ba3055be..5e0f07c8b9d 100644
--- a/storage/xtradb/include/trx0sys.ic
+++ b/storage/xtradb/include/trx0sys.ic
@@ -338,12 +338,6 @@ trx_list_get_min_trx_id(void)
/****************************************************************//**
Checks if a transaction with the given id is active.
-IMPORTANT ASSUMPTION:
- It is assumed that this function is only used for the purpose of
- determining if locks need to be created for the input transaction.
- So if innobase_release_locks_early global option is set, and if
- the transaction is already in prepared state, this returns FALSE,
- as locks are no longer needed for the transaction.
@return TRUE if active */
UNIV_INLINE
ibool
@@ -372,8 +366,7 @@ trx_is_active(
trx = trx_get_on_id(trx_id);
if (trx && (trx->conc_state == TRX_ACTIVE
- || (trx->conc_state == TRX_PREPARED &&
- !innobase_release_locks_early))) {
+ || trx->conc_state == TRX_PREPARED)) {
return(TRUE);
}
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index 5b8e656d8b2..ee164bd6317 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -53,6 +53,10 @@ Created 10/21/1995 Heikki Tuuri
# endif /* __WIN__ */
#endif /* !UNIV_HOTBACKUP */
+#ifdef _WIN32
+#define IOCP_SHUTDOWN_KEY (ULONG_PTR)-1
+#endif
+
/* This specifies the file permissions InnoDB uses when it creates files in
Unix; the value of os_innodb_umask is initialized in ha_innodb.cc to
my_umask */
@@ -121,6 +125,12 @@ typedef struct os_aio_slot_struct os_aio_slot_t;
/** The asynchronous i/o array slot structure */
struct os_aio_slot_struct{
+#ifdef WIN_ASYNC_IO
+ OVERLAPPED control; /*!< Windows control block for the
+ aio request, MUST be first element in the structure*/
+ void *arr; /*!< Array this slot belongs to*/
+#endif
+
ibool is_read; /*!< TRUE if a read operation */
ulint pos; /*!< index of the slot in the aio
array */
@@ -148,12 +158,6 @@ struct os_aio_slot_struct{
and which can be used to identify
which pending aio operation was
completed */
-#ifdef WIN_ASYNC_IO
- os_event_t event; /*!< event object we need in the
- OVERLAPPED struct */
- OVERLAPPED control; /*!< Windows control block for the
- aio request */
-#endif
};
/** The asynchronous i/o array structure */
@@ -182,15 +186,6 @@ struct os_aio_array_struct{
/*!< Number of reserved slots in the
aio array outside the ibuf segment */
os_aio_slot_t* slots; /*!< Pointer to the slots in the array */
-#ifdef __WIN__
- os_native_event_t* native_events;
- /*!< Pointer to an array of OS native
- event handles where we copied the
- handles from slots, in the same
- order. This can be used in
- WaitForMultipleObjects; used only in
- Windows */
-#endif
};
/** Array of events used in simulated aio */
@@ -250,6 +245,14 @@ UNIV_INTERN ulint os_n_pending_writes = 0;
/** Number of pending read operations */
UNIV_INTERN ulint os_n_pending_reads = 0;
+
+#ifdef _WIN32
+/** IO completion port used by background io threads */
+static HANDLE completion_port;
+/** Thread local storage index for the per-thread event used for synchronous IO */
+static DWORD tls_sync_io = TLS_OUT_OF_INDEXES;
+#endif
+
/***********************************************************************//**
Gets the operating system version. Currently works only on Windows.
@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000 */
@@ -270,10 +273,16 @@ os_get_os_version(void)
} else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
return(OS_WIN95);
} else if (os_info.dwPlatformId == VER_PLATFORM_WIN32_NT) {
- if (os_info.dwMajorVersion <= 4) {
- return(OS_WINNT);
- } else {
- return(OS_WIN2000);
+ switch(os_info.dwMajorVersion){
+ case 3:
+ case 4:
+ return OS_WINNT;
+ case 5:
+ return (os_info.dwMinorVersion == 0)?OS_WIN2000 : OS_WINXP;
+ case 6:
+ return (os_info.dwMinorVersion == 0)?OS_WINVISTA : OS_WIN7;
+ default:
+ return OS_WIN7;
}
} else {
ut_error;
@@ -286,6 +295,86 @@ os_get_os_version(void)
#endif
}
+
+#ifdef _WIN32
+/*
+Windows : Handling synchronous IO on files opened asynchronously.
+
+If file is opened for asynchronous IO (FILE_FLAG_OVERLAPPED) and also bound to
+a completion port, then every IO on this file would normally be enqueued to the
+completion port. Sometimes however we would like to do a synchronous IO. This is
+possible if we initialitze have overlapped.hEvent with a valid event and set its
+lowest order bit to 1 (see MSDN ReadFile and WriteFile description for more info)
+
+We'll create this special event once for each thread and store in thread local
+storage.
+*/
+
+
+/***********************************************************************//**
+Initialize tls index.for event handle used for synchronized IO on files that
+might be opened with FILE_FLAG_OVERLAPPED.
+*/
+static void win_init_syncio_event()
+{
+ tls_sync_io = TlsAlloc();
+ ut_a(tls_sync_io != TLS_OUT_OF_INDEXES);
+}
+
+/***********************************************************************//**
+Retrieve per-thread event for doing synchronous io on asyncronously opened files
+*/
+static HANDLE win_get_syncio_event()
+{
+ HANDLE h;
+ if(tls_sync_io == TLS_OUT_OF_INDEXES){
+ win_init_syncio_event();
+ }
+
+ h = (HANDLE)TlsGetValue(tls_sync_io);
+ if (h)
+ return h;
+ h = CreateEventA(NULL, FALSE, FALSE, NULL);
+ ut_a(h);
+ h = (HANDLE)((uintptr_t)h | 1);
+ TlsSetValue(tls_sync_io, h);
+ return h;
+}
+
+/*
+ TLS destructor, inspired by Chromium code
+ http://src.chromium.org/svn/trunk/src/base/threading/thread_local_storage_win.cc
+*/
+
+static void win_free_syncio_event()
+{
+ HANDLE h = win_get_syncio_event();
+ if (h) {
+ CloseHandle(h);
+ }
+}
+
+static void NTAPI win_tls_thread_exit(PVOID module, DWORD reason, PVOID reserved) {
+ if (DLL_THREAD_DETACH == reason || DLL_PROCESS_DETACH == reason)
+ win_free_syncio_event();
+}
+
+#ifdef _WIN64
+#pragma comment(linker, "/INCLUDE:_tls_used")
+#pragma comment(linker, "/INCLUDE:p_thread_callback_base")
+#pragma const_seg(".CRT$XLB")
+extern const PIMAGE_TLS_CALLBACK p_thread_callback_base;
+const PIMAGE_TLS_CALLBACK p_thread_callback_base = win_tls_thread_exit;
+#pragma data_seg()
+#else
+#pragma comment(linker, "/INCLUDE:__tls_used")
+#pragma comment(linker, "/INCLUDE:_p_thread_callback_base")
+#pragma data_seg(".CRT$XLB")
+PIMAGE_TLS_CALLBACK p_thread_callback_base = win_tls_thread_exit;
+#pragma data_seg()
+#endif
+#endif /*_WIN32 */
+
/***********************************************************************//**
Retrieves the last error number if an error occurs in a file io function.
The number should be retrieved before any other OS calls (because they may
@@ -611,6 +700,9 @@ os_io_init_simple(void)
for (i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) {
os_file_seek_mutexes[i] = os_mutex_create(NULL);
}
+#ifdef _WIN32
+ win_init_syncio_event();
+#endif
}
/***********************************************************************//**
@@ -1358,6 +1450,16 @@ try_again:
ut_error;
}
+ if (type == OS_LOG_FILE) {
+ if (srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) {
+ /* Map O_DSYNC to WRITE_THROUGH */
+ attributes |= FILE_FLAG_WRITE_THROUGH;
+ } else if (srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT) {
+ /* Open log file without buffering */
+ attributes |= FILE_FLAG_NO_BUFFERING;
+ }
+ }
+
file = CreateFile((LPCTSTR) name,
GENERIC_READ | GENERIC_WRITE, /* read and write
access */
@@ -1402,6 +1504,9 @@ try_again:
}
} else {
*success = TRUE;
+ if (os_aio_use_native_aio && ((attributes & FILE_FLAG_OVERLAPPED) != 0)) {
+ ut_a(CreateIoCompletionPort(file, completion_port, 0, 0));
+ }
}
return(file);
@@ -2350,13 +2455,9 @@ _os_file_read(
#ifdef __WIN__
BOOL ret;
DWORD len;
- DWORD ret2;
- DWORD low;
- DWORD high;
ibool retry;
-#ifndef UNIV_HOTBACKUP
- ulint i;
-#endif /* !UNIV_HOTBACKUP */
+ OVERLAPPED overlapped;
+
/* On 64-bit Windows, ulint is 64 bits. But offset and n should be
no more than 32 bits. */
@@ -2371,41 +2472,21 @@ try_again:
ut_ad(buf);
ut_ad(n > 0);
- low = (DWORD) offset;
- high = (DWORD) offset_high;
-
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
-#ifndef UNIV_HOTBACKUP
- /* Protect the seek / read operation with a mutex */
- i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
- os_mutex_enter(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
- ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
-
- if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
-
-#ifndef UNIV_HOTBACKUP
- os_mutex_exit(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
-
- goto error_handling;
+ memset (&overlapped, 0, sizeof (overlapped));
+ overlapped.Offset = (DWORD)offset;
+ overlapped.OffsetHigh = (DWORD)offset_high;
+ overlapped.hEvent = win_get_syncio_event();
+ ret = ReadFile(file, buf, n, NULL, &overlapped);
+ if (ret) {
+ ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, FALSE);
}
-
- ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
-
-#ifndef UNIV_HOTBACKUP
- os_mutex_exit(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
+ else if(GetLastError() == ERROR_IO_PENDING) {
+ ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE);
+ }
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
@@ -2433,9 +2514,6 @@ try_again:
(ulong)n, (ulong)offset_high,
(ulong)offset, (long)ret);
#endif /* __WIN__ */
-#ifdef __WIN__
-error_handling:
-#endif
retry = os_file_handle_error(NULL, "read");
if (retry) {
@@ -2477,13 +2555,11 @@ os_file_read_no_error_handling(
#ifdef __WIN__
BOOL ret;
DWORD len;
- DWORD ret2;
- DWORD low;
- DWORD high;
ibool retry;
-#ifndef UNIV_HOTBACKUP
- ulint i;
-#endif /* !UNIV_HOTBACKUP */
+ OVERLAPPED overlapped;
+ overlapped.Offset = (DWORD)offset;
+ overlapped.OffsetHigh = (DWORD)offset_high;
+
/* On 64-bit Windows, ulint is 64 bits. But offset and n should be
no more than 32 bits. */
@@ -2498,41 +2574,21 @@ try_again:
ut_ad(buf);
ut_ad(n > 0);
- low = (DWORD) offset;
- high = (DWORD) offset_high;
-
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads++;
os_mutex_exit(os_file_count_mutex);
-#ifndef UNIV_HOTBACKUP
- /* Protect the seek / read operation with a mutex */
- i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
- os_mutex_enter(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
- ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
-
- if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
-
-#ifndef UNIV_HOTBACKUP
- os_mutex_exit(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_reads--;
- os_mutex_exit(os_file_count_mutex);
-
- goto error_handling;
+ memset (&overlapped, 0, sizeof (overlapped));
+ overlapped.Offset = (DWORD)offset;
+ overlapped.OffsetHigh = (DWORD)offset_high;
+ overlapped.hEvent = win_get_syncio_event();
+ ret = ReadFile(file, buf, n, NULL, &overlapped);
+ if (ret) {
+ ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, FALSE);
}
-
- ret = ReadFile(file, buf, (DWORD) n, &len, NULL);
-
-#ifndef UNIV_HOTBACKUP
- os_mutex_exit(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
+ else if(GetLastError() == ERROR_IO_PENDING) {
+ ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE);
+ }
os_mutex_enter(os_file_count_mutex);
os_n_pending_reads--;
os_mutex_exit(os_file_count_mutex);
@@ -2554,9 +2610,6 @@ try_again:
return(TRUE);
}
#endif /* __WIN__ */
-#ifdef __WIN__
-error_handling:
-#endif
retry = os_file_handle_error_no_exit(NULL, "read");
if (retry) {
@@ -2609,14 +2662,9 @@ os_file_write(
#ifdef __WIN__
BOOL ret;
DWORD len;
- DWORD ret2;
- DWORD low;
- DWORD high;
ulint n_retries = 0;
ulint err;
-#ifndef UNIV_HOTBACKUP
- ulint i;
-#endif /* !UNIV_HOTBACKUP */
+ OVERLAPPED overlapped;
/* On 64-bit Windows, ulint is 64 bits. But offset and n should be
no more than 32 bits. */
@@ -2629,64 +2677,23 @@ os_file_write(
ut_ad(buf);
ut_ad(n > 0);
retry:
- low = (DWORD) offset;
- high = (DWORD) offset_high;
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes++;
os_mutex_exit(os_file_count_mutex);
-#ifndef UNIV_HOTBACKUP
- /* Protect the seek / write operation with a mutex */
- i = ((ulint) file) % OS_FILE_N_SEEK_MUTEXES;
-
- os_mutex_enter(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
- ret2 = SetFilePointer(file, low, &high, FILE_BEGIN);
-
- if (ret2 == 0xFFFFFFFF && GetLastError() != NO_ERROR) {
-
-#ifndef UNIV_HOTBACKUP
- os_mutex_exit(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
- os_mutex_enter(os_file_count_mutex);
- os_n_pending_writes--;
- os_mutex_exit(os_file_count_mutex);
+ memset (&overlapped, 0, sizeof (overlapped));
+ overlapped.Offset = (DWORD)offset;
+ overlapped.OffsetHigh = (DWORD)offset_high;
- ut_print_timestamp(stderr);
-
- fprintf(stderr,
- " InnoDB: Error: File pointer positioning to"
- " file %s failed at\n"
- "InnoDB: offset %lu %lu. Operating system"
- " error number %lu.\n"
- "InnoDB: Some operating system error numbers"
- " are described at\n"
- "InnoDB: "
- REFMAN "operating-system-error-codes.html\n",
- name, (ulong) offset_high, (ulong) offset,
- (ulong) GetLastError());
-
- return(FALSE);
+ overlapped.hEvent = win_get_syncio_event();
+ ret = WriteFile(file, buf, n, NULL, &overlapped);
+ if (ret) {
+ ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, FALSE);
}
-
- ret = WriteFile(file, buf, (DWORD) n, &len, NULL);
-
- /* Always do fsync to reduce the probability that when the OS crashes,
- a database page is only partially physically written to disk. */
-
-# ifdef UNIV_DO_FLUSH
- if (!os_do_not_call_flush_at_each_write) {
- ut_a(TRUE == os_file_flush(file));
+ else if(GetLastError() == ERROR_IO_PENDING) {
+ ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE);
}
-# endif /* UNIV_DO_FLUSH */
-
-#ifndef UNIV_HOTBACKUP
- os_mutex_exit(os_file_seek_mutexes[i]);
-#endif /* !UNIV_HOTBACKUP */
-
os_mutex_enter(os_file_count_mutex);
os_n_pending_writes--;
os_mutex_exit(os_file_count_mutex);
@@ -3071,9 +3078,6 @@ os_aio_array_create(
os_aio_array_t* array;
ulint i;
os_aio_slot_t* slot;
-#ifdef WIN_ASYNC_IO
- OVERLAPPED* over;
-#endif
ut_a(n > 0);
ut_a(n_segments > 0);
@@ -3089,23 +3093,12 @@ os_aio_array_create(
array->n_segments = n_segments;
array->n_reserved = 0;
array->slots = ut_malloc(n * sizeof(os_aio_slot_t));
-#ifdef __WIN__
- array->native_events = ut_malloc(n * sizeof(os_native_event_t));
-#endif
+
for (i = 0; i < n; i++) {
slot = os_aio_array_get_nth_slot(array, i);
-
slot->pos = i;
slot->reserved = FALSE;
-#ifdef WIN_ASYNC_IO
- slot->event = os_event_create(NULL);
-
- over = &(slot->control);
- over->hEvent = slot->event->handle;
-
- *((array->native_events) + i) = over->hEvent;
-#endif
}
return(array);
@@ -3119,18 +3112,7 @@ os_aio_array_free(
/*==============*/
os_aio_array_t* array) /*!< in, own: array to free */
{
-#ifdef WIN_ASYNC_IO
- ulint i;
- for (i = 0; i < array->n_slots; i++) {
- os_aio_slot_t* slot = os_aio_array_get_nth_slot(array, i);
- os_event_free(slot->event);
- }
-#endif /* WIN_ASYNC_IO */
-
-#ifdef __WIN__
- ut_free(array->native_events);
-#endif /* __WIN__ */
os_mutex_free(array->mutex);
os_event_free(array->not_full);
os_event_free(array->is_empty);
@@ -3209,7 +3191,11 @@ os_aio_init(
}
os_last_printout = time(NULL);
-
+#ifdef _WIN32
+ ut_a(completion_port == 0);
+ completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
+ ut_a(completion_port);
+#endif
}
/***********************************************************************
@@ -3251,11 +3237,9 @@ os_aio_array_wake_win_aio_at_shutdown(
/*==================================*/
os_aio_array_t* array) /*!< in: aio array */
{
- ulint i;
-
- for (i = 0; i < array->n_slots; i++) {
-
- os_event_set((array->slots + i)->event);
+ if(completion_port)
+ {
+ PostQueuedCompletionStatus(completion_port, 0, IOCP_SHUTDOWN_KEY, NULL);
}
}
#endif
@@ -3480,7 +3464,8 @@ found:
control = &(slot->control);
control->Offset = (DWORD)offset;
control->OffsetHigh = (DWORD)offset_high;
- os_event_reset(slot->event);
+ control->hEvent = 0;
+ slot->arr = array;
#endif
os_mutex_exit(array->mutex);
@@ -3517,9 +3502,6 @@ os_aio_array_free_slot(
os_event_set(array->is_empty);
}
-#ifdef WIN_ASYNC_IO
- os_event_reset(slot->event);
-#endif
os_mutex_exit(array->mutex);
}
@@ -3534,7 +3516,7 @@ os_aio_simulated_wake_handler_thread(
{
os_aio_array_t* array;
os_aio_slot_t* slot;
- ulint segment;
+ ulint segment __attribute__ ((unused));
ulint n;
ulint i;
@@ -3689,12 +3671,8 @@ os_aio(
os_aio_array_t* array;
os_aio_slot_t* slot;
#ifdef WIN_ASYNC_IO
- ibool retval;
- BOOL ret = TRUE;
DWORD len = (DWORD) n;
- struct fil_node_struct * dummy_mess1;
- void* dummy_mess2;
- ulint dummy_type;
+ BOOL ret;
#endif
ulint err = 0;
ibool retry;
@@ -3713,26 +3691,23 @@ os_aio(
wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER;
mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER);
- if (mode == OS_AIO_SYNC
-#ifdef WIN_ASYNC_IO
- && !os_aio_use_native_aio
-#endif
- ) {
+ if (mode == OS_AIO_SYNC)
+ {
+ ibool ret;
/* This is actually an ordinary synchronous read or write:
- no need to use an i/o-handler thread. NOTE that if we use
- Windows async i/o, Windows does not allow us to use
- ordinary synchronous os_file_read etc. on the same file,
- therefore we have built a special mechanism for synchronous
- wait in the Windows case. */
+ no need to use an i/o-handler thread */
if (type == OS_FILE_READ) {
- return(_os_file_read(file, buf, offset,
- offset_high, n, trx));
+ ret = _os_file_read(file, buf, offset,
+ offset_high, n, trx);
}
+ else {
+ ut_a(type == OS_FILE_WRITE);
- ut_a(type == OS_FILE_WRITE);
-
- return(os_file_write(name, file, buf, offset, offset_high, n));
+ ret = os_file_write(name, file, buf, offset, offset_high, n);
+ }
+ ut_a(ret);
+ return ret;
}
try_again:
@@ -3775,6 +3750,8 @@ try_again:
ret = ReadFile(file, buf, (DWORD)n, &len,
&(slot->control));
+ if(!ret && GetLastError() != ERROR_IO_PENDING)
+ err = 1;
#endif
} else {
if (!wake_later) {
@@ -3789,6 +3766,8 @@ try_again:
os_n_file_writes++;
ret = WriteFile(file, buf, (DWORD)n, &len,
&(slot->control));
+ if(!ret && GetLastError() != ERROR_IO_PENDING)
+ err = 1;
#endif
} else {
if (!wake_later) {
@@ -3801,34 +3780,7 @@ try_again:
ut_error;
}
-#ifdef WIN_ASYNC_IO
- if (os_aio_use_native_aio) {
- if ((ret && len == n)
- || (!ret && GetLastError() == ERROR_IO_PENDING)) {
- /* aio was queued successfully! */
-
- if (mode == OS_AIO_SYNC) {
- /* We want a synchronous i/o operation on a
- file where we also use async i/o: in Windows
- we must use the same wait mechanism as for
- async i/o */
-
- retval = os_aio_windows_handle(ULINT_UNDEFINED,
- slot->pos,
- &dummy_mess1,
- &dummy_mess2,
- &dummy_type,
- &space_id);
-
- return(retval);
- }
- return(TRUE);
- }
-
- err = 1; /* Fall through the next if */
- }
-#endif
if (err == 0) {
/* aio was queued successfully! */
@@ -3881,52 +3833,26 @@ os_aio_windows_handle(
ulint* space_id)
{
ulint orig_seg = segment;
- os_aio_array_t* array;
os_aio_slot_t* slot;
- ulint n;
- ulint i;
ibool ret_val;
BOOL ret;
DWORD len;
BOOL retry = FALSE;
+ ULONG_PTR key;
- if (segment == ULINT_UNDEFINED) {
- array = os_aio_sync_array;
- segment = 0;
- } else {
- segment = os_aio_get_array_and_local_segment(&array, segment);
- }
-
- /* NOTE! We only access constant fields in os_aio_array. Therefore
- we do not have to acquire the protecting mutex yet */
-
- ut_ad(os_aio_validate());
- ut_ad(segment < array->n_segments);
+ ret = GetQueuedCompletionStatus(completion_port, &len, &key,
+ (OVERLAPPED **)&slot, INFINITE);
- n = array->n_slots;
-
- if (array == os_aio_sync_array) {
- os_event_wait(os_aio_array_get_nth_slot(array, pos)->event);
- i = pos;
- } else {
- srv_set_io_thread_op_info(orig_seg, "wait Windows aio");
- i = os_event_wait_multiple(n,
- (array->native_events)
- );
+ /* If shutdown key was received, repost the shutdown message and exit */
+ if (ret && (key == IOCP_SHUTDOWN_KEY)) {
+ PostQueuedCompletionStatus(completion_port, 0, key, NULL);
+ os_thread_exit(NULL);
}
- os_mutex_enter(array->mutex);
-
- slot = os_aio_array_get_nth_slot(array, i);
-
- ut_a(slot->reserved);
-
- if (orig_seg != ULINT_UNDEFINED) {
- srv_set_io_thread_op_info(orig_seg,
- "get windows aio return value");
+ if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ os_thread_exit(NULL);
}
- ret = GetOverlappedResult(slot->file, &(slot->control), &len, TRUE);
*message1 = slot->message1;
*message2 = slot->message2;
@@ -3951,8 +3877,6 @@ os_aio_windows_handle(
ret_val = FALSE;
}
- os_mutex_exit(array->mutex);
-
if (retry) {
/* retry failed read/write operation synchronously.
No need to hold array->mutex. */
@@ -3961,37 +3885,19 @@ os_aio_windows_handle(
switch (slot->type) {
case OS_FILE_WRITE:
- ret = WriteFile(slot->file, slot->buf,
- (DWORD) slot->len, &len,
- &(slot->control));
-
+ ret_val = os_file_write(slot->name, slot->file, slot->buf,
+ slot->control.Offset, slot->control.OffsetHigh, slot->len);
break;
case OS_FILE_READ:
- ret = ReadFile(slot->file, slot->buf,
- (DWORD) slot->len, &len,
- &(slot->control));
-
+ ret_val = os_file_read(slot->file, slot->buf,
+ slot->control.Offset, slot->control.OffsetHigh, slot->len);
break;
default:
ut_error;
}
-
- if (!ret && GetLastError() == ERROR_IO_PENDING) {
- /* aio was queued successfully!
- We want a synchronous i/o operation on a
- file where we also use async i/o: in Windows
- we must use the same wait mechanism as for
- async i/o */
-
- ret = GetOverlappedResult(slot->file,
- &(slot->control),
- &len, TRUE);
- }
-
- ret_val = ret && len == slot->len;
}
- os_aio_array_free_slot(array, slot);
+ os_aio_array_free_slot((os_aio_array_t *)slot->arr, slot);
return(ret_val);
}
@@ -4020,7 +3926,7 @@ os_aio_simulated_handle(
ulint* space_id)
{
os_aio_array_t* array;
- ulint segment;
+ ulint segment __attribute__ ((unused));
os_aio_slot_t* slot;
os_aio_slot_t* slot2;
os_aio_slot_t* consecutive_ios[OS_AIO_MERGE_N_CONSECUTIVE];
diff --git a/storage/xtradb/os/os0sync.c b/storage/xtradb/os/os0sync.c
index dba997927cb..12153c309c0 100644
--- a/storage/xtradb/os/os0sync.c
+++ b/storage/xtradb/os/os0sync.c
@@ -38,6 +38,7 @@ Created 9/6/1995 Heikki Tuuri
#include "ut0mem.h"
#include "srv0start.h"
+#include "srv0srv.h"
/* Type definition for an operating system mutex struct */
struct os_mutex_struct{
@@ -74,11 +75,227 @@ UNIV_INTERN ulint os_event_count = 0;
UNIV_INTERN ulint os_mutex_count = 0;
UNIV_INTERN ulint os_fast_mutex_count = 0;
+/* The number of microsecnds in a second. */
+static const ulint MICROSECS_IN_A_SECOND = 1000000;
+
/* Because a mutex is embedded inside an event and there is an
event embedded inside a mutex, on free, this generates a recursive call.
This version of the free event function doesn't acquire the global lock */
static void os_event_free_internal(os_event_t event);
+/* On Windows (Vista and later), load function pointers for condition
+variable handling. Those functions are not available in prior versions,
+so we have to use them via runtime loading, as long as we support XP. */
+static void os_cond_module_init(void);
+
+#ifdef __WIN__
+/* Prototypes and function pointers for condition variable functions */
+typedef VOID (WINAPI* InitializeConditionVariableProc)
+ (PCONDITION_VARIABLE ConditionVariable);
+static InitializeConditionVariableProc initialize_condition_variable;
+
+typedef BOOL (WINAPI* SleepConditionVariableCSProc)
+ (PCONDITION_VARIABLE ConditionVariable,
+ PCRITICAL_SECTION CriticalSection,
+ DWORD dwMilliseconds);
+static SleepConditionVariableCSProc sleep_condition_variable;
+
+typedef VOID (WINAPI* WakeAllConditionVariableProc)
+ (PCONDITION_VARIABLE ConditionVariable);
+static WakeAllConditionVariableProc wake_all_condition_variable;
+
+typedef VOID (WINAPI* WakeConditionVariableProc)
+ (PCONDITION_VARIABLE ConditionVariable);
+static WakeConditionVariableProc wake_condition_variable;
+#endif
+
+/*********************************************************//**
+Initialitze condition variable */
+UNIV_INLINE
+void
+os_cond_init(
+/*=========*/
+ os_cond_t* cond) /*!< in: condition variable. */
+{
+ ut_a(cond);
+
+#ifdef __WIN__
+ ut_a(initialize_condition_variable != NULL);
+ initialize_condition_variable(cond);
+#else
+ ut_a(pthread_cond_init(cond, NULL) == 0);
+#endif
+}
+
+/*********************************************************//**
+Do a timed wait on condition variable.
+@return TRUE if timed out, FALSE otherwise */
+UNIV_INLINE
+ibool
+os_cond_wait_timed(
+/*===============*/
+ os_cond_t* cond, /*!< in: condition variable. */
+ os_fast_mutex_t* mutex, /*!< in: fast mutex */
+#ifndef __WIN__
+ const struct timespec* abstime /*!< in: timeout */
+#else
+ DWORD time_in_ms /*!< in: timeout in
+ milliseconds*/
+#endif /* !__WIN__ */
+)
+{
+#ifdef __WIN__
+ BOOL ret;
+ DWORD err;
+
+ ut_a(sleep_condition_variable != NULL);
+
+ ret = sleep_condition_variable(cond, mutex, time_in_ms);
+
+ if (!ret) {
+ err = GetLastError();
+ /* From http://msdn.microsoft.com/en-us/library/ms686301%28VS.85%29.aspx,
+ "Condition variables are subject to spurious wakeups
+ (those not associated with an explicit wake) and stolen wakeups
+ (another thread manages to run before the woken thread)."
+ Check for both types of timeouts.
+ Conditions are checked by the caller.*/
+ if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) {
+ return(TRUE);
+ }
+ }
+
+ ut_a(ret);
+
+ return(FALSE);
+#else
+ int ret;
+
+ ret = pthread_cond_timedwait(cond, mutex, abstime);
+
+ switch (ret) {
+ case 0:
+ case ETIMEDOUT:
+ /* We play it safe by checking for EINTR even though
+ according to the POSIX documentation it can't return EINTR. */
+ case EINTR:
+ break;
+
+ default:
+ fprintf(stderr, " InnoDB: pthread_cond_timedwait() returned: "
+ "%d: abstime={%lu,%lu}\n",
+ ret, (ulong) abstime->tv_sec, (ulong) abstime->tv_nsec);
+ ut_error;
+ }
+
+ return(ret == ETIMEDOUT);
+#endif
+}
+/*********************************************************//**
+Wait on condition variable */
+UNIV_INLINE
+void
+os_cond_wait(
+/*=========*/
+ os_cond_t* cond, /*!< in: condition variable. */
+ os_fast_mutex_t* mutex) /*!< in: fast mutex */
+{
+ ut_a(cond);
+ ut_a(mutex);
+
+#ifdef __WIN__
+ ut_a(sleep_condition_variable != NULL);
+ ut_a(sleep_condition_variable(cond, mutex, INFINITE));
+#else
+ ut_a(pthread_cond_wait(cond, mutex) == 0);
+#endif
+}
+
+/*********************************************************//**
+Wakes all threads waiting for condition variable */
+UNIV_INLINE
+void
+os_cond_broadcast(
+/*==============*/
+ os_cond_t* cond) /*!< in: condition variable. */
+{
+ ut_a(cond);
+
+#ifdef __WIN__
+ ut_a(wake_all_condition_variable != NULL);
+ wake_all_condition_variable(cond);
+#else
+ ut_a(pthread_cond_broadcast(cond) == 0);
+#endif
+}
+
+/*********************************************************//**
+Wakes one thread waiting for condition variable */
+UNIV_INLINE
+void
+os_cond_signal(
+/*==========*/
+ os_cond_t* cond) /*!< in: condition variable. */
+{
+ ut_a(cond);
+
+#ifdef __WIN__
+ ut_a(wake_condition_variable != NULL);
+ wake_condition_variable(cond);
+#else
+ ut_a(pthread_cond_signal(cond) == 0);
+#endif
+}
+
+/*********************************************************//**
+Destroys condition variable */
+UNIV_INLINE
+void
+os_cond_destroy(
+/*============*/
+ os_cond_t* cond) /*!< in: condition variable. */
+{
+#ifdef __WIN__
+ /* Do nothing */
+#else
+ ut_a(pthread_cond_destroy(cond) == 0);
+#endif
+}
+
+/*********************************************************//**
+On Windows (Vista and later), load function pointers for condition variable
+handling. Those functions are not available in prior versions, so we have to
+use them via runtime loading, as long as we support XP. */
+static
+void
+os_cond_module_init(void)
+/*=====================*/
+{
+#ifdef __WIN__
+ HMODULE h_dll;
+
+ if (!srv_use_native_conditions)
+ return;
+
+ h_dll = GetModuleHandle("kernel32");
+
+ initialize_condition_variable = (InitializeConditionVariableProc)
+ GetProcAddress(h_dll, "InitializeConditionVariable");
+ sleep_condition_variable = (SleepConditionVariableCSProc)
+ GetProcAddress(h_dll, "SleepConditionVariableCS");
+ wake_all_condition_variable = (WakeAllConditionVariableProc)
+ GetProcAddress(h_dll, "WakeAllConditionVariable");
+ wake_condition_variable = (WakeConditionVariableProc)
+ GetProcAddress(h_dll, "WakeConditionVariable");
+
+ /* When using native condition variables, check function pointers */
+ ut_a(initialize_condition_variable);
+ ut_a(sleep_condition_variable);
+ ut_a(wake_all_condition_variable);
+ ut_a(wake_condition_variable);
+#endif
+}
+
/*********************************************************//**
Initializes global event and OS 'slow' mutex lists. */
UNIV_INTERN
@@ -92,6 +309,9 @@ os_sync_init(void)
os_sync_mutex = NULL;
os_sync_mutex_inited = FALSE;
+ /* Now for Windows only */
+ os_cond_module_init();
+
os_sync_mutex = os_mutex_create(NULL);
os_sync_mutex_inited = TRUE;
@@ -146,42 +366,45 @@ os_event_create(
const char* name) /*!< in: the name of the event, if NULL
the event is created without a name */
{
-#ifdef __WIN__
- os_event_t event;
-
- event = ut_malloc(sizeof(struct os_event_struct));
-
- event->handle = CreateEvent(NULL, /* No security attributes */
- TRUE, /* Manual reset */
- FALSE, /* Initial state nonsignaled */
- (LPCTSTR) name);
- if (!event->handle) {
- fprintf(stderr,
- "InnoDB: Could not create a Windows event semaphore;"
- " Windows error %lu\n",
- (ulong) GetLastError());
- }
-#else /* Unix */
os_event_t event;
- UT_NOT_USED(name);
+#ifdef __WIN__
+ if(!srv_use_native_conditions) {
+
+ event = ut_malloc(sizeof(struct os_event_struct));
+
+ event->handle = CreateEvent(NULL,
+ TRUE,
+ FALSE,
+ (LPCTSTR) name);
+ if (!event->handle) {
+ fprintf(stderr,
+ "InnoDB: Could not create a Windows event"
+ " semaphore; Windows error %lu\n",
+ (ulong) GetLastError());
+ }
+ } else /* Windows with condition variables */
+#endif
- event = ut_malloc(sizeof(struct os_event_struct));
+ {
+ UT_NOT_USED(name);
- os_fast_mutex_init(&(event->os_mutex));
+ event = ut_malloc(sizeof(struct os_event_struct));
- ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
+ os_fast_mutex_init(&(event->os_mutex));
- event->is_set = FALSE;
+ os_cond_init(&(event->cond_var));
- /* We return this value in os_event_reset(), which can then be
- be used to pass to the os_event_wait_low(). The value of zero
- is reserved in os_event_wait_low() for the case when the
- caller does not want to pass any signal_count value. To
- distinguish between the two cases we initialize signal_count
- to 1 here. */
- event->signal_count = 1;
-#endif /* __WIN__ */
+ event->is_set = FALSE;
+
+ /* We return this value in os_event_reset(), which can then be
+ be used to pass to the os_event_wait_low(). The value of zero
+ is reserved in os_event_wait_low() for the case when the
+ caller does not want to pass any signal_count value. To
+ distinguish between the two cases we initialize signal_count
+ to 1 here. */
+ event->signal_count = 1;
+ }
/* The os_sync_mutex can be NULL because during startup an event
can be created [ because it's embedded in the mutex/rwlock ] before
@@ -211,10 +434,15 @@ os_event_set(
/*=========*/
os_event_t event) /*!< in: event to set */
{
-#ifdef __WIN__
ut_a(event);
- ut_a(SetEvent(event->handle));
-#else
+
+#ifdef __WIN__
+ if (!srv_use_native_conditions) {
+ ut_a(SetEvent(event->handle));
+ return;
+ }
+#endif
+
ut_a(event);
os_fast_mutex_lock(&(event->os_mutex));
@@ -224,11 +452,10 @@ os_event_set(
} else {
event->is_set = TRUE;
event->signal_count += 1;
- ut_a(0 == pthread_cond_broadcast(&(event->cond_var)));
+ os_cond_broadcast(&(event->cond_var));
}
os_fast_mutex_unlock(&(event->os_mutex));
-#endif
}
/**********************************************************//**
@@ -247,12 +474,14 @@ os_event_reset(
{
ib_int64_t ret = 0;
-#ifdef __WIN__
ut_a(event);
- ut_a(ResetEvent(event->handle));
-#else
- ut_a(event);
+#ifdef __WIN__
+ if(!srv_use_native_conditions) {
+ ut_a(ResetEvent(event->handle));
+ return(0);
+ }
+#endif
os_fast_mutex_lock(&(event->os_mutex));
@@ -264,7 +493,6 @@ os_event_reset(
ret = event->signal_count;
os_fast_mutex_unlock(&(event->os_mutex));
-#endif
return(ret);
}
@@ -277,17 +505,20 @@ os_event_free_internal(
os_event_t event) /*!< in: event to free */
{
#ifdef __WIN__
- ut_a(event);
+ if(!srv_use_native_conditions) {
+ ut_a(event);
+ ut_a(CloseHandle(event->handle));
+ } else
+#endif
+ {
+ ut_a(event);
- ut_a(CloseHandle(event->handle));
-#else
- ut_a(event);
+ /* This is to avoid freeing the mutex twice */
+ os_fast_mutex_free(&(event->os_mutex));
- /* This is to avoid freeing the mutex twice */
- os_fast_mutex_free(&(event->os_mutex));
+ os_cond_destroy(&(event->cond_var));
+ }
- ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
-#endif
/* Remove from the list of events */
UT_LIST_REMOVE(os_event_list, os_event_list, event);
@@ -306,16 +537,18 @@ os_event_free(
os_event_t event) /*!< in: event to free */
{
-#ifdef __WIN__
ut_a(event);
+#ifdef __WIN__
+ if(!srv_use_native_conditions){
+ ut_a(CloseHandle(event->handle));
+ } else /*Windows with condition variables */
+#endif
+ {
+ os_fast_mutex_free(&(event->os_mutex));
- ut_a(CloseHandle(event->handle));
-#else
- ut_a(event);
+ os_cond_destroy(&(event->cond_var));
+ }
- os_fast_mutex_free(&(event->os_mutex));
- ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
-#endif
/* Remove from the list of events */
os_mutex_enter(os_sync_mutex);
@@ -358,23 +591,24 @@ os_event_wait_low(
returned by previous call of
os_event_reset(). */
{
-#ifdef __WIN__
- DWORD err;
+
+ ib_int64_t old_signal_count;
- ut_a(event);
+#ifdef __WIN__
+ if(!srv_use_native_conditions) {
+ DWORD err;
- UT_NOT_USED(reset_sig_count);
+ ut_a(event);
- /* Specify an infinite time limit for waiting */
- err = WaitForSingleObject(event->handle, INFINITE);
+ UT_NOT_USED(reset_sig_count);
- ut_a(err == WAIT_OBJECT_0);
+ /* Specify an infinite wait */
+ err = WaitForSingleObject(event->handle, INFINITE);
- if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
- os_thread_exit(NULL);
+ ut_a(err == WAIT_OBJECT_0);
+ return;
}
-#else
- ib_int64_t old_signal_count;
+#endif
os_fast_mutex_lock(&(event->os_mutex));
@@ -399,13 +633,12 @@ os_event_wait_low(
return;
}
- pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
+ os_cond_wait(&(event->cond_var), &(event->os_mutex));
/* Solaris manual said that spurious wakeups may occur: we
have to check if the event really has been signaled after
we came here to wait */
}
-#endif
}
/**********************************************************//**
@@ -414,112 +647,112 @@ a timeout is exceeded.
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
UNIV_INTERN
ulint
-os_event_wait_time(
-/*===============*/
- os_event_t event, /*!< in: event to wait */
- ulint wtime) /*!< in: timeout in microseconds, or
- OS_SYNC_INFINITE_TIME */
+os_event_wait_time_low(
+/*===================*/
+ os_event_t event, /*!< in: event to wait */
+ ulint time_in_usec, /*!< in: timeout in
+ microseconds, or
+ OS_SYNC_INFINITE_TIME */
+ ib_int64_t reset_sig_count) /*!< in: zero or the value
+ returned by previous call of
+ os_event_reset(). */
+
{
+ ibool timed_out = FALSE;
+
#ifdef __WIN__
- DWORD err;
+ DWORD time_in_ms;
- ut_a(event);
+ if (!srv_use_native_conditions) {
+ DWORD err;
- if (wtime != OS_SYNC_INFINITE_TIME) {
- err = WaitForSingleObject(event->handle, (DWORD) wtime / 1000);
- } else {
- err = WaitForSingleObject(event->handle, INFINITE);
- }
+ ut_a(event);
- if (err == WAIT_OBJECT_0) {
+ if (time_in_usec != OS_SYNC_INFINITE_TIME) {
+ time_in_ms = time_in_usec / 1000;
+ err = WaitForSingleObject(event->handle, time_in_ms);
+ } else {
+ err = WaitForSingleObject(event->handle, INFINITE);
+ }
- return(0);
- } else if (err == WAIT_TIMEOUT) {
+ if (err == WAIT_OBJECT_0) {
+ return(0);
+ } else if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) {
+ return(OS_SYNC_TIME_EXCEEDED);
+ }
- return(OS_SYNC_TIME_EXCEEDED);
- } else {
ut_error;
- return(1000000); /* dummy value to eliminate compiler warn. */
+ /* Dummy value to eliminate compiler warning. */
+ return(42);
+ } else {
+ ut_a(sleep_condition_variable != NULL);
+
+ if (time_in_usec != OS_SYNC_INFINITE_TIME) {
+ time_in_ms = time_in_usec / 1000;
+ } else {
+ time_in_ms = INFINITE;
+ }
}
#else
- int err;
- int ret = 0;
- ulint tmp;
- ib_int64_t old_count;
- struct timeval tv_start;
- struct timespec timeout;
-
- if (wtime == OS_SYNC_INFINITE_TIME) {
- os_event_wait(event);
- return 0;
- }
+ struct timespec abstime;
- /* Compute the absolute point in time at which to time out. */
- gettimeofday(&tv_start, NULL);
- tmp = tv_start.tv_usec + wtime;
- timeout.tv_sec = tv_start.tv_sec + (tmp / 1000000);
- timeout.tv_nsec = (tmp % 1000000) * 1000;
+ if (time_in_usec != OS_SYNC_INFINITE_TIME) {
+ struct timeval tv;
+ int ret;
+ ulint sec;
+ ulint usec;
- os_fast_mutex_lock(&(event->os_mutex));
- old_count = event->signal_count;
+ ret = ut_usectime(&sec, &usec);
+ ut_a(ret == 0);
- for (;;) {
- if (event->is_set == TRUE || event->signal_count != old_count)
- break;
+ tv.tv_sec = sec;
+ tv.tv_usec = usec;
- err = pthread_cond_timedwait(&(event->cond_var),
- &(event->os_mutex), &timeout);
- if (err == ETIMEDOUT) {
- ret = OS_SYNC_TIME_EXCEEDED;
- break;
+ tv.tv_usec += time_in_usec;
+
+ if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) {
+ tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND;
+ tv.tv_usec %= MICROSECS_IN_A_SECOND;
}
+
+ abstime.tv_sec = tv.tv_sec;
+ abstime.tv_nsec = tv.tv_usec * 1000;
+ } else {
+ abstime.tv_nsec = 999999999;
+ abstime.tv_sec = (time_t) ULINT_MAX;
}
- os_fast_mutex_unlock(&(event->os_mutex));
+ ut_a(abstime.tv_nsec <= 999999999);
+
+#endif /* __WIN__ */
- if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ os_fast_mutex_lock(&event->os_mutex);
- os_thread_exit(NULL);
+ if (!reset_sig_count) {
+ reset_sig_count = event->signal_count;
}
- return ret;
-#endif
-}
+ do {
+ if (event->is_set || event->signal_count != reset_sig_count) {
-#ifdef __WIN__
-/**********************************************************//**
-Waits for any event in an OS native event array. Returns if even a single
-one is signaled or becomes signaled.
-@return index of the event which was signaled */
-UNIV_INTERN
-ulint
-os_event_wait_multiple(
-/*===================*/
- ulint n, /*!< in: number of events in the
- array */
- os_native_event_t* native_event_array)
- /*!< in: pointer to an array of event
- handles */
-{
- DWORD index;
+ break;
+ }
- ut_a(native_event_array);
- ut_a(n > 0);
+ timed_out = os_cond_wait_timed(
+ &event->cond_var, &event->os_mutex,
+#ifndef __WIN__
+ &abstime
+#else
+ time_in_ms
+#endif /* !__WIN__ */
+ );
- index = WaitForMultipleObjects((DWORD) n, native_event_array,
- FALSE, /* Wait for any 1 event */
- INFINITE); /* Infinite wait time
- limit */
- ut_a(index >= WAIT_OBJECT_0); /* NOTE: Pointless comparison */
- ut_a(index < WAIT_OBJECT_0 + n);
+ } while (!timed_out);
- if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
- os_thread_exit(NULL);
- }
+ os_fast_mutex_unlock(&event->os_mutex);
- return(index - WAIT_OBJECT_0);
+ return(timed_out ? OS_SYNC_TIME_EXCEEDED : 0);
}
-#endif
/*********************************************************//**
Creates an operating system mutex semaphore. Because these are slow, the
@@ -532,15 +765,6 @@ os_mutex_create(
const char* name) /*!< in: the name of the mutex, if NULL
the mutex is created without a name */
{
-#ifdef __WIN__
- HANDLE mutex;
- os_mutex_t mutex_str;
-
- mutex = CreateMutex(NULL, /* No security attributes */
- FALSE, /* Initial state: no owner */
- (LPCTSTR) name);
- ut_a(mutex);
-#else
os_fast_mutex_t* mutex;
os_mutex_t mutex_str;
@@ -549,7 +773,6 @@ os_mutex_create(
mutex = ut_malloc(sizeof(os_fast_mutex_t));
os_fast_mutex_init(mutex);
-#endif
mutex_str = ut_malloc(sizeof(os_mutex_str_t));
mutex_str->handle = mutex;
@@ -580,25 +803,11 @@ os_mutex_enter(
/*===========*/
os_mutex_t mutex) /*!< in: mutex to acquire */
{
-#ifdef __WIN__
- DWORD err;
-
- ut_a(mutex);
-
- /* Specify infinite time limit for waiting */
- err = WaitForSingleObject(mutex->handle, INFINITE);
-
- ut_a(err == WAIT_OBJECT_0);
-
- (mutex->count)++;
- ut_a(mutex->count == 1);
-#else
os_fast_mutex_lock(mutex->handle);
(mutex->count)++;
ut_a(mutex->count == 1);
-#endif
}
/**********************************************************//**
@@ -614,11 +823,7 @@ os_mutex_exit(
ut_a(mutex->count == 1);
(mutex->count)--;
-#ifdef __WIN__
- ut_a(ReleaseMutex(mutex->handle));
-#else
os_fast_mutex_unlock(mutex->handle);
-#endif
}
/**********************************************************//**
@@ -647,15 +852,9 @@ os_mutex_free(
os_mutex_exit(os_sync_mutex);
}
-#ifdef __WIN__
- ut_a(CloseHandle(mutex->handle));
-
- ut_free(mutex);
-#else
os_fast_mutex_free(mutex->handle);
ut_free(mutex->handle);
ut_free(mutex);
-#endif
}
/*********************************************************//**
diff --git a/storage/xtradb/plug.in b/storage/xtradb/plug.in
index 2e0c873094a..1846543a81c 100644
--- a/storage/xtradb/plug.in
+++ b/storage/xtradb/plug.in
@@ -16,7 +16,6 @@
MYSQL_STORAGE_ENGINE(xtradb, xtradb, [XtraDB Storage Engine],
[XtraDB - a drop-in replacement for InnoDB], [max,max-no-ndb])
-MYSQL_PLUGIN_DIRECTORY(xtradb, [storage/xtradb])
MYSQL_PLUGIN_STATIC(xtradb, [libxtradb.la])
MYSQL_PLUGIN_DYNAMIC(xtradb, [ha_xtradb.la])
MYSQL_PLUGIN_ACTIONS(xtradb, [
diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c
index 13dccdffb96..1dbd9e3a42d 100644
--- a/storage/xtradb/row/row0sel.c
+++ b/storage/xtradb/row/row0sel.c
@@ -58,6 +58,8 @@ Created 12/19/1997 Heikki Tuuri
#include "buf0lru.h"
#include "ha_prototypes.h"
+#include "my_compare.h" /* enum icp_result */
+
/* Maximum number of rows to prefetch; MySQL interface has another parameter */
#define SEL_MAX_N_PREFETCH 16
@@ -2674,144 +2676,96 @@ row_sel_field_store_in_mysql_format(
}
/**************************************************************//**
-Convert a row in the Innobase format to a row in the MySQL format.
-Note that the template in prebuilt may advise us to copy only a few
-columns to mysql_rec, other columns are left blank. All columns may not
-be needed in the query.
-@return TRUE on success, FALSE if not all columns could be retrieved */
+Convert a field in the Innobase format to a field in the MySQL format. */
static __attribute__((warn_unused_result))
ibool
-row_sel_store_mysql_rec(
-/*====================*/
- byte* mysql_rec, /*!< out: row in the MySQL format */
- row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
- const rec_t* rec, /*!< in: Innobase record in the index
- which was described in prebuilt's
- template, or in the clustered index;
- must be protected by a page latch */
- ibool rec_clust, /*!< in: TRUE if rec is in the
- clustered index instead of
- prebuilt->index */
- const ulint* offsets, /* in: array returned by
- rec_get_offsets() */
- ulint start_field_no, /* in: start from this field */
- ulint end_field_no) /* in: end at this field */
+row_sel_store_mysql_field(
+/*======================*/
+ byte* mysql_rec, /*!< out: record in the
+ MySQL format */
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct */
+ const rec_t* rec, /*!< in: InnoDB record;
+ must be protected by
+ a page latch */
+ const ulint* offsets, /*!< in: array returned by
+ rec_get_offsets() */
+ ulint field_no, /*!< in: templ->rec_field_no or
+ templ->clust_rec_field_no */
+ const mysql_row_templ_t*templ) /*!< in: row template */
{
- mem_heap_t* extern_field_heap = NULL;
- mem_heap_t* heap;
- ulint i;
+ const byte* data;
+ ulint len;
- ut_ad(prebuilt->mysql_template);
ut_ad(prebuilt->default_rec);
+ ut_ad(templ);
+ ut_ad(templ >= prebuilt->mysql_template);
+ ut_ad(templ < &prebuilt->mysql_template[prebuilt->n_template]);
+ ut_ad(field_no == templ->clust_rec_field_no
+ || field_no == templ->rec_field_no
+ || field_no == templ->icp_rec_field_no);
ut_ad(rec_offs_validate(rec, NULL, offsets));
- ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
- if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
- mem_heap_free(prebuilt->blob_heap);
- prebuilt->blob_heap = NULL;
- }
-
- for (i = start_field_no; i < end_field_no /* prebuilt->n_template */ ; i++) {
-
- const mysql_row_templ_t*templ = prebuilt->mysql_template + i;
- const byte* data;
- ulint len;
- ulint field_no;
-
- field_no = rec_clust
- ? templ->clust_rec_field_no : templ->rec_field_no;
+ if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) {
- if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) {
+ mem_heap_t* heap;
+ /* Copy an externally stored field to a temporary heap */
- /* Copy an externally stored field to the temporary
- heap */
+ ut_a(!prebuilt->trx->has_search_latch);
+ ut_ad(field_no == templ->clust_rec_field_no);
- ut_a(!prebuilt->trx->has_search_latch);
+ if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
+ if (prebuilt->blob_heap == NULL) {
+ prebuilt->blob_heap = mem_heap_create(
+ UNIV_PAGE_SIZE);
+ }
- if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
- if (prebuilt->blob_heap == NULL) {
- prebuilt->blob_heap = mem_heap_create(
- UNIV_PAGE_SIZE);
- }
+ heap = prebuilt->blob_heap;
+ } else {
+ heap = mem_heap_create(UNIV_PAGE_SIZE);
+ }
- heap = prebuilt->blob_heap;
- } else {
- extern_field_heap
- = mem_heap_create(UNIV_PAGE_SIZE);
+ /* NOTE: if we are retrieving a big BLOB, we may
+ already run out of memory in the next call, which
+ causes an assert */
- heap = extern_field_heap;
- }
+ data = btr_rec_copy_externally_stored_field(
+ rec, offsets,
+ dict_table_zip_size(prebuilt->table),
+ field_no, &len, heap);
- /* NOTE: if we are retrieving a big BLOB, we may
- already run out of memory in the next call, which
- causes an assert */
-
- data = btr_rec_copy_externally_stored_field(
- rec, offsets,
- dict_table_zip_size(prebuilt->table),
- field_no, &len, heap);
-
- if (UNIV_UNLIKELY(!data)) {
- /* The externally stored field
- was not written yet. This
- record should only be seen by
- recv_recovery_rollback_active()
- or any TRX_ISO_READ_UNCOMMITTED
- transactions. */
-
- if (extern_field_heap) {
- mem_heap_free(extern_field_heap);
- }
+ if (UNIV_UNLIKELY(!data)) {
+ /* The externally stored field was not written
+ yet. This record should only be seen by
+ recv_recovery_rollback_active() or any
+ TRX_ISO_READ_UNCOMMITTED transactions. */
- return(FALSE);
+ if (heap != prebuilt->blob_heap) {
+ mem_heap_free(heap);
}
- ut_a(len != UNIV_SQL_NULL);
- } else {
- /* Field is stored in the row. */
-
- data = rec_get_nth_field(rec, offsets, field_no, &len);
+ ut_a(prebuilt->trx->isolation_level
+ == TRX_ISO_READ_UNCOMMITTED);
+ return(FALSE);
+ }
- if (UNIV_UNLIKELY(templ->type == DATA_BLOB)
- && len != UNIV_SQL_NULL) {
+ ut_a(len != UNIV_SQL_NULL);
- /* It is a BLOB field locally stored in the
- InnoDB record: we MUST copy its contents to
- prebuilt->blob_heap here because later code
- assumes all BLOB values have been copied to a
- safe place. */
+ row_sel_field_store_in_mysql_format(
+ mysql_rec + templ->mysql_col_offset,
+ templ, data, len);
- if (prebuilt->blob_heap == NULL) {
- prebuilt->blob_heap = mem_heap_create(
- UNIV_PAGE_SIZE);
- }
-
- data = memcpy(mem_heap_alloc(
- prebuilt->blob_heap, len),
- data, len);
- }
+ if (heap != prebuilt->blob_heap) {
+ mem_heap_free(heap);
}
+ } else {
+ /* Field is stored in the row. */
- if (len != UNIV_SQL_NULL) {
- row_sel_field_store_in_mysql_format(
- mysql_rec + templ->mysql_col_offset,
- templ, data, len);
-
- /* Cleanup */
- if (extern_field_heap) {
- mem_heap_free(extern_field_heap);
- extern_field_heap = NULL;
- }
+ data = rec_get_nth_field(rec, offsets, field_no, &len);
- if (templ->mysql_null_bit_mask) {
- /* It is a nullable column with a non-NULL
- value */
- mysql_rec[templ->mysql_null_byte_offset]
- &= ~(byte) templ->mysql_null_bit_mask;
- }
- } else {
+ if (len == UNIV_SQL_NULL) {
/* MySQL assumes that the field for an SQL
NULL value is set to the default value. */
+ ut_ad(templ->mysql_null_bit_mask);
UNIV_MEM_ASSERT_RW(prebuilt->default_rec
+ templ->mysql_col_offset,
@@ -2822,6 +2776,85 @@ row_sel_store_mysql_rec(
(const byte*) prebuilt->default_rec
+ templ->mysql_col_offset,
templ->mysql_col_len);
+ return(TRUE);
+ }
+
+ if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
+
+ /* It is a BLOB field locally stored in the
+ InnoDB record: we MUST copy its contents to
+ prebuilt->blob_heap here because
+ row_sel_field_store_in_mysql_format() stores a
+ pointer to the data, and the data passed to us
+ will be invalid as soon as the
+ mini-transaction is committed and the page
+ latch on the clustered index page is
+ released. */
+
+ if (prebuilt->blob_heap == NULL) {
+ prebuilt->blob_heap = mem_heap_create(
+ UNIV_PAGE_SIZE);
+ }
+
+ data = mem_heap_dup(prebuilt->blob_heap, data, len);
+ }
+
+ row_sel_field_store_in_mysql_format(
+ mysql_rec + templ->mysql_col_offset,
+ templ, data, len);
+ }
+
+ ut_ad(len != UNIV_SQL_NULL);
+
+ if (templ->mysql_null_bit_mask) {
+ /* It is a nullable column with a non-NULL
+ value */
+ mysql_rec[templ->mysql_null_byte_offset]
+ &= ~(byte) templ->mysql_null_bit_mask;
+ }
+
+ return(TRUE);
+}
+
+/**************************************************************//**
+Convert a row in the Innobase format to a row in the MySQL format.
+Note that the template in prebuilt may advise us to copy only a few
+columns to mysql_rec, other columns are left blank. All columns may not
+be needed in the query.
+@return TRUE on success, FALSE if not all columns could be retrieved */
+static __attribute__((warn_unused_result))
+ibool
+row_sel_store_mysql_rec(
+/*====================*/
+ byte* mysql_rec, /*!< out: row in the MySQL format */
+ row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
+ const rec_t* rec, /*!< in: Innobase record in the index
+ which was described in prebuilt's
+ template, or in the clustered index;
+ must be protected by a page latch */
+ ibool rec_clust, /*!< in: TRUE if rec is in the
+ clustered index instead of
+ prebuilt->index */
+ const ulint* offsets) /*!< in: array returned by
+ rec_get_offsets(rec) */
+{
+ ulint i;
+
+ if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
+ mem_heap_free(prebuilt->blob_heap);
+ prebuilt->blob_heap = NULL;
+ }
+
+ for (i = 0; i < prebuilt->n_template; i++) {
+ const mysql_row_templ_t*templ = &prebuilt->mysql_template[i];
+
+ if (!row_sel_store_mysql_field(mysql_rec, prebuilt,
+ rec, offsets,
+ rec_clust
+ ? templ->clust_rec_field_no
+ : templ->rec_field_no,
+ templ)) {
+ return(FALSE);
}
}
@@ -3192,31 +3225,19 @@ UNIV_INLINE __attribute__((warn_unused_result))
ibool
row_sel_push_cache_row_for_mysql(
/*=============================*/
- row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
- const rec_t* rec, /*!< in: record to push, in the index
- which was described in prebuilt's
- template, or in the clustered index;
- must be protected by a page latch */
- ibool rec_clust, /*!< in: TRUE if rec is in the
- clustered index instead of
- prebuilt->index */
- const ulint* offsets, /* in: rec_get_offsets() */
- ulint start_field_no, /* in: start from this field */
- byte* remainder_buf) /* in: if start_field_no !=0,
- where to take prev fields */
+ byte* mysql_rec, /*!< in/out: MySQL record */
+ row_prebuilt_t* prebuilt) /*!< in/out: prebuilt struct */
{
- byte* buf;
- ulint i;
-
ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE);
- ut_ad(rec_offs_validate(rec, NULL, offsets));
- ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
ut_a(!prebuilt->templ_contains_blob);
- if (prebuilt->fetch_cache[0] == NULL) {
+ if (UNIV_UNLIKELY(prebuilt->fetch_cache[0] == NULL)) {
+ ulint i;
/* Allocate memory for the fetch cache */
+ ut_ad(prebuilt->n_fetch_cached == 0);
for (i = 0; i < MYSQL_FETCH_CACHE_SIZE; i++) {
+ byte* buf;
/* A user has reported memory corruption in these
buffers in Linux. Put magic numbers there to help
@@ -3236,46 +3257,14 @@ row_sel_push_cache_row_for_mysql(
UNIV_MEM_INVALID(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
prebuilt->mysql_row_len);
- if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
- prebuilt->fetch_cache[
- prebuilt->n_fetch_cached],
- prebuilt,
- rec,
- rec_clust,
- offsets,
- start_field_no,
- prebuilt->n_template))) {
- return(FALSE);
- }
-
- if (start_field_no) {
-
- for (i=0; i < start_field_no; i++) {
- register ulint offs;
- mysql_row_templ_t* templ;
- register byte * null_byte;
-
- templ = prebuilt->mysql_template + i;
+ memcpy(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
+ mysql_rec, prebuilt->mysql_row_len);
- if (templ->mysql_null_bit_mask) {
- offs = templ->mysql_null_byte_offset;
-
- null_byte= prebuilt->fetch_cache[
- prebuilt->n_fetch_cached]+offs;
- (*null_byte)&= ~templ->mysql_null_bit_mask;
- (*null_byte)|= (*(remainder_buf + offs) &
- templ->mysql_null_bit_mask);
- }
-
- offs = templ->mysql_col_offset;
- memcpy(prebuilt->fetch_cache[prebuilt->n_fetch_cached]
- + offs,
- remainder_buf + offs,
- templ->mysql_col_len);
- }
+ if (++prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE) {
+ return(FALSE);
}
- prebuilt->n_fetch_cached++;
+ row_sel_pop_cached_row_for_mysql(mysql_rec, prebuilt);
return(TRUE);
}
@@ -3353,6 +3342,81 @@ row_sel_try_search_shortcut_for_mysql(
return(SEL_FOUND);
}
+/*********************************************************************//**
+Check a pushed-down index condition.
+@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */
+static
+enum icp_result
+row_search_idx_cond_check(
+/*======================*/
+ byte* mysql_rec, /*!< out: record
+ in MySQL format (invalid unless
+ prebuilt->idx_cond!=NULL and
+ we return ICP_MATCH) */
+ row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct
+ for the table handle */
+ const rec_t* rec, /*!< in: InnoDB record */
+ const ulint* offsets) /*!< in: rec_get_offsets() */
+{
+ enum icp_result result;
+ ulint i;
+
+ ut_ad(rec_offs_validate(rec, prebuilt->index, offsets));
+
+ if (!prebuilt->idx_cond) {
+ return(ICP_MATCH);
+ }
+
+ /* Convert to MySQL format those fields that are needed for
+ evaluating the index condition. */
+
+ if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
+ mem_heap_empty(prebuilt->blob_heap);
+ }
+
+ for (i = 0; i < prebuilt->idx_cond_n_cols; i++) {
+ const mysql_row_templ_t*templ = &prebuilt->mysql_template[i];
+
+ if (!row_sel_store_mysql_field(mysql_rec, prebuilt,
+ rec, offsets,
+ templ->icp_rec_field_no,
+ templ)) {
+ return(ICP_NO_MATCH);
+ }
+ }
+
+ /* We assume that the index conditions on
+ case-insensitive columns are case-insensitive. The
+ case of such columns may be wrong in a secondary
+ index, if the case of the column has been updated in
+ the past, or a record has been deleted and a record
+ inserted in a different case. */
+ result = innobase_index_cond(prebuilt->idx_cond);
+ switch (result) {
+ case ICP_MATCH:
+ /* Convert the remaining fields to MySQL format.
+ If this is a secondary index record, we must defer
+ this until we have fetched the clustered index record. */
+ if (!prebuilt->need_to_access_clustered
+ || dict_index_is_clust(prebuilt->index)) {
+ if (!row_sel_store_mysql_rec(mysql_rec, prebuilt,
+ rec,
+ FALSE, offsets)) {
+ ut_ad(dict_index_is_clust(prebuilt->index));
+ result = ICP_NO_MATCH;
+ }
+ }
+ /* fall through */
+ case ICP_NO_MATCH:
+ case ICP_OUT_OF_RANGE:
+ case ICP_ABORTED_BY_USER:
+ return(result);
+ default: ;
+ }
+
+ ut_error;
+}
+
/********************************************************************//**
Searches for rows in the database. This is used in the interface to
MySQL. This function opens a cursor, and also implements fetch next
@@ -3415,10 +3479,8 @@ row_search_for_mysql(
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_;
- ibool some_fields_in_buffer;
ibool table_lock_waited = FALSE;
ibool problematic_use = FALSE;
- ibool get_clust_rec = 0;
rec_offs_init(offsets_);
@@ -3681,10 +3743,24 @@ row_search_for_mysql(
mtr_commit(&mtr). */
ut_ad(!rec_get_deleted_flag(rec, comp));
+ if (prebuilt->idx_cond) {
+ switch (row_search_idx_cond_check(
+ buf, prebuilt,
+ rec, offsets)) {
+ case ICP_NO_MATCH:
+ case ICP_OUT_OF_RANGE:
+ case ICP_ABORTED_BY_USER:
+ goto shortcut_mismatch;
+ case ICP_MATCH:
+ goto shortcut_match;
+ default: ;
+ }
+ ut_error;
+ }
+
if (!row_sel_store_mysql_rec(buf, prebuilt,
rec, FALSE,
- offsets, 0,
- prebuilt->n_template)) {
+ offsets)) {
/* Only fresh inserts may contain
incomplete externally stored
columns. Pretend that such
@@ -3695,13 +3771,12 @@ row_search_for_mysql(
rolling back a recovered
transaction. Rollback happens
at a lower level, not here. */
- ut_a(trx->isolation_level
- == TRX_ISO_READ_UNCOMMITTED);
/* Proceed as in case SEL_RETRY. */
break;
}
+ shortcut_match:
mtr_commit(&mtr);
/* ut_print_name(stderr, index->name);
@@ -3713,6 +3788,7 @@ row_search_for_mysql(
goto release_search_latch_if_needed;
case SEL_EXHAUSTED:
+ shortcut_mismatch:
mtr_commit(&mtr);
/* ut_print_name(stderr, index->name);
@@ -3804,8 +3880,9 @@ retry_check:
if (!prebuilt->sql_stat_start) {
/* No need to set an intention lock or assign a read view */
- if (trx->read_view == NULL
- && prebuilt->select_lock_type == LOCK_NONE) {
+ if (UNIV_UNLIKELY
+ (trx->read_view == NULL
+ && prebuilt->select_lock_type == LOCK_NONE)) {
fputs("InnoDB: Error: MySQL is trying to"
" perform a consistent read\n"
@@ -4265,6 +4342,16 @@ no_gap_lock:
if (UNIV_LIKELY(trx->wait_lock != NULL)) {
lock_cancel_waiting_and_release(
trx->wait_lock);
+ mutex_exit(&kernel_mutex);
+
+ if (old_vers == NULL) {
+ /* The row was not yet committed */
+
+ goto next_rec;
+ }
+
+ did_semi_consistent_read = TRUE;
+ rec = old_vers;
} else {
mutex_exit(&kernel_mutex);
@@ -4275,19 +4362,7 @@ no_gap_lock:
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED,
&heap);
- err = DB_SUCCESS;
- break;
}
- mutex_exit(&kernel_mutex);
-
- if (old_vers == NULL) {
- /* The row was not yet committed */
-
- goto next_rec;
- }
-
- did_semi_consistent_read = TRUE;
- rec = old_vers;
break;
default:
@@ -4346,8 +4421,27 @@ no_gap_lock:
if (!lock_sec_rec_cons_read_sees(
rec, trx->read_view)) {
- get_clust_rec = TRUE;
- goto idx_cond_check;
+ /* We should look at the clustered index.
+ However, as this is a non-locking read,
+ we can skip the clustered index lookup if
+ the condition does not match the secondary
+ index entry. */
+ switch (row_search_idx_cond_check(
+ buf, prebuilt, rec, offsets)) {
+ case ICP_NO_MATCH:
+ goto next_rec;
+ case ICP_OUT_OF_RANGE:
+ err = DB_RECORD_NOT_FOUND;
+ goto idx_cond_failed;
+ case ICP_ABORTED_BY_USER:
+ err = DB_SEARCH_ABORTED_BY_USER;
+ goto idx_cond_failed;
+ case ICP_MATCH:
+ goto requires_clust_rec;
+ default: ;
+ }
+
+ ut_error;
}
}
}
@@ -4392,38 +4486,31 @@ no_gap_lock:
goto next_rec;
}
-
-idx_cond_check:
- if (prebuilt->idx_cond_func) {
- int res;
- ibool ib_res;
- ut_ad(prebuilt->template_type != ROW_MYSQL_DUMMY_TEMPLATE);
- offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
- ib_res= row_sel_store_mysql_rec(buf, prebuilt, rec, FALSE,
- offsets, 0, prebuilt->n_index_fields);
- /*
- The above call will fail and return FALSE when requested to
- store an "externally stored column" (afaiu, a blob). Index
- Condition Pushdown is not supported for indexes with blob
- columns, so we should never get this error.
- */
- ut_ad(ib_res);
- res= prebuilt->idx_cond_func(prebuilt->idx_cond_func_arg);
- if (res == XTRADB_ICP_NO_MATCH)
- goto next_rec;
- else if (res != XTRADB_ICP_MATCH) {
- err= (res == XTRADB_ICP_ABORTED_BY_USER ?
- DB_SEARCH_ABORTED_BY_USER :
- DB_RECORD_NOT_FOUND);
- goto idx_cond_failed;
- }
- /* res == XTRADB_ICP_MATCH */
- }
+ /* Check if the record matches the index condition. */
+ switch (row_search_idx_cond_check(buf, prebuilt, rec, offsets)) {
+ case ICP_NO_MATCH:
+ if (did_semi_consistent_read) {
+ row_unlock_for_mysql(prebuilt, TRUE);
+ }
+ goto next_rec;
+ case ICP_ABORTED_BY_USER:
+ err = DB_SEARCH_ABORTED_BY_USER;
+ goto idx_cond_failed;
+ case ICP_OUT_OF_RANGE:
+ err = DB_RECORD_NOT_FOUND;
+ goto idx_cond_failed;
+ case ICP_MATCH:
+ break;
+ default:
+ ut_error;
+ }
/* Get the clustered index record if needed, if we did not do the
search using the clustered index. */
- if (get_clust_rec || (index != clust_index
- && prebuilt->need_to_access_clustered)) {
+ if (index != clust_index && prebuilt->need_to_access_clustered) {
+
+requires_clust_rec:
+ ut_ad(index != clust_index);
/* We use a 'goto' to the preceding label if a consistent
read of a secondary index record requires us to look up old
@@ -4487,6 +4574,19 @@ idx_cond_check:
result_rec = clust_rec;
ut_ad(rec_offs_validate(result_rec, clust_index, offsets));
+
+ if (prebuilt->idx_cond) {
+ /* Convert the remaining fields to
+ MySQL format. We were unable to do
+ this in row_search_idx_cond_check(),
+ because the condition is on the
+ secondary index and the requested
+ column is in the clustered index. */
+ if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec,
+ TRUE, offsets)) {
+ goto next_rec;
+ }
+ }
} else {
result_rec = rec;
}
@@ -4520,15 +4620,10 @@ idx_cond_check:
are BLOBs in the fields to be fetched. In HANDLER we do
not cache rows because there the cursor is a scrollable
cursor. */
- some_fields_in_buffer = (index != clust_index
- && prebuilt->idx_cond_func);
-
- if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
- result_rec != rec,
- offsets,
- some_fields_in_buffer?
- prebuilt->n_index_fields : 0,
- buf)) {
+
+ if (!prebuilt->idx_cond
+ && !row_sel_store_mysql_rec(buf, prebuilt, result_rec,
+ result_rec != rec, offsets)) {
/* Only fresh inserts may contain incomplete
externally stored columns. Pretend that such
records do not exist. Such records may only be
@@ -4536,14 +4631,10 @@ idx_cond_check:
level or when rolling back a recovered
transaction. Rollback happens at a lower
level, not here. */
- ut_a(trx->isolation_level == TRX_ISO_READ_UNCOMMITTED);
- } else if (prebuilt->n_fetch_cached
- == MYSQL_FETCH_CACHE_SIZE) {
-
- goto got_row;
+ goto next_rec;
+ } else if (row_sel_push_cache_row_for_mysql(buf, prebuilt)) {
+ goto next_rec;
}
-
- goto next_rec;
} else {
if (UNIV_UNLIKELY
(prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE)) {
@@ -4564,15 +4655,11 @@ idx_cond_check:
rec_offs_size(offsets));
mach_write_to_4(buf,
rec_offs_extra_size(offsets) + 4);
- } else {
- /* Returning a row to MySQL */
-
- if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec,
- result_rec != rec,
- offsets,
- prebuilt->idx_cond_func?
- prebuilt->n_index_fields: 0,
- prebuilt->n_template)) {
+ } else if (!prebuilt->idx_cond) {
+ /* The record was not yet converted to MySQL format. */
+ if (!row_sel_store_mysql_rec(
+ buf, prebuilt,
+ result_rec, result_rec != rec, offsets)) {
/* Only fresh inserts may contain
incomplete externally stored
columns. Pretend that such records do
@@ -4581,8 +4668,6 @@ idx_cond_check:
isolation level or when rolling back a
recovered transaction. Rollback
happens at a lower level, not here. */
- ut_a(trx->isolation_level
- == TRX_ISO_READ_UNCOMMITTED);
goto next_rec;
}
}
@@ -4600,7 +4685,6 @@ idx_cond_check:
/* From this point on, 'offsets' are invalid. */
-got_row:
/* We have an optimization to save CPU time: if this is a consistent
read on a unique condition on the clustered index, then we do not
store the pcur position, because any fetch next or prev will anyway
@@ -4624,7 +4708,6 @@ idx_cond_failed:
next_rec:
/* Reset the old and new "did semi-consistent read" flags. */
- get_clust_rec = FALSE;
if (UNIV_UNLIKELY(prebuilt->row_read_type
== ROW_READ_DID_SEMI_CONSISTENT)) {
prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
@@ -4635,6 +4718,7 @@ next_rec:
/*-------------------------------------------------------------*/
/* PHASE 5: Move the cursor to the next index record */
+ /*TODO: with ICP, do this when switching pages, every N pages */
if (UNIV_UNLIKELY(mtr_has_extra_clust_latch)) {
/* We must commit mtr if we are moving to the next
non-clustered index record, because we could break the
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index fb13ec395c2..9a142e1ca86 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -139,6 +139,20 @@ UNIV_INTERN ulint srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
/** Place locks to records only i.e. do not use next-key locking except
on duplicate key checking and foreign key checking */
UNIV_INTERN ibool srv_locks_unsafe_for_binlog = FALSE;
+#ifdef __WIN__
+/* Windows native condition variables. We use runtime loading / function
+pointers, because they are not available on Windows Server 2003 and
+Windows XP/2000.
+
+We use condition for events on Windows if possible, even if os_event
+resembles Windows kernel event object well API-wise. The reason is
+performance, kernel objects are heavyweights and WaitForSingleObject() is a
+performance killer causing calling thread to context switch. Besides, Innodb
+is preallocating large number (often millions) of os_events. With kernel event
+objects it takes a big chunk out of non-paged pool, which is better suited
+for tasks like IO than for storing idle event objects. */
+UNIV_INTERN ibool srv_use_native_conditions = FALSE;
+#endif /* __WIN__ */
UNIV_INTERN ulint srv_n_data_files = 0;
UNIV_INTERN char** srv_data_file_names = NULL;
@@ -496,9 +510,6 @@ UNIV_INTERN FILE* srv_misc_tmpfile;
UNIV_INTERN ulint srv_main_thread_process_no = 0;
UNIV_INTERN ulint srv_main_thread_id = 0;
-/* Release row locks already in the prepare phase */
-UNIV_INTERN my_bool innobase_release_locks_early = FALSE;
-
/* The following count work done by srv_master_thread. */
/* Iterations by the 'once per second' loop. */
diff --git a/storage/xtradb/srv/srv0start.c b/storage/xtradb/srv/srv0start.c
index cef045d72e1..d002a1bb682 100644
--- a/storage/xtradb/srv/srv0start.c
+++ b/storage/xtradb/srv/srv0start.c
@@ -1265,6 +1265,7 @@ innobase_start_or_create_for_mysql(void)
case OS_WIN95:
case OS_WIN31:
case OS_WINNT:
+ srv_use_native_conditions = FALSE;
/* On Win 95, 98, ME, Win32 subsystem for Windows 3.1,
and NT use simulated aio. In NT Windows provides async i/o,
but when run in conjunction with InnoDB Hot Backup, it seemed
@@ -1272,24 +1273,26 @@ innobase_start_or_create_for_mysql(void)
os_aio_use_native_aio = FALSE;
break;
- default:
- /* On Win 2000 and XP use async i/o */
- //os_aio_use_native_aio = TRUE;
- os_aio_use_native_aio = FALSE;
- fprintf(stderr,
- "InnoDB: Windows native async i/o is disabled as default.\n"
- "InnoDB: It is not applicable for the current"
- " multi io threads implementation.\n");
- break;
+
+ case OS_WIN2000:
+ case OS_WINXP:
+ /* On 2000 and XP, async IO is available, but no condition variables. */
+ os_aio_use_native_aio = TRUE;
+ srv_use_native_conditions = FALSE;
+ break;
+
+ default:
+ os_aio_use_native_aio = TRUE;
+ srv_use_native_conditions = TRUE;
}
#endif
+
if (srv_file_flush_method_str == NULL) {
/* These are the default options */
srv_unix_file_flush_method = SRV_UNIX_FSYNC;
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
-#ifndef __WIN__
} else if (0 == ut_strcmp(srv_file_flush_method_str, "fsync")) {
srv_unix_file_flush_method = SRV_UNIX_FSYNC;
@@ -1307,7 +1310,7 @@ innobase_start_or_create_for_mysql(void)
} else if (0 == ut_strcmp(srv_file_flush_method_str, "nosync")) {
srv_unix_file_flush_method = SRV_UNIX_NOSYNC;
-#else
+#ifdef _WIN32
} else if (0 == ut_strcmp(srv_file_flush_method_str, "normal")) {
srv_win_file_flush_method = SRV_WIN_IO_NORMAL;
os_aio_use_native_aio = FALSE;
@@ -1315,16 +1318,10 @@ innobase_start_or_create_for_mysql(void)
} else if (0 == ut_strcmp(srv_file_flush_method_str, "unbuffered")) {
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
os_aio_use_native_aio = FALSE;
-
} else if (0 == ut_strcmp(srv_file_flush_method_str,
"async_unbuffered")) {
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
os_aio_use_native_aio = TRUE;
- srv_n_read_io_threads = srv_n_write_io_threads = 1;
- fprintf(stderr,
- "InnoDB: 'async_unbuffered' was detected as innodb_flush_method.\n"
- "InnoDB: Windows native async i/o is enabled.\n"
- "InnoDB: And io threads are restricted.\n");
#endif
} else {
fprintf(stderr,
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index e98c11f258a..7d3d7481f97 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -1016,6 +1016,7 @@ fi
%attr(755, root, root) %{_bindir}/mysqld_safe
%attr(755, root, root) %{_bindir}/mysqldumpslow
%attr(755, root, root) %{_bindir}/mysqlhotcopy
+%attr(755, root, root) %{_bindir}/mytop
%attr(755, root, root) %{_bindir}/mysqltest
%attr(755, root, root) %{_bindir}/perror
%attr(755, root, root) %{_bindir}/replace
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 2500911bd23..7190ce30135 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -366,7 +366,7 @@ static MYSQL* client_connect(ulong flag, uint protocol, my_bool auto_reconnect)
have_innodb= check_have_innodb(mysql);
if (!opt_silent)
- fprintf(stdout, "OK");
+ fprintf(stdout, "OK\n");
return mysql;
}
@@ -18558,6 +18558,71 @@ static void test_bug56976()
DBUG_VOID_RETURN;
}
+/*
+ Test that CLIENT_PROGRESS works.
+*/
+
+uint progress_stage, progress_max_stage, progress_count;
+
+static void report_progress(const MYSQL *mysql __attribute__((unused)),
+ uint stage, uint max_stage,
+ double progress __attribute__((unused)),
+ const char *proc_info __attribute__((unused)),
+ uint proc_info_length __attribute__((unused)))
+{
+ progress_stage= stage;
+ progress_max_stage= max_stage;
+ progress_count++;
+}
+
+
+static void test_progress_reporting()
+{
+ int rc, i;
+ MYSQL* conn;
+
+ /* Progress reporting doesn't work yet with embedded server */
+ if (embedded_server_arg_count)
+ return;
+
+ myheader("test_progress_reporting");
+
+ conn= client_connect(CLIENT_PROGRESS, MYSQL_PROTOCOL_TCP, 0);
+ DIE_UNLESS(conn->client_flag & CLIENT_PROGRESS);
+
+ mysql_options(conn, MYSQL_PROGRESS_CALLBACK, (void*) report_progress);
+ rc= mysql_query(conn, "set @save=@@global.progress_report_time");
+ myquery(rc);
+ rc= mysql_query(conn, "set @@global.progress_report_time=1");
+ myquery(rc);
+
+ rc= mysql_query(conn, "drop table if exists t1,t2");
+ myquery(rc);
+ rc= mysql_query(conn, "create table t1 (f2 varchar(255)) engine=aria");
+ myquery(rc);
+ rc= mysql_query(conn, "create table t2 like t1");
+ myquery(rc);
+ rc= mysql_query(conn, "insert into t1 (f2) values (repeat('a',100)),(repeat('b',200)),(repeat('c',202)),(repeat('d',202)),(repeat('e',202)),(repeat('f',202)),(repeat('g',23))");
+ myquery(rc);
+ for (i= 0 ; i < 5 ; i++)
+ {
+ rc= mysql_query(conn, "insert into t2 (f2) select f2 from t1");
+ myquery(rc);
+ rc= mysql_query(conn, "insert into t1 (f2) select f2 from t2");
+ myquery(rc);
+ }
+ rc= mysql_query(conn, "alter table t1 add f1 int primary key auto_increment, add key (f2), order by f2");
+ myquery(rc);
+ if (!opt_silent)
+ printf("Got progress_count: %u stage: %u max_stage: %u\n",
+ progress_count, progress_stage, progress_max_stage);
+ DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 3);
+ myquery(rc);
+ rc= mysql_query(conn, "set @@global.progress_report_time=@save");
+ myquery(rc);
+ client_disconnect(conn, 0);
+}
+
/*
Read and parse arguments and MySQL options from my.cnf
@@ -18886,6 +18951,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug47485", test_bug47485 },
{ "test_bug58036", test_bug58036 },
{ "test_bug56976", test_bug56976 },
+ { "test_progress_reporting", test_progress_reporting },
{ 0, 0 }
};
diff --git a/unittest/mysys/lf-t.c b/unittest/mysys/lf-t.c
index 61b7ae08cf5..29de0a0e812 100644
--- a/unittest/mysys/lf-t.c
+++ b/unittest/mysys/lf-t.c
@@ -33,14 +33,13 @@ LF_HASH lf_hash;
pthread_handler_t test_lf_pinbox(void *arg)
{
int m= *(int *)arg;
- int32 x= 0;
LF_PINS *pins;
my_thread_init();
pins= lf_pinbox_get_pins(&lf_allocator.pinbox);
- for (x= ((int)(intptr)(&m)); m ; m--)
+ for (; m ; m--)
{
lf_pinbox_put_pins(pins);
pins= lf_pinbox_get_pins(&lf_allocator.pinbox);
diff --git a/unittest/mysys/ma_dyncol-t.c b/unittest/mysys/ma_dyncol-t.c
index 0e973b20747..11731ae81d4 100644
--- a/unittest/mysys/ma_dyncol-t.c
+++ b/unittest/mysys/ma_dyncol-t.c
@@ -61,7 +61,7 @@ void test_value_single_uint(ulonglong num, const char *name)
DYNAMIC_COLUMN str;
/* init values */
val.type= DYN_COL_UINT;
- val.ulong_value= num;
+ val.x.ulong_value= num;
dynamic_column_value_init(&res);
/* create column */
if (dynamic_column_create(&str, 1, &val))
@@ -70,8 +70,8 @@ void test_value_single_uint(ulonglong num, const char *name)
/* read column */
if (dynamic_column_get(&str, 1, &res))
goto err;
- rc= (res.type == DYN_COL_UINT) && (res.ulong_value == num);
- num= res.ulong_value;
+ rc= (res.type == DYN_COL_UINT) && (res.x.ulong_value == num);
+ num= res.x.ulong_value;
err:
ok(rc, "%s - %llu", name, num);
/* cleanup */
@@ -85,7 +85,7 @@ void test_value_single_sint(longlong num, const char *name)
DYNAMIC_COLUMN str;
/* init values */
val.type= DYN_COL_INT;
- val.long_value= num;
+ val.x.long_value= num;
dynamic_column_value_init(&res);
/* create column */
if (dynamic_column_create(&str, 1, &val))
@@ -94,8 +94,8 @@ void test_value_single_sint(longlong num, const char *name)
/* read column */
if (dynamic_column_get(&str, 1, &res))
goto err;
- rc= (res.type == DYN_COL_INT) && (res.long_value == num);
- num= res.ulong_value;
+ rc= (res.type == DYN_COL_INT) && (res.x.long_value == num);
+ num= res.x.ulong_value;
err:
ok(rc, "%s - %lld", name, num);
/* cleanup */
@@ -110,7 +110,7 @@ void test_value_single_double(double num, const char *name)
DYNAMIC_COLUMN str;
/* init values */
val.type= DYN_COL_DOUBLE;
- val.double_value= num;
+ val.x.double_value= num;
dynamic_column_value_init(&res);
/* create column */
if (dynamic_column_create(&str, 1, &val))
@@ -119,8 +119,8 @@ void test_value_single_double(double num, const char *name)
/* read column */
if (dynamic_column_get(&str, 1, &res))
goto err;
- rc= (res.type == DYN_COL_DOUBLE) && (res.double_value == num);
- num= res.ulong_value;
+ rc= (res.type == DYN_COL_DOUBLE) && (res.x.double_value == num);
+ num= res.x.ulong_value;
err:
ok(rc, "%s - %lf", name, num);
/* cleanup */
@@ -138,7 +138,7 @@ void test_value_single_decimal(const char *num)
/* init values */
dynamic_column_prepare_decimal(&val); // special procedure for decimal!!!
- if (string2decimal(num, &val.decimal_value, &end) != E_DEC_OK)
+ if (string2decimal(num, &val.x.decimal.value, &end) != E_DEC_OK)
goto err;
dynamic_column_value_init(&res);
@@ -150,8 +150,8 @@ void test_value_single_decimal(const char *num)
if (dynamic_column_get(&str, 1, &res))
goto err;
rc= ((res.type == DYN_COL_DECIMAL) &&
- (decimal_cmp(&res.decimal_value, &val.decimal_value) == 0));
- decimal2string(&res.decimal_value, buff, &length, 0, 0, ' ');
+ (decimal_cmp(&res.x.decimal.value, &val.x.decimal.value) == 0));
+ decimal2string(&res.x.decimal.value, buff, &length, 0, 0, ' ');
err:
ok(rc, "%s - %s", num, buff);
/* cleanup */
@@ -211,9 +211,9 @@ void test_value_single_string(const char *string, size_t len,
/* init values */
val.type= DYN_COL_STRING;
- val.string_value.str= (char*)string;
- val.string_value.length= len;
- val.charset= cs;
+ val.x.string.value.str= (char*)string;
+ val.x.string.value.length= len;
+ val.x.string.charset= cs;
dynamic_column_value_init(&res);
/* create column */
@@ -224,15 +224,15 @@ void test_value_single_string(const char *string, size_t len,
if (dynamic_column_get(&str, 1, &res))
goto err;
rc= ((res.type == DYN_COL_STRING) &&
- (res.string_value.length == len) &&
- (memcmp(res.string_value.str, string, len) == 0) &&
- (res.charset->number == cs->number));
+ (res.x.string.value.length == len) &&
+ (memcmp(res.x.string.value.str, string, len) == 0) &&
+ (res.x.string.charset->number == cs->number));
err:
ok(rc, "'%s' - '%s' %u %u-%s", string,
- res.string_value.str, (uint)res.string_value.length,
- (uint)res.charset->number, res.charset->name);
+ res.x.string.value.str, (uint)res.x.string.value.length,
+ (uint)res.x.string.charset->number, res.x.string.charset->name);
/* cleanup */
- val.string_value.str= NULL; // we did not allocated it
+ val.x.string.value.str= NULL; // we did not allocated it
dynamic_column_column_free(&str);
}
@@ -243,10 +243,10 @@ void test_value_single_date(uint year, uint month, uint day, const char *name)
DYNAMIC_COLUMN str;
/* init values */
val.type= DYN_COL_DATE;
- val.time_value.time_type= MYSQL_TIMESTAMP_DATE;
- val.time_value.year= year;
- val.time_value.month= month;
- val.time_value.day= day;
+ val.x.time_value.time_type= MYSQL_TIMESTAMP_DATE;
+ val.x.time_value.year= year;
+ val.x.time_value.month= month;
+ val.x.time_value.day= day;
dynamic_column_value_init(&res);
/* create column */
if (dynamic_column_create(&str, 1, &val))
@@ -256,10 +256,10 @@ void test_value_single_date(uint year, uint month, uint day, const char *name)
if (dynamic_column_get(&str, 1, &res))
goto err;
rc= ((res.type == DYN_COL_DATE) &&
- (res.time_value.time_type == MYSQL_TIMESTAMP_DATE) &&
- (res.time_value.year == year) &&
- (res.time_value.month == month) &&
- (res.time_value.day == day));
+ (res.x.time_value.time_type == MYSQL_TIMESTAMP_DATE) &&
+ (res.x.time_value.year == year) &&
+ (res.x.time_value.month == month) &&
+ (res.x.time_value.day == day));
err:
ok(rc, "%s - %04u-%02u-%02u", name, year, month, day);
/* cleanup */
@@ -274,12 +274,12 @@ void test_value_single_time(uint neg, uint hour, uint minute, uint second,
DYNAMIC_COLUMN str;
/* init values */
val.type= DYN_COL_TIME;
- val.time_value.time_type= MYSQL_TIMESTAMP_TIME;
- val.time_value.neg= neg;
- val.time_value.hour= hour;
- val.time_value.minute= minute;
- val.time_value.second= second;
- val.time_value.second_part= mic;
+ val.x.time_value.time_type= MYSQL_TIMESTAMP_TIME;
+ val.x.time_value.neg= neg;
+ val.x.time_value.hour= hour;
+ val.x.time_value.minute= minute;
+ val.x.time_value.second= second;
+ val.x.time_value.second_part= mic;
dynamic_column_value_init(&res);
/* create column */
if (dynamic_column_create(&str, 1, &val))
@@ -289,12 +289,12 @@ void test_value_single_time(uint neg, uint hour, uint minute, uint second,
if (dynamic_column_get(&str, 1, &res))
goto err;
rc= ((res.type == DYN_COL_TIME) &&
- (res.time_value.time_type == MYSQL_TIMESTAMP_TIME) &&
- (res.time_value.neg == (int)neg) &&
- (res.time_value.hour == hour) &&
- (res.time_value.minute == minute) &&
- (res.time_value.second == second) &&
- (res.time_value.second_part == mic));
+ (res.x.time_value.time_type == MYSQL_TIMESTAMP_TIME) &&
+ (res.x.time_value.neg == (int)neg) &&
+ (res.x.time_value.hour == hour) &&
+ (res.x.time_value.minute == minute) &&
+ (res.x.time_value.second == second) &&
+ (res.x.time_value.second_part == mic));
err:
ok(rc, "%s - %c%02u:%02u:%02u.%06u", name, (neg ? '-' : '+'),
hour, minute, second, mic);
@@ -312,15 +312,15 @@ void test_value_single_datetime(uint neg, uint year, uint month, uint day,
DYNAMIC_COLUMN str;
/* init values */
val.type= DYN_COL_DATETIME;
- val.time_value.time_type= MYSQL_TIMESTAMP_DATETIME;
- val.time_value.neg= neg;
- val.time_value.year= year;
- val.time_value.month= month;
- val.time_value.day= day;
- val.time_value.hour= hour;
- val.time_value.minute= minute;
- val.time_value.second= second;
- val.time_value.second_part= mic;
+ val.x.time_value.time_type= MYSQL_TIMESTAMP_DATETIME;
+ val.x.time_value.neg= neg;
+ val.x.time_value.year= year;
+ val.x.time_value.month= month;
+ val.x.time_value.day= day;
+ val.x.time_value.hour= hour;
+ val.x.time_value.minute= minute;
+ val.x.time_value.second= second;
+ val.x.time_value.second_part= mic;
dynamic_column_value_init(&res);
/* create column */
if (dynamic_column_create(&str, 1, &val))
@@ -330,15 +330,15 @@ void test_value_single_datetime(uint neg, uint year, uint month, uint day,
if (dynamic_column_get(&str, 1, &res))
goto err;
rc= ((res.type == DYN_COL_DATETIME) &&
- (res.time_value.time_type == MYSQL_TIMESTAMP_DATETIME) &&
- (res.time_value.neg == (int)neg) &&
- (res.time_value.year == year) &&
- (res.time_value.month == month) &&
- (res.time_value.day == day) &&
- (res.time_value.hour == hour) &&
- (res.time_value.minute == minute) &&
- (res.time_value.second == second) &&
- (res.time_value.second_part == mic));
+ (res.x.time_value.time_type == MYSQL_TIMESTAMP_DATETIME) &&
+ (res.x.time_value.neg == (int)neg) &&
+ (res.x.time_value.year == year) &&
+ (res.x.time_value.month == month) &&
+ (res.x.time_value.day == day) &&
+ (res.x.time_value.hour == hour) &&
+ (res.x.time_value.minute == minute) &&
+ (res.x.time_value.second == second) &&
+ (res.x.time_value.second_part == mic));
err:
ok(rc, "%s - %c %04u-%02u-%02u %02u:%02u:%02u.%06u", name, (neg ? '-' : '+'),
year, month, day, hour, minute, second, mic);
@@ -368,40 +368,40 @@ void test_value_multi(ulonglong num0,
DYNAMIC_COLUMN str;
/* init values */
val[0].type= DYN_COL_UINT;
- val[0].ulong_value= num0;
+ val[0].x.ulong_value= num0;
val[1].type= DYN_COL_INT;
- val[1].long_value= num1;
+ val[1].x.long_value= num1;
val[2].type= DYN_COL_DOUBLE;
- val[2].double_value= num2;
+ val[2].x.double_value= num2;
dynamic_column_prepare_decimal(val + 3); // special procedure for decimal!!!
- if (string2decimal(num3, &val[3].decimal_value, &end3) != E_DEC_OK)
+ if (string2decimal(num3, &val[3].x.decimal.value, &end3) != E_DEC_OK)
goto err;
val[4].type= DYN_COL_STRING;
- val[4].string_value.str= (char*)string4;
- val[4].string_value.length= len4;
- val[4].charset= cs4;
+ val[4].x.string.value.str= (char*)string4;
+ val[4].x.string.value.length= len4;
+ val[4].x.string.charset= cs4;
val[5].type= DYN_COL_DATE;
- val[5].time_value.time_type= MYSQL_TIMESTAMP_DATE;
- val[5].time_value.year= year5;
- val[5].time_value.month= month5;
- val[5].time_value.day= day5;
+ val[5].x.time_value.time_type= MYSQL_TIMESTAMP_DATE;
+ val[5].x.time_value.year= year5;
+ val[5].x.time_value.month= month5;
+ val[5].x.time_value.day= day5;
val[6].type= DYN_COL_TIME;
- val[6].time_value.time_type= MYSQL_TIMESTAMP_TIME;
- val[6].time_value.neg= neg6;
- val[6].time_value.hour= hour6;
- val[6].time_value.minute= minute6;
- val[6].time_value.second= second6;
- val[6].time_value.second_part= mic6;
+ val[6].x.time_value.time_type= MYSQL_TIMESTAMP_TIME;
+ val[6].x.time_value.neg= neg6;
+ val[6].x.time_value.hour= hour6;
+ val[6].x.time_value.minute= minute6;
+ val[6].x.time_value.second= second6;
+ val[6].x.time_value.second_part= mic6;
val[7].type= DYN_COL_DATETIME;
- val[7].time_value.time_type= MYSQL_TIMESTAMP_DATETIME;
- val[7].time_value.neg= neg7;
- val[7].time_value.year= year7;
- val[7].time_value.month= month7;
- val[7].time_value.day= day7;
- val[7].time_value.hour= hour7;
- val[7].time_value.minute= minute7;
- val[7].time_value.second= second7;
- val[7].time_value.second_part= mic7;
+ val[7].x.time_value.time_type= MYSQL_TIMESTAMP_DATETIME;
+ val[7].x.time_value.neg= neg7;
+ val[7].x.time_value.year= year7;
+ val[7].x.time_value.month= month7;
+ val[7].x.time_value.day= day7;
+ val[7].x.time_value.hour= hour7;
+ val[7].x.time_value.minute= minute7;
+ val[7].x.time_value.second= second7;
+ val[7].x.time_value.second_part= mic7;
val[8].type= DYN_COL_NULL;
for (i= 0; i < 9; i++)
dynamic_column_value_init(res + i);
@@ -414,44 +414,44 @@ void test_value_multi(ulonglong num0,
if (dynamic_column_get(&str, column_numbers[i], res + i))
goto err;
rc= ((res[0].type == DYN_COL_UINT) &&
- (res[0].ulong_value == num0) &&
+ (res[0].x.ulong_value == num0) &&
(res[1].type == DYN_COL_INT) &&
- (res[1].long_value == num1) &&
+ (res[1].x.long_value == num1) &&
(res[2].type == DYN_COL_DOUBLE) &&
- (res[2].double_value == num2) &&
+ (res[2].x.double_value == num2) &&
(res[3].type == DYN_COL_DECIMAL) &&
- (decimal_cmp(&res[3].decimal_value, &val[3].decimal_value) == 0) &&
+ (decimal_cmp(&res[3].x.decimal.value, &val[3].x.decimal.value) == 0) &&
(res[4].type == DYN_COL_STRING) &&
- (res[4].string_value.length == len4) &&
- (memcmp(res[4].string_value.str, string4, len4) == 0) &&
- (res[4].charset->number == cs4->number) &&
+ (res[4].x.string.value.length == len4) &&
+ (memcmp(res[4].x.string.value.str, string4, len4) == 0) &&
+ (res[4].x.string.charset->number == cs4->number) &&
(res[5].type == DYN_COL_DATE) &&
- (res[5].time_value.time_type == MYSQL_TIMESTAMP_DATE) &&
- (res[5].time_value.year == year5) &&
- (res[5].time_value.month == month5) &&
- (res[5].time_value.day == day5) &&
+ (res[5].x.time_value.time_type == MYSQL_TIMESTAMP_DATE) &&
+ (res[5].x.time_value.year == year5) &&
+ (res[5].x.time_value.month == month5) &&
+ (res[5].x.time_value.day == day5) &&
(res[6].type == DYN_COL_TIME) &&
- (res[6].time_value.time_type == MYSQL_TIMESTAMP_TIME) &&
- (res[6].time_value.neg == (int)neg6) &&
- (res[6].time_value.hour == hour6) &&
- (res[6].time_value.minute == minute6) &&
- (res[6].time_value.second == second6) &&
- (res[6].time_value.second_part == mic6) &&
+ (res[6].x.time_value.time_type == MYSQL_TIMESTAMP_TIME) &&
+ (res[6].x.time_value.neg == (int)neg6) &&
+ (res[6].x.time_value.hour == hour6) &&
+ (res[6].x.time_value.minute == minute6) &&
+ (res[6].x.time_value.second == second6) &&
+ (res[6].x.time_value.second_part == mic6) &&
(res[7].type == DYN_COL_DATETIME) &&
- (res[7].time_value.time_type == MYSQL_TIMESTAMP_DATETIME) &&
- (res[7].time_value.neg == (int)neg7) &&
- (res[7].time_value.year == year7) &&
- (res[7].time_value.month == month7) &&
- (res[7].time_value.day == day7) &&
- (res[7].time_value.hour == hour7) &&
- (res[7].time_value.minute == minute7) &&
- (res[7].time_value.second == second7) &&
- (res[7].time_value.second_part == mic7) &&
+ (res[7].x.time_value.time_type == MYSQL_TIMESTAMP_DATETIME) &&
+ (res[7].x.time_value.neg == (int)neg7) &&
+ (res[7].x.time_value.year == year7) &&
+ (res[7].x.time_value.month == month7) &&
+ (res[7].x.time_value.day == day7) &&
+ (res[7].x.time_value.hour == hour7) &&
+ (res[7].x.time_value.minute == minute7) &&
+ (res[7].x.time_value.second == second7) &&
+ (res[7].x.time_value.second_part == mic7) &&
(res[8].type == DYN_COL_NULL));
err:
ok(rc, "%s", name);
/* cleanup */
- val[4].string_value.str= NULL; // we did not allocated it
+ val[4].x.string.value.str= NULL; // we did not allocated it
dynamic_column_column_free(&str);
}
@@ -486,13 +486,13 @@ void test_update_multi(uint *column_numbers, uint *column_values,
DYNAMIC_COLUMN_VALUE val;
val.type= DYN_COL_UINT;
- val.ulong_value= column_values[0];
+ val.x.ulong_value= column_values[0];
if (dynamic_column_create(&str, column_numbers[0], &val))
goto err;
for (i= 1; i < all; i++)
{
val.type= (null_values[i] ? DYN_COL_NULL : DYN_COL_UINT);
- val.ulong_value= column_values[i];
+ val.x.ulong_value= column_values[i];
if (dynamic_column_update(&str, column_numbers[i], &val))
goto err;
@@ -510,7 +510,7 @@ void test_update_multi(uint *column_numbers, uint *column_values,
else
{
if (val.type != DYN_COL_UINT ||
- val.ulong_value != column_values[j] ||
+ val.x.ulong_value != column_values[j] ||
dynamic_column_exists(&str, column_numbers[j]) == ER_DYNCOL_NO)
goto err;
}
@@ -582,12 +582,12 @@ void test_empty_string()
"%s", "empty list");
val.type= DYN_COL_UINT;
- val.ulong_value= 1212;
+ val.x.ulong_value= 1212;
rc= dynamic_column_update(&str, 1, &val);
if (rc == ER_DYNCOL_OK)
rc= dynamic_column_get(&str, 1, &res);
ok( (rc == ER_DYNCOL_OK) &&
- (res.type == DYN_COL_UINT) && (res.ulong_value == val.ulong_value),
+ (res.type == DYN_COL_UINT) && (res.x.ulong_value == val.x.ulong_value),
"%s", "empty update");
}
@@ -616,7 +616,7 @@ void test_update_many(uint *column_numbers, uint *column_values,
for (i= 0; i < column_count; i++)
{
val[i].type= DYN_COL_UINT;
- val[i].ulong_value= column_values[i];
+ val[i].x.ulong_value= column_values[i];
}
for (i= 0; i < update_count; i++)
{
@@ -625,13 +625,13 @@ void test_update_many(uint *column_numbers, uint *column_values,
else
{
upd[i].type= DYN_COL_UINT;
- upd[i].ulong_value= update_values[i];
+ upd[i].x.ulong_value= update_values[i];
}
}
for (i= 0; i < result_count; i++)
{
res[i].type= DYN_COL_UINT;
- res[i].ulong_value= result_values[i];
+ res[i].x.ulong_value= result_values[i];
}
if (dynamic_column_create_many(&str1, column_count, column_numbers, val))
goto err;
diff --git a/win/README b/win/README
index 916f64913ac..8ae611ec746 100644
--- a/win/README
+++ b/win/README
@@ -51,12 +51,10 @@ win\configure <options>
The options right now are:
- WITH_INNOBASE_STORAGE_ENGINE Enable particular storage engines
- WITH_PARTITION_STORAGE_ENGINE
- WITH_ARCHIVE_STORAGE_ENGINE
- WITH_BLACKHOLE_STORAGE_ENGINE
- WITH_EXAMPLE_STORAGE_ENGINE
- WITH_FEDERATED_STORAGE_ENGINE
+ --with-plugin-XXX Enable particular plugin or plugins
+ --with-plugins=XXX,YYY,...
+ --with-plugins=GROUP GROUP can be, for example, "max" or "max-no-ndb"
+ --without-plugin-XXX Disable particular plugin
__NT__ Enable named pipe support
MYSQL_SERVER_SUFFIX=<suffix> Server suffix, default none
COMPILATION_COMMENT=<comment> Server comment, default "Source distribution"
@@ -70,7 +68,7 @@ The options right now are:
So the command line could look like:
-win\configure WITH_INNOBASE_STORAGE_ENGINE WITH_PARTITION_STORAGE_ENGINE MYSQL_SERVER_SUFFIX=-pro
+win\configure --with-plugin-innobase --with-plugin-partition MYSQL_SERVER_SUFFIX=-pro
Step 6
------
diff --git a/win/cmake/install_macros.cmake b/win/cmake/install_macros.cmake
index e74d064b9a5..a5357204950 100644
--- a/win/cmake/install_macros.cmake
+++ b/win/cmake/install_macros.cmake
@@ -152,7 +152,8 @@ IF(WIN32)
/a /t http://timestamp.verisign.com/scripts/timstamp.dll
CACHE STRING "parameters for signtool (list)")
FIND_PROGRAM(SIGNTOOL_EXECUTABLE signtool
- PATHS "$ENV{ProgramFiles}/Microsoft SDKs/Windows/v7.0A"
+ PATHS "$ENV{ProgramFiles}/Microsoft SDKs/Windows/v7.0A/bin"
+ "$ENV{ProgramFiles}/Windows Kits/8.0/bin/x86"
)
IF(NOT SIGNTOOL_EXECUTABLE)
MESSAGE(FATAL_ERROR
diff --git a/win/configure-mariadb.bat b/win/configure-mariadb.bat
index 6c4283359b4..dc5b59819a3 100644
--- a/win/configure-mariadb.bat
+++ b/win/configure-mariadb.bat
@@ -5,4 +5,5 @@ cscript win\configure.js ^
WITH_PARTITION_STORAGE_ENGINE ^
WITH_ARIA_STORAGE_ENGINE ^
WITH_PBXT_STORAGE_ENGINE ^
- WITH_XTRADB_STORAGE_ENGINE
+ WITH_XTRADB_STORAGE_ENGINE ^
+ WITH_FEEDBACK_STORAGE_ENGINE
diff --git a/win/configure-mariadb.sh b/win/configure-mariadb.sh
index 616d1b790d6..67bfe293639 100644
--- a/win/configure-mariadb.sh
+++ b/win/configure-mariadb.sh
@@ -18,4 +18,5 @@ cscript win/configure.js \
WITH_ARIA_STORAGE_ENGINE \
WITH_PBXT_STORAGE_ENGINE \
WITH_XTRADB_STORAGE_ENGINE \
+ WITH_FEEDBACK_STORAGE_ENGINE \
WITH_EMBEDDED_SERVER
diff --git a/win/configure.js b/win/configure.js
index da7e4c2cd43..43234b39c22 100644
--- a/win/configure.js
+++ b/win/configure.js
@@ -126,7 +126,7 @@ try
var engineOptions = ParsePlugins();
for (option in engineOptions)
{
- configfile.WriteLine("SET(" + engineOptions[option] + " TRUE)");
+ configfile.WriteLine("SET (" + engineOptions[option] + " TRUE)");
}
configfile.Close();
@@ -302,7 +302,7 @@ function ParsePlugins()
{
var content = fso.OpenTextFile(filename, ForReading).ReadAll();
var match =
- /MYSQL_STORAGE_ENGINE([ ]*)[\(]([^\)]+)[\)]/.exec(content);
+ /MYSQL_(PLUGIN|STORAGE_ENGINE)([ ]*)[\(]([^\)]+)[\)]/.exec(content);
if (match== null)
continue;
match = /\[[\w,\-_]+\][\s]?\)/.exec(match[0]);
@@ -329,9 +329,9 @@ function ParsePlugins()
for(key in config)
{
var eng = config[key];
- if(eng.isGroup != undefined && !eng.isGroup && eng.include != undefined)
+ if(eng.isGroup != undefined && !eng.isGroup && eng.include != undefined)
{
- if (fso.FolderExists("storage\\"+key) || key=="PARTITION")
+ if (fso.FolderExists("storage\\"+key) || fso.FolderExists("plugin\\"+key) || key=="PARTITION")
{
arr[arr.length] = eng.include?
"WITH_"+key+"_STORAGE_ENGINE":"WITHOUT_"+key+"_STORAGE_ENGINE";
diff --git a/win/packaging/extra.wxs.in b/win/packaging/extra.wxs.in
index 5aab7bc813c..37b12575328 100644
--- a/win/packaging/extra.wxs.in
+++ b/win/packaging/extra.wxs.in
@@ -49,6 +49,9 @@
<!-- Disable advertised shortcuts weirdness -->
<Property Id="DISABLEADVTSHORTCUTS" Secure="yes" Value="1"/>
+ <!-- Activate feedback plugin-->
+ <Property Id="FEEDBACK" Secure="yes"/>
+
<?if $(var.HaveInnodb) = "1" ?>
<!-- Quick configuration : set default storage engine to innodb, use strict sql_mode -->
<Property Id="STDCONFIG" Secure="yes" Value="1"/>
@@ -57,6 +60,9 @@
<Property Id="BUFFERPOOLSIZE" Secure="yes"/>
+ <CustomAction Id="LaunchUrl" BinaryKey="WixCA" DllEntry="WixShellExec" Execute="immediate" Return="check" Impersonate="yes" />
+
+
<!--
User interface dialogs
-->
@@ -157,6 +163,43 @@
</Control>
<Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
</Dialog>
+
+ <!-- Feedback dialog -->
+ <Dialog Id="Feedback" Width="370" Height="270" Title="[ProductName] Setup" NoMinimize="yes">
+
+ <Control Id="CheckBoxFeedback" Type="CheckBox" X="8" Y="61" Width="360" Height="12" Property="FEEDBACK" CheckBoxValue="1" TabSkip="no">
+ <Text>{\Font1}Enable the Feedback plugin and submit anonymous usage information</Text>
+ </Control>
+
+ <Control Id="Text" Type="Text" X="23" Y="82" Width="290" Height="55">
+ <Text>Monty Program has created a Feedback plugin for MariaDB which, if enabled, collects basic anonymous statistical information. This information is used by the developers to improve MariaDB. Enabling this plugin is an easy way to help with MariaDB development. Collected statistics, and more information on the plugin, can be viewed at http://mariadb.org/feedback_plugin </Text>
+ </Control>
+
+ <Control Id="MoreInfo" Type="PushButton" X="23" Y="140" Width="56" Height="17" Text="More Info" ToolTip="http://mariadb.org/feedback_plugin" >
+ <Publish Property="WixShellExecTarget" Value="http://mariadb.org/feedback_plugin" Order="1">1</Publish>
+ <Publish Event="DoAction" Value="LaunchUrl" Order="2">1</Publish>
+ </Control>
+
+
+ <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="&amp;Back">
+ <Publish Event="NewDialog" Value="ServicePortDlg">1</Publish>
+ </Control>
+ <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Text="&amp;Next">
+ <Publish Event="NewDialog" Value="VerifyReadyDlg">1</Publish>
+ </Control>
+ <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="Cancel">
+ <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
+ </Control>
+ <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="WixUI_Bmp_Banner" />
+ <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>Submit usage information</Text>
+ </Control>
+ <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="0" />
+ <Control Id="Title" Type="Text" X="15" Y="6" Width="200" Height="15" Transparent="yes" NoPrefix="yes">
+ <Text>{\WixUI_Font_Title}[ProductName] setup</Text>
+ </Control>
+ <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
+ </Dialog>
<!-- Error popup dialog -->
<Dialog Id="WarningDlg" Width="320" Height="85" Title="[ProductName] Setup" NoMinimize="yes">
@@ -320,7 +363,7 @@
</Publish>
<Publish Event="DoAction" Value="CheckDatabaseProperties">NOT WarningText</Publish>
<Publish Event="SpawnDialog" Value="WarningDlg">WarningText</Publish>
- <Publish Event="NewDialog" Value="VerifyReadyDlg">Not WarningText</Publish>
+ <Publish Event="NewDialog" Value="Feedback">Not WarningText</Publish>
</Control>
<Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="no" Text="Cancel">
<Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
@@ -350,7 +393,7 @@
NOT Installed AND UpgradableServiceFound
</Publish>
- <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="ServicePortDlg" Order="3" ><![CDATA[&DBInstance=3 AND NOT !DBInstance=3]]></Publish>
+ <Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="Feedback" Order="3" ><![CDATA[&DBInstance=3 AND NOT !DBInstance=3]]></Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="3"> <![CDATA[OLDERVERSIONBEINGUPGRADED <>""]]></Publish>
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="ConfirmDataCleanupDlg" Order="1" ><![CDATA[(&DBInstance=2) AND (!DBInstance=3)]]></Publish>
@@ -460,6 +503,21 @@
Value="[LOGFILESIZE]M" />
</Component>
<?endif?>
+
+ <Component Id="C.feedback" Guid="*" Directory="DATADIR">
+ <Condition>FEEDBACK</Condition>
+ <RegistryValue Root='HKLM'
+ Key='SOFTWARE\@MANUFACTURER@\@CPACK_WIX_PACKAGE_NAME@'
+ Name='FEEDBACK' Value='1' Type='string' KeyPath='yes'/>
+ <IniFile Id="Ini5"
+ Action="createLine"
+ Directory="DATADIR"
+ Section="mysqld"
+ Name="my.ini"
+ Key="feedback"
+ Value="ON" />
+ </Component>
+
<!--- Grant service account permission to the database folder (Windows 7 and later) -->
<Component Id="C.serviceaccount.permission" Guid="*" Directory='DATADIR' Transitive='yes'>
<Condition><![CDATA[SERVICENAME AND (VersionNT > 600)]]></Condition>