summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2011-11-22 18:04:38 +0100
committerSergei Golubchik <sergii@pisem.net>2011-11-22 18:04:38 +0100
commitd2755a2c9c109ddb4e2e0c9feda89431a6c4fd50 (patch)
treec6e4678908c750d7f558e98cedc349aa1d350892
parentaf32b02c06f32a89dc9f52e556bc5dd3bf49c19e (diff)
parent42221abaed700f6dc5d280b462755851780e8487 (diff)
downloadmariadb-git-d2755a2c9c109ddb4e2e0c9feda89431a6c4fd50.tar.gz
5.3->5.5 merge
-rw-r--r--.bzrignore12
-rw-r--r--client/mysql.cc4
-rw-r--r--client/mysqlbinlog.cc12
-rw-r--r--client/mysqltest.cc3
-rw-r--r--configure.cmake1
-rw-r--r--include/ma_dyncol.h12
-rw-r--r--include/maria.h2
-rw-r--r--include/my_bitmap.h4
-rw-r--r--include/my_compare.h5
-rw-r--r--include/my_sys.h5
-rw-r--r--include/myisam.h2
-rw-r--r--include/myisamchk.h2
-rw-r--r--include/mysql.h.pp4
-rw-r--r--include/mysql_com.h11
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_annotate.test12
-rw-r--r--mysql-test/extra/rpl_tests/rpl_row_func003.test3
-rw-r--r--mysql-test/include/default_mysqld.cnf2
-rw-r--r--mysql-test/include/icp_tests.inc490
-rw-r--r--mysql-test/include/mysqld--help.inc2
-rwxr-xr-xmysql-test/lib/v1/mysql-test-run.pl14
-rwxr-xr-xmysql-test/mysql-test-run.pl29
-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/compare.result2
-rw-r--r--mysql-test/r/derived.result4
-rw-r--r--mysql-test/r/derived_view.result631
-rw-r--r--mysql-test/r/dyncol.result4
-rw-r--r--mysql-test/r/explain.result12
-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.result9
-rw-r--r--mysql-test/r/func_in.result21
-rw-r--r--mysql-test/r/func_time.result4
-rw-r--r--mysql-test/r/group_by.result27
-rw-r--r--mysql-test/r/group_min_max.result6
-rw-r--r--mysql-test/r/index_merge_myisam.result20
-rw-r--r--mysql-test/r/information_schema_all_engines.result10
-rw-r--r--mysql-test/r/innodb_bug878769.result57
-rw-r--r--mysql-test/r/innodb_icp.result476
-rw-r--r--mysql-test/r/join.result8
-rw-r--r--mysql-test/r/join_cache.result252
-rw-r--r--mysql-test/r/join_nested.result64
-rw-r--r--mysql-test/r/join_nested_jcl6.result85
-rw-r--r--mysql-test/r/join_outer.result59
-rw-r--r--mysql-test/r/join_outer_jcl6.result59
-rw-r--r--mysql-test/r/kill.result25
-rw-r--r--mysql-test/r/maria_icp.result482
-rw-r--r--mysql-test/r/maria_mrr.result17
-rw-r--r--mysql-test/r/mrr_icp_extra.result9
-rw-r--r--mysql-test/r/myisam.result26
-rw-r--r--mysql-test/r/myisam_icp.result543
-rw-r--r--mysql-test/r/myisam_mrr.result61
-rw-r--r--mysql-test/r/mysql.result10
-rw-r--r--mysql-test/r/mysqld--help-notwin.result14
-rw-r--r--mysql-test/r/optimizer_switch_eng_cond_pushdown1.result5
-rw-r--r--mysql-test/r/optimizer_switch_eng_cond_pushdown2.result5
-rw-r--r--mysql-test/r/order_by.result7
-rw-r--r--mysql-test/r/partition_pruning.result5
-rw-r--r--mysql-test/r/ps_ddl.result12
-rw-r--r--mysql-test/r/range.result14
-rw-r--r--mysql-test/r/range_mrr_icp.result22
-rw-r--r--mysql-test/r/range_vs_index_merge.result37
-rw-r--r--mysql-test/r/range_vs_index_merge_innodb.result37
-rw-r--r--mysql-test/r/select.result3
-rw-r--r--mysql-test/r/select_jcl6.result5
-rw-r--r--mysql-test/r/select_pkeycache.result3
-rw-r--r--mysql-test/r/select_safe.result6
-rw-r--r--mysql-test/r/subselect.result454
-rw-r--r--mysql-test/r/subselect2.result12
-rw-r--r--mysql-test/r/subselect3.result92
-rw-r--r--mysql-test/r/subselect3_jcl6.result86
-rw-r--r--mysql-test/r/subselect4.result113
-rw-r--r--mysql-test/r/subselect_cache.result27
-rw-r--r--mysql-test/r/subselect_extra.result167
-rw-r--r--mysql-test/r/subselect_extra_no_semijoin.result484
-rw-r--r--mysql-test/r/subselect_innodb.result58
-rw-r--r--mysql-test/r/subselect_mat.result320
-rw-r--r--mysql-test/r/subselect_mat_cost.result15
-rw-r--r--mysql-test/r/subselect_mat_cost_bugs.result75
-rw-r--r--mysql-test/r/subselect_no_mat.result454
-rw-r--r--mysql-test/r/subselect_no_opts.result416
-rw-r--r--mysql-test/r/subselect_no_scache.result (renamed from mysql-test/r/subselect_scache.result)460
-rw-r--r--mysql-test/r/subselect_no_semijoin.result470
-rw-r--r--mysql-test/r/subselect_nulls.result3
-rw-r--r--mysql-test/r/subselect_partial_match.result634
-rw-r--r--mysql-test/r/subselect_sj.result353
-rw-r--r--mysql-test/r/subselect_sj2.result135
-rw-r--r--mysql-test/r/subselect_sj2_jcl6.result137
-rw-r--r--mysql-test/r/subselect_sj2_mat.result147
-rw-r--r--mysql-test/r/subselect_sj_jcl6.result329
-rw-r--r--mysql-test/r/subselect_sj_mat.result218
-rw-r--r--mysql-test/r/system_mysql_db.result2
-rw-r--r--mysql-test/r/table_elim.result22
-rw-r--r--mysql-test/r/trigger.result20
-rw-r--r--mysql-test/r/type_datetime.result22
-rw-r--r--mysql-test/r/user_limits.result37
-rw-r--r--mysql-test/r/variables.result5
-rw-r--r--mysql-test/r/view.result24
-rw-r--r--mysql-test/r/xtradb_mrr.result5
-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/r/innodb_func_view.result18
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_mysql.result4
-rw-r--r--mysql-test/suite/funcs_1/r/memory_func_view.result18
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_func_view.result18
-rw-r--r--mysql-test/suite/innodb/r/innodb.result2
-rw-r--r--mysql-test/suite/innodb/t/innodb.test1
-rw-r--r--mysql-test/suite/maria/r/maria.result31
-rw-r--r--mysql-test/suite/maria/r/maria3.result1
-rw-r--r--mysql-test/suite/maria/t/maria.test3
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug45219.result21
-rw-r--r--mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result12
-rw-r--r--mysql-test/suite/parts/r/partition_repair_myisam.result1
-rw-r--r--mysql-test/suite/pbxt/r/derived.result4
-rw-r--r--mysql-test/suite/pbxt/r/func_in.result6
-rw-r--r--mysql-test/suite/pbxt/r/group_by.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/mysqlshow.result4
-rw-r--r--mysql-test/suite/pbxt/r/subselect.result132
-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/mysqlshow.test2
-rw-r--r--mysql-test/suite/pbxt/t/subselect.test5
-rw-r--r--mysql-test/suite/perfschema/r/pfs_upgrade.result10
-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_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/sys_vars/r/aria_checkpoint_log_activity_basic.result43
-rw-r--r--mysql-test/suite/sys_vars/r/binlog_annotate_row_events_basic.result50
-rw-r--r--mysql-test/suite/sys_vars/r/binlog_annotate_rows_events_basic.result50
-rw-r--r--mysql-test/suite/sys_vars/r/debug_binlog_fsync_sleep_basic.result41
-rw-r--r--mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result22
-rw-r--r--mysql-test/suite/sys_vars/r/max_user_connections-2.result2
-rw-r--r--mysql-test/suite/sys_vars/r/max_user_connections_basic.result22
-rw-r--r--mysql-test/suite/sys_vars/r/max_user_connections_func.result14
-rw-r--r--mysql-test/suite/sys_vars/r/optimizer_switch_basic.result16
-rw-r--r--mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown1.result5
-rw-r--r--mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown2.result5
-rw-r--r--mysql-test/suite/sys_vars/r/replicate_annotate_row_events_basic.result21
-rw-r--r--mysql-test/suite/sys_vars/r/replicate_annotate_rows_events_basic.result21
-rw-r--r--mysql-test/suite/sys_vars/t/aria_checkpoint_log_activity_basic.test43
-rw-r--r--mysql-test/suite/sys_vars/t/binlog_annotate_row_events_basic.test39
-rw-r--r--mysql-test/suite/sys_vars/t/binlog_annotate_rows_events_basic.test39
-rw-r--r--mysql-test/suite/sys_vars/t/binlog_dbug_fsync_sleep_basic.test48
-rw-r--r--mysql-test/suite/sys_vars/t/debug_binlog_fsync_sleep_basic.test42
-rw-r--r--mysql-test/suite/sys_vars/t/max_user_connections-2.test11
-rw-r--r--mysql-test/suite/sys_vars/t/max_user_connections_basic-master.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/max_user_connections_basic.test4
-rw-r--r--mysql-test/suite/sys_vars/t/max_user_connections_func-master.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/max_user_connections_func.test27
-rw-r--r--mysql-test/suite/sys_vars/t/optimizer_switch_eng_cond_pushdown1-master.opt (renamed from mysql-test/t/optimizer_switch_eng_cond_pushdown1-master.opt)0
-rw-r--r--mysql-test/suite/sys_vars/t/optimizer_switch_eng_cond_pushdown1.test (renamed from mysql-test/t/optimizer_switch_eng_cond_pushdown1.test)0
-rw-r--r--mysql-test/suite/sys_vars/t/optimizer_switch_eng_cond_pushdown2-master.opt (renamed from mysql-test/t/optimizer_switch_eng_cond_pushdown2-master.opt)0
-rw-r--r--mysql-test/suite/sys_vars/t/optimizer_switch_eng_cond_pushdown2.test (renamed from mysql-test/t/optimizer_switch_eng_cond_pushdown2.test)0
-rw-r--r--mysql-test/suite/sys_vars/t/replicate_annotate_row_events_basic.test23
-rw-r--r--mysql-test/suite/sys_vars/t/replicate_annotate_rows_events_basic.test23
-rw-r--r--mysql-test/suite/vcol/r/vcol_misc.result3
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_innodb.result8
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_myisam.result8
-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_view.test482
-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.test23
-rw-r--r--mysql-test/t/fulltext.test2
-rw-r--r--mysql-test/t/fulltext_plugin.test2
-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.test17
-rw-r--r--mysql-test/t/index_merge_myisam.test24
-rw-r--r--mysql-test/t/innodb_bug878769.test56
-rw-r--r--mysql-test/t/join.test10
-rw-r--r--mysql-test/t/join_cache.test143
-rw-r--r--mysql-test/t/join_nested.test25
-rw-r--r--mysql-test/t/join_nested_jcl6.test9
-rw-r--r--mysql-test/t/join_outer.test55
-rw-r--r--mysql-test/t/kill.test30
-rw-r--r--mysql-test/t/maria_mrr.test11
-rw-r--r--mysql-test/t/mrr_icp_extra.test1
-rw-r--r--mysql-test/t/myisam.test8
-rw-r--r--mysql-test/t/myisam_icp.test52
-rw-r--r--mysql-test/t/myisam_mrr.test51
-rw-r--r--mysql-test/t/mysql.test9
-rw-r--r--mysql-test/t/order_by.test1
-rw-r--r--mysql-test/t/partition_pruning.test1
-rw-r--r--mysql-test/t/range.test12
-rwxr-xr-xmysql-test/t/range_vs_index_merge.test29
-rw-r--r--mysql-test/t/select.test1
-rw-r--r--mysql-test/t/select_safe.test2
-rw-r--r--mysql-test/t/subselect.test229
-rw-r--r--mysql-test/t/subselect3.test49
-rw-r--r--mysql-test/t/subselect4.test97
-rw-r--r--mysql-test/t/subselect_cache.test30
-rw-r--r--mysql-test/t/subselect_extra.test123
-rw-r--r--mysql-test/t/subselect_extra_no_semijoin.test9
-rw-r--r--mysql-test/t/subselect_innodb.test60
-rw-r--r--mysql-test/t/subselect_mat.test28
-rw-r--r--mysql-test/t/subselect_mat_cost-master.opt1
-rw-r--r--mysql-test/t/subselect_mat_cost.test11
-rw-r--r--mysql-test/t/subselect_mat_cost_bugs.test65
-rw-r--r--mysql-test/t/subselect_no_opts.test2
-rw-r--r--mysql-test/t/subselect_no_scache.test (renamed from mysql-test/t/subselect_scache.test)2
-rw-r--r--mysql-test/t/subselect_nulls.test5
-rw-r--r--mysql-test/t/subselect_partial_match.test455
-rw-r--r--mysql-test/t/subselect_sj.test311
-rw-r--r--mysql-test/t/subselect_sj2.test123
-rw-r--r--mysql-test/t/subselect_sj_jcl6.test2
-rw-r--r--mysql-test/t/subselect_sj_mat.test189
-rw-r--r--mysql-test/t/table_elim.test21
-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-master.opt1
-rw-r--r--mysql-test/t/user_limits.test42
-rw-r--r--mysql-test/t/variables-master.opt1
-rw-r--r--mysql-test/t/variables.test5
-rw-r--r--mysql-test/t/view.test22
-rw-r--r--mysql-test/t/xtradb_mrr.test1
-rw-r--r--mysql-test/valgrind.supp9
-rw-r--r--mysys/ma_dyncol.c129
-rw-r--r--mysys/mf_iocache.c10
-rw-r--r--mysys/my_bitmap.c90
-rw-r--r--mysys/my_gethwaddr.c182
-rw-r--r--mysys/my_getopt.c6
-rw-r--r--mysys/my_init.c1
-rw-r--r--mysys/my_malloc.c6
-rw-r--r--mysys/my_open.c11
-rw-r--r--mysys/my_pread.c34
-rw-r--r--mysys/my_read.c8
-rw-r--r--mysys/my_static.c2
-rw-r--r--mysys/my_write.c11
-rw-r--r--mysys/thr_mutex.c1
-rw-r--r--plugin/feedback/CMakeLists.txt18
-rw-r--r--plugin/feedback/Makefile.am18
-rw-r--r--plugin/feedback/feedback.cc393
-rw-r--r--plugin/feedback/feedback.h67
-rw-r--r--plugin/feedback/plug.in28
-rw-r--r--plugin/feedback/sender_thread.cc305
-rw-r--r--plugin/feedback/url_base.cc51
-rw-r--r--plugin/feedback/url_http.cc307
-rw-r--r--plugin/feedback/utils.cc393
-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
-rw-r--r--scripts/make_binary_distribution.sh1
-rw-r--r--scripts/mysql_system_tables.sql2
-rw-r--r--scripts/mysql_system_tables_fix.sql5
-rw-r--r--sql-bench/crash-me.sh45
-rw-r--r--sql-bench/limits/mysql.cfg27
-rw-r--r--sql-common/my_time.c2
-rw-r--r--sql/debug_sync.cc4
-rw-r--r--sql/event_scheduler.cc2
-rw-r--r--sql/filesort.cc31
-rw-r--r--sql/ha_ndbcluster_binlog.cc2
-rw-r--r--sql/handler.cc15
-rw-r--r--sql/handler.h11
-rw-r--r--sql/item.cc43
-rw-r--r--sql/item.h39
-rw-r--r--sql/item_cmpfunc.cc98
-rw-r--r--sql/item_cmpfunc.h5
-rw-r--r--sql/item_func.cc5
-rw-r--r--sql/item_row.cc2
-rw-r--r--sql/item_strfunc.cc144
-rw-r--r--sql/item_subselect.cc244
-rw-r--r--sql/item_subselect.h123
-rw-r--r--sql/item_sum.cc4
-rw-r--r--sql/item_timefunc.cc8
-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.cc23
-rw-r--r--sql/mysqld.cc112
-rw-r--r--sql/mysqld.h7
-rw-r--r--sql/opt_index_cond_pushdown.cc90
-rw-r--r--sql/opt_range.cc28
-rw-r--r--sql/opt_range.h7
-rw-r--r--sql/opt_subselect.cc296
-rw-r--r--sql/opt_sum.cc4
-rw-r--r--sql/opt_table_elimination.cc4
-rw-r--r--sql/records.cc24
-rw-r--r--sql/records.h2
-rw-r--r--sql/rpl_rli.h8
-rw-r--r--sql/share/errmsg-utf8.txt4
-rw-r--r--sql/slave.cc11
-rw-r--r--sql/slave.h2
-rw-r--r--sql/sp.cc44
-rw-r--r--sql/sp.h28
-rw-r--r--sql/sp_head.cc4
-rw-r--r--sql/sp_head.h11
-rw-r--r--sql/sp_rcontext.cc2
-rw-r--r--sql/sql_acl.cc63
-rw-r--r--sql/sql_base.cc32
-rw-r--r--sql/sql_cache.cc7
-rw-r--r--sql/sql_class.cc119
-rw-r--r--sql/sql_class.h66
-rw-r--r--sql/sql_connect.cc17
-rw-r--r--sql/sql_db.cc1
-rw-r--r--sql/sql_delete.cc16
-rw-r--r--sql/sql_insert.cc28
-rw-r--r--sql/sql_join_cache.cc76
-rw-r--r--sql/sql_lex.cc131
-rw-r--r--sql/sql_lex.h13
-rw-r--r--sql/sql_list.h21
-rw-r--r--sql/sql_load.cc12
-rw-r--r--sql/sql_parse.cc159
-rw-r--r--sql/sql_parse.h2
-rw-r--r--sql/sql_plugin.cc15
-rw-r--r--sql/sql_prepare.cc1
-rw-r--r--sql/sql_priv.h6
-rw-r--r--sql/sql_repl.cc8
-rw-r--r--sql/sql_select.cc327
-rw-r--r--sql/sql_select.h22
-rw-r--r--sql/sql_show.cc18
-rw-r--r--sql/sql_union.cc1
-rw-r--r--sql/sql_update.cc16
-rw-r--r--sql/sql_view.cc2
-rw-r--r--sql/sql_yacc.yy52
-rw-r--r--sql/structs.h9
-rw-r--r--sql/sys_vars.cc40
-rw-r--r--sql/sys_vars.h113
-rw-r--r--sql/table.cc20
-rw-r--r--storage/maria/ha_maria.cc46
-rw-r--r--storage/maria/ha_maria.h1
-rw-r--r--storage/maria/ma_bitmap.c5
-rw-r--r--storage/maria/ma_blockrec.c13
-rw-r--r--storage/maria/ma_check.c19
-rw-r--r--storage/maria/ma_checkpoint.c90
-rw-r--r--storage/maria/ma_create.c2
-rw-r--r--storage/maria/ma_dynrec.c9
-rw-r--r--storage/maria/ma_ft_update.c2
-rw-r--r--storage/maria/ma_info.c6
-rw-r--r--storage/maria/ma_key_recover.c3
-rw-r--r--storage/maria/ma_loghandler.c8
-rw-r--r--storage/maria/ma_open.c4
-rw-r--r--storage/maria/ma_recovery.c6
-rw-r--r--storage/maria/ma_rt_split.c2
-rw-r--r--storage/maria/maria_def.h3
-rw-r--r--storage/maria/maria_pack.c2
-rw-r--r--storage/maria/trnman.c1
-rw-r--r--storage/maria/unittest/CMakeLists.txt1
-rw-r--r--storage/myisam/ha_myisam.cc24
-rw-r--r--storage/myisam/ha_myisam.h2
-rw-r--r--storage/myisam/mi_check.c77
-rw-r--r--storage/myisam/mi_test2.c1
-rw-r--r--storage/myisam/myisamchk.c1
-rw-r--r--storage/myisam/sort.c4
-rw-r--r--storage/ndb/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
-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.cc6
-rw-r--r--storage/pbxt/src/xactlog_xt.cc4
-rw-r--r--storage/sphinx/ha_sphinx.cc2
-rw-r--r--storage/xtradb/btr/btr0cur.c5
-rw-r--r--storage/xtradb/dict/dict0dict.c13
-rw-r--r--storage/xtradb/handler/ha_innodb.cc623
-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/row0mysql.h29
-rw-r--r--storage/xtradb/os/os0file.c4
-rw-r--r--storage/xtradb/row/row0sel.c583
-rw-r--r--unittest/mysys/ma_dyncol-t.c240
-rw-r--r--win/configure-mariadb.bat3
-rw-r--r--win/configure-mariadb.sh1
-rw-r--r--win/packaging/extra.wxs.in62
394 files changed, 17627 insertions, 3353 deletions
diff --git a/.bzrignore b/.bzrignore
index 1c9bb50e800..a2947f9afe3 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -477,8 +477,6 @@ ma_test_recovery.output
make_dist.cmake
Makefile
Makefile.in
-maria_log.00000*
-maria_log_control
MinSizeRel/
MIRRORS
missing
@@ -1065,10 +1063,6 @@ vio/test-sslserver
vio/viotest-ssl
vio/viotest-sslconnect.cpp
vio/viotest.cpp
-win/configure.data
-win/vs71cache.txt
-win/vs8cache.txt
-win/nmake_cache.txt
ylwrap
zlib/*.ds?
sql-bench/test-table-elimination
@@ -1123,7 +1117,6 @@ storage/pbxt/bin/xtstat
libmysqld/sql_expression_cache.cc
mysql-test/mtr_command
scripts/convert-debug-for-diff
-plugin/handler_socket/client/hsclient
client/strings_def.h
libmysql/strings_def.h
libmysql_r/strings_def.h
@@ -1134,3 +1127,8 @@ cmd-line-utils/libedit/emacs.h
mysql-test/collections/default.release
support-files/plugins.files
client/mysql_plugin
+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/client/mysql.cc b/client/mysql.cc
index db6f5b83a1b..5debadee26c 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -46,7 +46,7 @@
#include <locale.h>
#endif
-const char *VER= "15.0";
+const char *VER= "15.1";
/* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024
@@ -2250,7 +2250,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)
{
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 71ebd5d4ab7..4de571b546d 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -116,7 +116,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.
@@ -1040,7 +1040,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
@@ -1348,10 +1348,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}
};
@@ -1827,7 +1827,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);
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 2f12ee7f280..29235dbd234 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -5481,7 +5481,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/configure.cmake b/configure.cmake
index 1a434e91f23..6363a616b41 100644
--- a/configure.cmake
+++ b/configure.cmake
@@ -257,6 +257,7 @@ CHECK_INCLUDE_FILES ("stdlib.h;sys/un.h" HAVE_SYS_UN_H)
CHECK_INCLUDE_FILES (vis.h HAVE_VIS_H)
CHECK_INCLUDE_FILES (wchar.h HAVE_WCHAR_H)
CHECK_INCLUDE_FILES (wctype.h HAVE_WCTYPE_H)
+CHECK_INCLUDE_FILES (sys/sockio.h HAVE_SYS_SOCKIO_H)
IF(HAVE_SYS_STREAM_H)
# Needs sys/stream.h on Solaris
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 08febdb1a40..3ee5b6b9df8 100644
--- a/include/maria.h
+++ b/include/maria.h
@@ -461,6 +461,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_bitmap.h b/include/my_bitmap.h
index 0edda50de05..7b78252ea27 100644
--- a/include/my_bitmap.h
+++ b/include/my_bitmap.h
@@ -55,6 +55,10 @@ extern my_bool bitmap_test_and_clear(MY_BITMAP *map, uint bitmap_bit);
extern my_bool bitmap_fast_test_and_set(MY_BITMAP *map, uint bitmap_bit);
extern my_bool bitmap_union_is_set_all(const MY_BITMAP *map1,
const MY_BITMAP *map2);
+extern my_bool bitmap_exists_intersection(const MY_BITMAP **bitmap_array,
+ uint bitmap_count,
+ uint start_bit, uint end_bit);
+
extern uint bitmap_set_next(MY_BITMAP *map);
extern uint bitmap_get_first(const MY_BITMAP *map);
extern uint bitmap_get_first_set(const MY_BITMAP *map);
diff --git a/include/my_compare.h b/include/my_compare.h
index 39186e40a15..b47eb65199e 100644
--- a/include/my_compare.h
+++ b/include/my_compare.h
@@ -135,6 +135,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
*/
@@ -143,7 +145,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;
typedef ICP_RESULT (*index_cond_func_t)(void *param);
diff --git a/include/my_sys.h b/include/my_sys.h
index ca27e0f76a5..554ee487a4f 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -63,7 +63,6 @@ typedef struct my_aio_result {
#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 8192 /* my_create/delete/rename: sync directory */
#define MY_UNUSED 64 /* Unused (was 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() */
@@ -84,6 +83,7 @@ typedef struct my_aio_result {
#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*/
@@ -233,7 +233,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 */
diff --git a/include/myisam.h b/include/myisam.h
index 9e843e176eb..0aa8fe79c27 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -292,6 +292,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 bd184c75e7e..9478936c748 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;
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index eed977aff50..556ba91c7b9 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
{
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 57e84dc4e08..adba1ba141a 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -428,12 +428,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/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 6b58dc11644..d12b5a3306a 100644
--- a/mysql-test/extra/rpl_tests/rpl_row_func003.test
+++ b/mysql-test/extra/rpl_tests/rpl_row_func003.test
@@ -59,9 +59,6 @@ if (`SELECT UPPER(LEFT('$engine_type', 3)) != 'NDB'`) {
sync_slave_with_master;
connection master;
}
-# Sync master and slave for NDB engine
-let $wait_time= 6;
---source include/wait_for_ndb_to_binlog.inc
# Time to dump the databases and so we can see if they match
diff --git a/mysql-test/include/default_mysqld.cnf b/mysql-test/include/default_mysqld.cnf
index 26587d885c1..0354e375d53 100644
--- a/mysql-test/include/default_mysqld.cnf
+++ b/mysql-test/include/default_mysqld.cnf
@@ -36,6 +36,8 @@ max_heap_table_size= 1M
loose-skip-innodb
loose-skip-pbxt
loose-skip-federated
+loose-skip-feedback
+loose-feedback-user-info= mysql-test
loose-innodb_data_file_path= ibdata1:10M:autoextend
loose-innodb_buffer_pool_size= 8M
diff --git a/mysql-test/include/icp_tests.inc b/mysql-test/include/icp_tests.inc
index 4af8bf9c452..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 #
@@ -227,6 +374,273 @@ 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) ;
@@ -254,3 +668,79 @@ WHERE (6, 234) IN (
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/mysqld--help.inc b/mysql-test/include/mysqld--help.inc
index 84a6c8091a9..346a3a7cb18 100644
--- a/mysql-test/include/mysqld--help.inc
+++ b/mysql-test/include/mysqld--help.inc
@@ -21,7 +21,7 @@ perl;
datadir slave-load-tmpdir tmpdir socket/;
# Plugins which may or may not be there:
- @plugins=qw/innodb ndb archive blackhole federated partition ndbcluster debug temp-pool ssl des-key-file
+ @plugins=qw/innodb ndb archive blackhole federated partition ndbcluster feedback debug temp-pool ssl des-key-file
xtradb thread-concurrency super-large-pages mutex-deadlock-detector null-audit maria aria pbxt oqgraph sphinx/;
# And substitute the content some environment variables with their
diff --git a/mysql-test/lib/v1/mysql-test-run.pl b/mysql-test/lib/v1/mysql-test-run.pl
index b50cdb47a47..61ec3476ed7 100755
--- a/mysql-test/lib/v1/mysql-test-run.pl
+++ b/mysql-test/lib/v1/mysql-test-run.pl
@@ -2349,8 +2349,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/*") )
{
@@ -2409,8 +2412,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 77bc0c42b71..25427b81eff 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -3162,7 +3162,6 @@ sub mysql_server_start($) {
}
if (-d $datadir ) {
- preserve_error_log($mysqld);
mtr_verbose(" - removing '$datadir'");
rmtree($datadir);
}
@@ -3191,7 +3190,6 @@ sub mysql_server_start($) {
unless -d $datadir;
}
- restore_error_log($mysqld);
# Create the servers tmpdir
my $tmpdir= $mysqld->value('tmpdir');
@@ -4537,30 +4535,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.
@@ -4776,6 +4750,8 @@ sub extract_warning_lines ($$) {
qr| entry '.*' ignored in --skip-name-resolve mode|,
qr|mysqld got signal 6|,
qr|Error while setting value 'pool-of-threads' to 'thread_handling'|,
+ qr|Access denied for user|,
+ qr|Aborted connection|,
qr|table.*is full|,
);
@@ -5088,7 +5064,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);
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index 40d900a0389..a95975f1097 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -220,3 +220,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 5e6078c5f39..918122385e9 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
@@ -750,3 +750,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/compare.result b/mysql-test/r/compare.result
index 010c3becdbb..6ee01349022 100644
--- a/mysql-test/r/compare.result
+++ b/mysql-test/r/compare.result
@@ -88,7 +88,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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 #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`a` AS `a`,(select count(0) from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (concat(`test`.`t1`.`b`,`test`.`t1`.`c`) = concat('0',`test`.`t2`.`a`,'01')))) AS `x` from `test`.`t2` order by `test`.`t2`.`a`
+Note 1003 select `test`.`t2`.`a` AS `a`,<expr_cache><`test`.`t2`.`a`>((select count(0) from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t2`.`a`) and (concat(`test`.`t1`.`b`,`test`.`t1`.`c`) = concat('0',`test`.`t2`.`a`,'01'))))) AS `x` from `test`.`t2` order by `test`.`t2`.`a`
DROP TABLE t1,t2;
CREATE TABLE t1 (a TIMESTAMP);
INSERT INTO t1 VALUES (NOW()),(NOW()),(NOW());
diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result
index 575fdbe04b4..0fc7804297c 100644
--- a/mysql-test/r/derived.result
+++ b/mysql-test/r/derived.result
@@ -190,13 +190,13 @@ pla_id test
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> ALL NULL $hj 7 test.m2.matintnum 9 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 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> ALL NULL $hj 7 test.m2.matintnum 9 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 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;
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index 37157162e61..30c4d330e64 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -714,8 +714,8 @@ SELECT t.a FROM t1 LEFT JOIN
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 t3 ALL NULL NULL NULL NULL 2 100.00 Using where
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
@@ -730,8 +730,8 @@ SELECT t.a FROM t1 LEFT JOIN
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 t3 ALL NULL NULL NULL NULL 2 100.00 Using where
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
@@ -749,15 +749,17 @@ 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');
+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 key1 key1 10 test.t1.a,test.t1.a 2
-2 DERIVED t3 ALL NULL NULL NULL NULL 3 Using temporary; Using filesort
+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
@@ -789,11 +791,11 @@ 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 key0 key0 5 func 2 100.00
+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 <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`))))
+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
@@ -997,10 +999,10 @@ 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
-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`.`t2` where <in_optimizer>(0,<exists>(select 0 from dual where (<cache>(0) = 0)))
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t2` semi join (dual) 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
@@ -1010,10 +1012,10 @@ 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
-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`.`t2` where <in_optimizer>(0,<exists>(select 0 from dual where (<cache>(0) = 0)))
+Note 1003 select `test`.`t2`.`a` AS `a`,0 AS `a`,0 AS `b` from `test`.`t2` semi join (dual) where 1
DROP VIEW v1;
DROP TABLE t1,t2;
#
@@ -1024,7 +1026,9 @@ 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);
+('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;
@@ -1085,7 +1089,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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`.`t3` where (not(<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)))))))
+Note 1003 select 6 AS `a`,5 AS `b` from `test`.`t3` 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
@@ -1094,12 +1098,12 @@ 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 t2 system NULL NULL NULL NULL 1 100.00
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`.`t3` where (not(<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)))))))
+Note 1003 select 6 AS `a`,5 AS `b` from `test`.`t3` 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
@@ -1108,12 +1112,12 @@ 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 t2 system NULL NULL NULL NULL 1 100.00
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`.`t3` where (not(<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)))))))
+Note 1003 select 6 AS `a`,5 AS `b` from `test`.`t3` 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;
#
@@ -1153,7 +1157,7 @@ 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
+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
@@ -1173,7 +1177,7 @@ 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
+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
@@ -1272,7 +1276,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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 exists(select 28 from `test`.`t3` where ('j' < `test`.`t1`.`a`))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 28 from `test`.`t3` 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);
@@ -1280,4 +1284,591 @@ 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
+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` 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` 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/dyncol.result b/mysql-test/r/dyncol.result
index 60f9dca0dd7..f4a858c3029 100644
--- a/mysql-test/r/dyncol.result
+++ b/mysql-test/r/dyncol.result
@@ -838,9 +838,7 @@ column_get(column_create(1, "2001021"), 1 as date)
set @@sql_mode="allow_invalid_dates";
select column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as date);
column_get(column_create(1, "2011-02-30 18:46:06.23434" AS CHAR), 1 as date)
-NULL
-Warnings:
-Warning 1292 Truncated incorrect date value: '2011-02-30'
+2011-02-30
select column_get(column_create(1, "0000-00-000" AS CHAR), 1 as date);
column_get(column_create(1, "0000-00-000" AS CHAR), 1 as date)
0000-00-00
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index 048efb039f3..65bc5b22ba8 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -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
@@ -196,16 +196,16 @@ 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
+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
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
+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
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
@@ -225,7 +225,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t1.c' of SELECT #2 was resolved in SELECT #1
-Note 1003 select (select 1 from `test`.`t2` where (`test`.`t2`.`d` = NULL)) AS `(SELECT 1 FROM t2 WHERE d = c)` from dual
+Note 1003 select <expr_cache><NULL>((select 1 from `test`.`t2` where (`test`.`t2`.`d` = NULL))) AS `(SELECT 1 FROM t2 WHERE d = c)` from dual
DROP TABLE t1, t2;
#
# Bug#30302: Tables that were optimized away are printed in the
diff --git a/mysql-test/r/feedback_plugin_install.result b/mysql-test/r/feedback_plugin_install.result
new file mode 100644
index 00000000000..b1b35072a08
--- /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.1
+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..d434d1282c5
--- /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.1
+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..db622cb3f97
--- /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.1
+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 a76abaa4544..c96937fea34 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -505,6 +505,8 @@ Level Code Message
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
@@ -520,15 +522,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 433f8ca6a65..0a1d136b55e 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,
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index 9f98ffbe706..779049f8b4c 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -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
@@ -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_time.result b/mysql-test/r/func_time.result
index c50fbfc7fe0..6e0a0d84115 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 c531c856f8b..7b22b450b62 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -1543,8 +1543,8 @@ id select_type table type possible_keys key key_len ref rows Extra
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
+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;
@@ -1556,8 +1556,8 @@ id select_type table type possible_keys key key_len ref rows Extra
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
+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;
CREATE TABLE t1(
a INT,
@@ -1738,7 +1738,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 No tables used
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select (select `test`.`t1`.`a`) AS `aa`,count(distinct `test`.`t1`.`b`) AS `COUNT(DISTINCT b)` from `test`.`t1` group by ((select `test`.`t1`.`a`) + 0)
+Note 1003 select <expr_cache><`test`.`t1`.`a`>((select `test`.`t1`.`a`)) AS `aa`,count(distinct `test`.`t1`.`b`) AS `COUNT(DISTINCT b)` from `test`.`t1` group by (<expr_cache><`test`.`t1`.`a`>((select `test`.`t1`.`a`)) + 0)
EXPLAIN EXTENDED
SELECT (SELECT t1.a) aa, COUNT(DISTINCT b) FROM t1 GROUP BY -aa;
id select_type table type possible_keys key key_len ref rows filtered Extra
@@ -1746,7 +1746,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 No tables used
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
-Note 1003 select (select `test`.`t1`.`a`) AS `aa`,count(distinct `test`.`t1`.`b`) AS `COUNT(DISTINCT b)` from `test`.`t1` group by -((select `test`.`t1`.`a`))
+Note 1003 select <expr_cache><`test`.`t1`.`a`>((select `test`.`t1`.`a`)) AS `aa`,count(distinct `test`.`t1`.`b`) AS `COUNT(DISTINCT b)` from `test`.`t1` group by -(<expr_cache><`test`.`t1`.`a`>((select `test`.`t1`.`a`)))
# should return only one record
SELECT (SELECT tt.a FROM t1 tt LIMIT 1) aa, COUNT(DISTINCT b) FROM t1
GROUP BY aa;
@@ -1966,3 +1966,18 @@ f1 MIN(f2) MAX(f2)
4 00:25:00 00:25:00
DROP TABLE t1;
#End of test#49771
+#
+# lp: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 3affad5b7de..047ae5e1307 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -1432,7 +1432,7 @@ 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
+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
@@ -1489,7 +1489,7 @@ 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
+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
@@ -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/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result
index 3db268a18b1..00c924988da 100644
--- a/mysql-test/r/index_merge_myisam.result
+++ b/mysql-test/r/index_merge_myisam.result
@@ -1594,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_all_engines.result b/mysql-test/r/information_schema_all_engines.result
index 013d480c8e1..9ea7c947100 100644
--- a/mysql-test/r/information_schema_all_engines.result
+++ b/mysql-test/r/information_schema_all_engines.result
@@ -54,11 +54,11 @@ INNODB_BUFFER_POOL_PAGES_BLOB
INNODB_SYS_TABLES
INNODB_SYS_FIELDS
INNODB_SYS_COLUMNS
-INNODB_TABLE_STATS
INNODB_SYS_STATS
INNODB_SYS_FOREIGN
INNODB_SYS_INDEXES
XTRADB_ADMIN_COMMAND
+INNODB_TABLE_STATS
SELECT t.table_name, c1.column_name
FROM information_schema.tables t
INNER JOIN
@@ -127,11 +127,11 @@ INNODB_BUFFER_POOL_PAGES_BLOB space_id
INNODB_SYS_TABLES SCHEMA
INNODB_SYS_FIELDS INDEX_ID
INNODB_SYS_COLUMNS TABLE_ID
-INNODB_TABLE_STATS table_schema
INNODB_SYS_STATS INDEX_ID
INNODB_SYS_FOREIGN ID
INNODB_SYS_INDEXES INDEX_ID
XTRADB_ADMIN_COMMAND result_message
+INNODB_TABLE_STATS table_schema
SELECT t.table_name, c1.column_name
FROM information_schema.tables t
INNER JOIN
@@ -200,11 +200,11 @@ INNODB_BUFFER_POOL_PAGES_BLOB space_id
INNODB_SYS_TABLES SCHEMA
INNODB_SYS_FIELDS INDEX_ID
INNODB_SYS_COLUMNS TABLE_ID
-INNODB_TABLE_STATS table_schema
INNODB_SYS_STATS INDEX_ID
INNODB_SYS_FOREIGN ID
INNODB_SYS_INDEXES INDEX_ID
XTRADB_ADMIN_COMMAND result_message
+INNODB_TABLE_STATS table_schema
select 1 as f1 from information_schema.tables where "CHARACTER_SETS"=
(select cast(table_name as char) from information_schema.tables
order by table_name limit 1) limit 1;
@@ -340,11 +340,11 @@ Database: information_schema
| INNODB_SYS_TABLES |
| INNODB_SYS_FIELDS |
| INNODB_SYS_COLUMNS |
-| INNODB_TABLE_STATS |
| INNODB_SYS_STATS |
| INNODB_SYS_FOREIGN |
| INNODB_SYS_INDEXES |
| XTRADB_ADMIN_COMMAND |
+| INNODB_TABLE_STATS |
+---------------------------------------+
Database: INFORMATION_SCHEMA
+---------------------------------------+
@@ -403,11 +403,11 @@ Database: INFORMATION_SCHEMA
| INNODB_SYS_TABLES |
| INNODB_SYS_FIELDS |
| INNODB_SYS_COLUMNS |
-| INNODB_TABLE_STATS |
| INNODB_SYS_STATS |
| INNODB_SYS_FOREIGN |
| INNODB_SYS_INDEXES |
| XTRADB_ADMIN_COMMAND |
+| INNODB_TABLE_STATS |
+---------------------------------------+
Wildcard: inf_rmation_schema
+--------------------+
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 6df834168fa..b3b59bcdea6 100644
--- a/mysql-test/r/innodb_icp.result
+++ b/mysql-test/r/innodb_icp.result
@@ -83,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 (
@@ -203,6 +347,260 @@ COUNT(*)
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) ;
@@ -225,5 +623,83 @@ 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/join.result b/mysql-test/r/join.result
index e95ed8c7cf2..0f7f2411c0c 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -1341,3 +1341,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 0e616e259bc..1ef17b0763e 100644
--- a/mysql-test/r/join_cache.result
+++ b/mysql-test/r/join_cache.result
@@ -3037,12 +3037,12 @@ 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
-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 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
@@ -3151,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'
@@ -3176,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
@@ -3566,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
@@ -3613,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
@@ -3968,7 +3986,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
@@ -4003,6 +4023,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
@@ -4117,6 +4138,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;
@@ -4127,55 +4159,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
@@ -4193,7 +4257,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)
@@ -4202,7 +4274,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)
@@ -4214,49 +4286,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
@@ -4323,13 +4401,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 = 256;
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 t1 ALL NULL NULL NULL NULL 36
+1 SIMPLE t2 ALL idx NULL NULL NULL 30 Using where; Using join buffer (flat, BNL 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;
@@ -4356,20 +4439,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
@@ -4379,16 +4469,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
@@ -4419,6 +4510,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,
@@ -4434,6 +4532,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 = 256;
SET SESSION join_cache_level = 4;
EXPLAIN
@@ -4441,8 +4548,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
@@ -4467,19 +4574,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
@@ -4487,6 +4603,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;
#
@@ -4569,6 +4690,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';
@@ -4786,13 +4910,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
@@ -4805,6 +4932,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;
#
@@ -4834,7 +4971,7 @@ 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);
@@ -4929,13 +5066,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;
@@ -4948,17 +5087,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 = 256;
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 ;
@@ -4968,6 +5110,7 @@ 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;
@@ -5006,4 +5149,37 @@ a
0
SET SESSION join_cache_level = DEFAULT;
DROP TABLE t1, t2;
+#
+# Bug #887479: join_cache_level=3 + semijoin=on
+#
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (3914,17), (3710,5), (3888,20);
+CREATE TABLE t2 (c int, KEY (c));
+INSERT INTO t2 VALUES (27), (17), (33), (20), (3), (7), (18), (2);
+SET @tmp887479_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on';
+SET SESSION optimizer_switch='semijoin_with_cache=on';
+SET SESSION join_cache_level=1;
+EXPLAIN
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY t2 ref c c 5 test.t1.b 2 Using index; Start temporary; End temporary
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+a b
+3914 17
+3888 20
+SET SESSION join_cache_level=3;
+EXPLAIN
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+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
+1 PRIMARY t2 hash_index c #hash#c:c 5:5 test.t1.b 8 End temporary; Using join buffer (flat, BNLH join)
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+a b
+3914 17
+3888 20
+SET SESSION join_cache_level = DEFAULT;
+SET optimizer_switch=@tmp887479_optimizer_switch;
+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 bdf650b97bc..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
diff --git a/mysql-test/r/join_nested_jcl6.result b/mysql-test/r/join_nested_jcl6.result
index d11955226ae..ff5a31b599b 100644
--- a/mysql-test/r/join_nested_jcl6.result
+++ b/mysql-test/r/join_nested_jcl6.result
@@ -850,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
@@ -887,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
(
@@ -916,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
@@ -937,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
(
@@ -946,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
@@ -966,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,
@@ -986,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
@@ -1015,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
@@ -1049,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
@@ -1065,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
@@ -1096,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
@@ -1110,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
@@ -1133,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
@@ -1850,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
@@ -1858,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
@@ -1877,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 918ed1f21e6..49ea07c5dff 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -1685,7 +1685,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t3.pk 1 100.00 Using where; Using index
Warnings:
Note 1276 Field or reference 'test.t2.pk' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`pk` AS `pk`,(select (`test`.`t3`.`pk` + if(isnull(`test`.`t4`.`pk`),0,`test`.`t4`.`pk`)) from `test`.`t3` left join `test`.`t4` on((`test`.`t4`.`pk` = `test`.`t3`.`pk`)) where (`test`.`t3`.`pk` = (`test`.`t2`.`pk` + 1000)) limit 1) AS `t` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`pk` = (`test`.`t1`.`pk` + 1000)) and (`test`.`t1`.`pk` > 1000)) group by `test`.`t2`.`pk`
+Note 1003 select `test`.`t2`.`pk` AS `pk`,<expr_cache><`test`.`t2`.`pk`>((select (`test`.`t3`.`pk` + if(isnull(`test`.`t4`.`pk`),0,`test`.`t4`.`pk`)) from `test`.`t3` left join `test`.`t4` on((`test`.`t4`.`pk` = `test`.`t3`.`pk`)) where (`test`.`t3`.`pk` = (`test`.`t2`.`pk` + 1000)) limit 1)) AS `t` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`pk` = (`test`.`t1`.`pk` + 1000)) and (`test`.`t1`.`pk` > 1000)) group by `test`.`t2`.`pk`
select t2.pk,
(select t3.pk+if(isnull(t4.pk),0,t4.pk)
from t3 left join t4 on t4.pk=t3.pk
@@ -1725,6 +1725,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
@@ -1842,3 +1844,58 @@ 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: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: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 69f7052235b..4a53ff636cb 100644
--- a/mysql-test/r/join_outer_jcl6.result
+++ b/mysql-test/r/join_outer_jcl6.result
@@ -1694,7 +1694,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t3.pk 1 100.00 Using where; Using index
Warnings:
Note 1276 Field or reference 'test.t2.pk' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`pk` AS `pk`,(select (`test`.`t3`.`pk` + if(isnull(`test`.`t4`.`pk`),0,`test`.`t4`.`pk`)) from `test`.`t3` left join `test`.`t4` on((`test`.`t4`.`pk` = `test`.`t3`.`pk`)) where (`test`.`t3`.`pk` = (`test`.`t2`.`pk` + 1000)) limit 1) AS `t` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`pk` = (`test`.`t1`.`pk` + 1000)) and (`test`.`t1`.`pk` > 1000)) group by `test`.`t2`.`pk`
+Note 1003 select `test`.`t2`.`pk` AS `pk`,<expr_cache><`test`.`t2`.`pk`>((select (`test`.`t3`.`pk` + if(isnull(`test`.`t4`.`pk`),0,`test`.`t4`.`pk`)) from `test`.`t3` left join `test`.`t4` on((`test`.`t4`.`pk` = `test`.`t3`.`pk`)) where (`test`.`t3`.`pk` = (`test`.`t2`.`pk` + 1000)) limit 1)) AS `t` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`pk` = (`test`.`t1`.`pk` + 1000)) and (`test`.`t1`.`pk` > 1000)) group by `test`.`t2`.`pk`
select t2.pk,
(select t3.pk+if(isnull(t4.pk),0,t4.pk)
from t3 left join t4 on t4.pk=t3.pk
@@ -1734,6 +1734,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
@@ -1851,6 +1853,61 @@ 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: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: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/kill.result b/mysql-test/r/kill.result
index 699c1fc4463..36dd37611c4 100644
--- a/mysql-test/r/kill.result
+++ b/mysql-test/r/kill.result
@@ -161,7 +161,7 @@ SET DEBUG_SYNC = 'RESET';
# Connection: con1.
SET DEBUG_SYNC= 'thread_end SIGNAL con1_end';
KILL @id;
-ERROR 70100: Query execution was interrupted
+ERROR 70100: Connection was killed
SET DEBUG_SYNC= 'now WAIT_FOR con1_end';
# ER_SERVER_SHUTDOWN, CR_SERVER_GONE_ERROR, CR_SERVER_LOST,
# depending on the timing of close of the connection socket
@@ -275,5 +275,28 @@ unlock tables;
# Switching to connection 'default'
drop table t1;
drop table t2;
+#
+# 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 DEBUG_SYNC = 'RESET';
DROP FUNCTION MY_KILL;
diff --git a/mysql-test/r/maria_icp.result b/mysql-test/r/maria_icp.result
index 81bf90f5439..255ec069eb0 100644
--- a/mysql-test/r/maria_icp.result
+++ b/mysql-test/r/maria_icp.result
@@ -83,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 (
@@ -203,6 +347,266 @@ COUNT(*)
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 storage 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 storage 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) ;
@@ -225,5 +629,83 @@ 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 52e8a916003..c94f16ea1fb 100644
--- a/mysql-test/r/maria_mrr.result
+++ b/mysql-test/r/maria_mrr.result
@@ -187,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
@@ -209,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
@@ -349,7 +349,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)
@@ -360,7 +362,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)
@@ -386,11 +388,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;
diff --git a/mysql-test/r/mrr_icp_extra.result b/mysql-test/r/mrr_icp_extra.result
index 9163267d356..5e49fb6e956 100644
--- a/mysql-test/r/mrr_icp_extra.result
+++ b/mysql-test/r/mrr_icp_extra.result
@@ -69,9 +69,10 @@ 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 3 Using index condition; Using filesort
+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
@@ -80,7 +81,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 index condition; Using where; Using filesort
select * from t1 where b=2 or b is null order by a;
a b
3 NULL
@@ -104,7 +105,7 @@ 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 where; Using filesort
+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
@@ -122,7 +123,7 @@ 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; Rowid-ordered scan
+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
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 9b096fe70d3..ad714fdb91b 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 Index_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 Index_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
diff --git a/mysql-test/r/myisam_icp.result b/mysql-test/r/myisam_icp.result
index d3e1114b39c..0426e1bdfba 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 (
@@ -199,6 +345,266 @@ COUNT(*)
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 storage 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 storage 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) ;
@@ -221,8 +627,84 @@ FROM t3 JOIN t4 ON t4.f11 = t3.f10
f11 f10
DROP TABLE t1,t2,t3,t4;
set optimizer_switch= @tmp_778434;
-set @myisam_icp_tmp=@@optimizer_switch;
-set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+#
+# 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
@@ -238,4 +720,61 @@ 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
+Warnings:
+Warning 1292 Truncated incorrect DOUBLE value: 'c'
+Warning 1292 Truncated incorrect DOUBLE value: 'c'
+Warning 1292 Truncated incorrect DOUBLE value: 'c'
+Warning 1292 Truncated incorrect DOUBLE value: 'c'
+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 d3d6366456b..a85fb97fdbc 100644
--- a/mysql-test/r/myisam_mrr.result
+++ b/mysql-test/r/myisam_mrr.result
@@ -188,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
@@ -210,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
@@ -365,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
@@ -488,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
@@ -496,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
@@ -505,9 +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;
-set optimizer_switch= @myisam_mrr_tmp;
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 9923ba03b3d..d43d891da2f 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/mysqld--help-notwin.result b/mysql-test/r/mysqld--help-notwin.result
index 342126fba84..acdee8d8e89 100644
--- a/mysql-test/r/mysqld--help-notwin.result
+++ b/mysql-test/r/mysqld--help-notwin.result
@@ -32,7 +32,7 @@ The following options may be given as the first argument:
--big-tables Allow big result sets by saving all temporary sets on
file (Solves most 'table full' errors)
--bind-address=name IP address to bind to.
- --binlog-annotate-rows-events
+ --binlog-annotate-row-events
Tells the master to annotate RBR events with the
statement that caused these events
--binlog-cache-size=#
@@ -332,7 +332,9 @@ The following options may be given as the first argument:
when binary log is disabled).
--log-tc-size=# Size of transaction coordinator log.
-W, --log-warnings[=#]
- Log some not critical warnings to the general log file
+ Log some not critical warnings to the general log
+ file.Value can be between 0 and 11. Higher values mean
+ more verbosity
--long-query-time=# Log all queries that have taken more than long_query_time
seconds to execute to file. The argument will be treated
as a decimal value with microsecond precision
@@ -606,7 +608,7 @@ The following options may be given as the first argument:
transaction processed
--relay-log-space-limit=#
Maximum space to use for all relay logs
- --replicate-annotate-rows-events
+ --replicate-annotate-row-events
Tells the slave to write annotate rows events recieved
from the master to its own binary log. Ignored if
log_slave_updates is not set
@@ -858,7 +860,7 @@ automatic-sp-privileges TRUE
back-log 50
big-tables FALSE
bind-address (No default value)
-binlog-annotate-rows-events FALSE
+binlog-annotate-row-events FALSE
binlog-cache-size 32768
binlog-checksum NONE
binlog-direct-non-transactional-updates FALSE
@@ -998,7 +1000,7 @@ old-passwords FALSE
old-style-user-limits FALSE
optimizer-prune-level 1
optimizer-search-depth 62
-optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
performance-schema FALSE
performance-schema-events-waits-history-long-size 10000
performance-schema-events-waits-history-size 10
@@ -1040,7 +1042,7 @@ relay-log-info-file relay-log.info
relay-log-purge TRUE
relay-log-recovery FALSE
relay-log-space-limit 0
-replicate-annotate-rows-events FALSE
+replicate-annotate-row-events FALSE
replicate-same-server-id FALSE
report-host (No default value)
report-password (No default value)
diff --git a/mysql-test/r/optimizer_switch_eng_cond_pushdown1.result b/mysql-test/r/optimizer_switch_eng_cond_pushdown1.result
deleted file mode 100644
index afb607e4877..00000000000
--- a/mysql-test/r/optimizer_switch_eng_cond_pushdown1.result
+++ /dev/null
@@ -1,5 +0,0 @@
-select @@session.engine_condition_pushdown,
-@@global.engine_condition_pushdown,
-@@session.optimizer_switch, @@global.optimizer_switch;
-@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-1 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
diff --git a/mysql-test/r/optimizer_switch_eng_cond_pushdown2.result b/mysql-test/r/optimizer_switch_eng_cond_pushdown2.result
deleted file mode 100644
index 813f8b47f6c..00000000000
--- a/mysql-test/r/optimizer_switch_eng_cond_pushdown2.result
+++ /dev/null
@@ -1,5 +0,0 @@
-select @@session.engine_condition_pushdown,
-@@global.engine_condition_pushdown,
-@@session.optimizer_switch, @@global.optimizer_switch;
-@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index 5372ec1ec66..824e6f55ae0 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -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 where; 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 where; 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
@@ -1465,7 +1466,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
diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result
index 3f49bf9cc9e..eb0849e2cad 100644
--- a/mysql-test/r/partition_pruning.result
+++ b/mysql-test/r/partition_pruning.result
@@ -2669,16 +2669,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/ps_ddl.result b/mysql-test/r/ps_ddl.result
index 726579d1595..1b908e1046d 100644
--- a/mysql-test/r/ps_ddl.result
+++ b/mysql-test/r/ps_ddl.result
@@ -1568,12 +1568,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
@@ -1581,12 +1581,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 62f73a712c8..1c6845ef07e 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -698,6 +698,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
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
@@ -705,7 +717,7 @@ 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 where
-1 SIMPLE s ALL OXLEFT NULL NULL NULL 6 Range checked for each record (index map: 0x4)
+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
diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result
index 3ddbc992c27..5966785c7c3 100644
--- a/mysql-test/r/range_mrr_icp.result
+++ b/mysql-test/r/range_mrr_icp.result
@@ -700,6 +700,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
WHERE s.oxrootid = 'd8c4177d09f8b11f5.52725521' AND
@@ -707,7 +719,7 @@ 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 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
@@ -915,7 +927,7 @@ 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; Rowid-ordered scan
+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
@@ -1019,13 +1031,13 @@ 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; Rowid-ordered scan
+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
+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
@@ -1783,7 +1795,7 @@ 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; Rowid-ordered scan
+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
diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result
index 08ede868ed6..f1838bc9aae 100644
--- a/mysql-test/r/range_vs_index_merge.result
+++ b/mysql-test/r/range_vs_index_merge.result
@@ -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 e74d187a416..71a4fcf9690 100644
--- a/mysql-test/r/range_vs_index_merge_innodb.result
+++ b/mysql-test/r/range_vs_index_merge_innodb.result
@@ -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 2a187cb3d8c..5a20057995d 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -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
@@ -4786,7 +4787,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a > UNIX_TIMESTAMP('2009-03-10 00:00:00'
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > 1236639600)
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > <cache>(unix_timestamp('2009-03-10 00:00:00')))
CREATE FUNCTION f1() RETURNS INT DETERMINISTIC
BEGIN
SET @cnt := @cnt + 1;
diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result
index 0451f35dae6..22ad32c23f2 100644
--- a/mysql-test/r/select_jcl6.result
+++ b/mysql-test/r/select_jcl6.result
@@ -2403,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
@@ -3427,7 +3428,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;
SET SQL_MODE='NO_UNSIGNED_SUBTRACTION';
CREATE TABLE t1 (i TINYINT UNSIGNED NOT NULL);
@@ -4795,7 +4796,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a > UNIX_TIMESTAMP('2009-03-10 00:00:00'
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > 1236639600)
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > <cache>(unix_timestamp('2009-03-10 00:00:00')))
CREATE FUNCTION f1() RETURNS INT DETERMINISTIC
BEGIN
SET @cnt := @cnt + 1;
diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result
index 2a187cb3d8c..5a20057995d 100644
--- a/mysql-test/r/select_pkeycache.result
+++ b/mysql-test/r/select_pkeycache.result
@@ -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
@@ -4786,7 +4787,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a > UNIX_TIMESTAMP('2009-03-10 00:00:00'
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > 1236639600)
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` > <cache>(unix_timestamp('2009-03-10 00:00:00')))
CREATE FUNCTION f1() RETURNS INT DETERMINISTIC
BEGIN
SET @cnt := @cnt + 1;
diff --git a/mysql-test/r/select_safe.result b/mysql-test/r/select_safe.result
index d8a5857aeb8..60364b8c4ec 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/subselect.result b/mysql-test/r/subselect.result
index 713b0fcce2e..82b8e740cdc 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -2,7 +2,7 @@ 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");
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=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)
@@ -55,7 +55,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 dual having ((select 1) = 1)
+Note 1003 select 1 AS `1` from dual having (<expr_cache><1>((select 1)) = 1)
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
1
1
@@ -229,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
@@ -275,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`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`)))
+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
@@ -319,7 +319,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 (select 2 from dual 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 <expr_cache><`test`.`t2`.`a`>((select 2 from dual 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));
@@ -337,7 +337,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 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 <expr_cache><`test`.`t6`.`clinic_uq`>(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;
@@ -367,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)
@@ -543,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 = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where multiple equal(1, `test`.`t1`.`numeropost`))))
+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);
@@ -751,7 +757,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 <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 <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)))))
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
id
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
@@ -899,7 +905,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`,<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`,<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`
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;
@@ -914,8 +920,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`,<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`,<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'
@@ -1475,27 +1606,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(<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(<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`
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`
+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`
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`
+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`
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`
+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);
@@ -1508,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`,((select max(NULL) from `test`.`t2`) > `test`.`t3`.`a`)))
+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);
@@ -1516,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`,((select min(NULL) from `test`.`t2`) <= `test`.`t3`.`a`)))
+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
@@ -1527,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`,(<max>(select NULL from `test`.`t2` group by 1) > `test`.`t3`.`a`)))
+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);
@@ -1535,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`,(<min>(select NULL from `test`.`t2` group by 1) <= `test`.`t3`.`a`)))
+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);
@@ -1578,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`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= `test`.`t3`.`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());
@@ -1748,14 +1879,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(<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(<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`))))))))
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))))
+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)))))
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');
@@ -2291,7 +2422,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 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 <expr_cache><`test`.`up`.`a`>(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);
@@ -2762,6 +2893,8 @@ select * from (select max(fld) from t1) as foo;
max(fld)
1
drop table t1;
+set @tmp11867_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin_with_cache=off';
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');
@@ -2832,7 +2965,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`,<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
@@ -2844,8 +2977,9 @@ 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`
+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=@tmp11867_optimizer_switch;
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'));
@@ -4290,7 +4424,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 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 2 AS `2` from `test`.`t1` where exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))
+Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a));
@@ -4302,7 +4436,7 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select 2 AS `2` from `test`.`t1` where exists((select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) union (select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
+Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists((select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) union (select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))))
DROP TABLE t1,t2;
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
@@ -4380,13 +4514,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 <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 <expr_cache><1>(<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))))
+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)))))
DROP TABLE t1;
#
# Bug#45061: Incorrectly market field caused wrong result.
@@ -5506,6 +5640,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: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
@@ -5528,24 +5823,30 @@ ON t2.f10 = t3.f10
f1
DROP TABLE t1,t2,t3;
#
-# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+# 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 ( 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;
+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.
#
@@ -5664,4 +5965,55 @@ id select_type table type possible_keys key key_len ref rows Extra
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: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 67b9ef0a2e9..a7b6e40d9c9 100644
--- a/mysql-test/r/subselect2.result
+++ b/mysql-test/r/subselect2.result
@@ -125,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 t3 ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX CMFLDRPARNT_IDX 35 const 6 Using index condition; Using where
-1 PRIMARY t3 ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX CMFLDRPARNT_IDX 35 test.t3.FOLDERID 1 Using where
-1 PRIMARY t3 ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX CMFLDRPARNT_IDX 35 test.t3.FOLDERID 1 Using where
-1 PRIMARY t3 ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX CMFLDRPARNT_IDX 35 test.t3.FOLDERID 1 Using where
-1 PRIMARY t3 ref PRIMARY,FFOLDERID_IDX,CMFLDRPARNT_IDX CMFLDRPARNT_IDX 35 test.t3.FOLDERID 1 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
+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);
diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result
index c96a25f05e4..501804a0006 100644
--- a/mysql-test/r/subselect3.result
+++ b/mysql-test/r/subselect3.result
@@ -1,6 +1,6 @@
drop table if exists t0, t1, t2, t3, t4, t5, t11, t12, t21, t22;
set @subselect3_tmp= @@optimizer_switch;
-set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on';
create table t1 (oref int, grp int, ie int) ;
insert into t1 (oref, grp, ie) values
(1, 1, 1),
@@ -32,7 +32,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary
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`.`oref` AS `oref`,<in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`))))))) AS `Z` from `test`.`t2`
explain extended
select a, oref from t2
where a in (select max(ie) from t1 where oref=t2.oref group by grp);
@@ -41,7 +41,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary
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`.`oref` AS `oref` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having (<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having (<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`))))))
select a, oref, a in (
select max(ie) from t1 where oref=t2.oref group by grp union
select max(ie) from t1 where oref=t2.oref group by grp
@@ -72,7 +72,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary
Warnings:
-Note 1003 select <in_optimizer>(`test`.`t3`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = 4) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t3`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))) AS `a in (select max(ie) from t1 where oref=4 group by grp)` from `test`.`t3`
+Note 1003 select <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = 4) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t3`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`))))))) AS `a in (select max(ie) from t1 where oref=4 group by grp)` from `test`.`t3`
set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3;
create table t1 (a int, oref int, key(a));
@@ -82,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;
@@ -97,14 +98,14 @@ 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`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,<in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) having trigcond(<is_not_null_test>(`test`.`t1`.`a`))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) having trigcond(<is_not_null_test>(`test`.`t1`.`a`)))))) AS `Z` from `test`.`t2`
flush status;
select oref, a from t2 where a in (select a from t1 where oref=t2.oref);
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';
@@ -123,7 +124,7 @@ Handler_read_last 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.
@@ -165,7 +166,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 ref a a 5 test.t1.b 1 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t3.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<in_optimizer>(`test`.`t3`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond(((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and (`test`.`t2`.`a` = `test`.`t1`.`b`)) having trigcond(<is_not_null_test>(`test`.`t1`.`a`)))) AS `Z` from `test`.`t3`
+Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<expr_cache><`test`.`t3`.`a`,`test`.`t3`.`oref`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond(((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and (`test`.`t2`.`a` = `test`.`t1`.`b`)) having trigcond(<is_not_null_test>(`test`.`t1`.`a`))))) AS `Z` from `test`.`t3`
drop table t1, t2, t3;
create table t1 (a int NOT NULL, b int NOT NULL, key(a));
insert into t1 values
@@ -193,7 +194,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 ref a a 4 test.t1.b 1 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t3.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<in_optimizer>(`test`.`t3`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`)) and (`test`.`t2`.`a` = `test`.`t1`.`b`)))) AS `Z` from `test`.`t3`
+Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<expr_cache><`test`.`t3`.`a`,`test`.`t3`.`oref`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`)) and (`test`.`t2`.`a` = `test`.`t1`.`b`))))) AS `Z` from `test`.`t3`
drop table t1,t2,t3;
create table t1 (oref int, grp int);
insert into t1 (oref, grp) values
@@ -217,7 +218,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 temporary
Warnings:
Note 1276 Field or reference 't2.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<in_optimizer>(`test`.`t2`.`a`,<exists>(select count(0) from `test`.`t1` group by `test`.`t1`.`grp` having ((`test`.`t1`.`grp` = `test`.`t2`.`oref`) and trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(count(0))))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select count(0) from `test`.`t1` group by `test`.`t1`.`grp` having ((`test`.`t1`.`grp` = `test`.`t2`.`oref`) and trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(count(0)))))))) AS `Z` from `test`.`t2`
drop table t1, t2;
create table t1 (a int, b int, primary key (a));
insert into t1 values (1,1), (3,1),(100,1);
@@ -249,7 +250,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`,<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
@@ -266,7 +267,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`,<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;
@@ -311,7 +312,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`,<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
@@ -345,8 +346,8 @@ dd NULL 0
bb NULL NULL
select oref, a from t2 where a in (select ie from t1 where oref=t2.oref);
oref a
-ff 2
aa 1
+ff 2
select oref, a from t2 where a not in (select ie from t1 where oref=t2.oref);
oref a
bb 2
@@ -523,8 +524,8 @@ aa 1 1 1
dd 1 NULL 0
select oref, a, b from t2 where (a,b) in (select ie1,ie2 from t1 where oref=t2.oref);
oref a b
-ff 2 2
aa 1 1
+ff 2 2
select oref, a, b from t2 where (a,b) not in (select ie1,ie2 from t1 where oref=t2.oref);
oref a b
bb 2 1
@@ -581,7 +582,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`,<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
@@ -712,7 +713,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using index
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t1`.`a`) and (not(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` where trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) having trigcond(<is_not_null_test>(`test`.`t1`.`a`)))))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t1`.`a`) and (not(<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` where trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) having trigcond(<is_not_null_test>(`test`.`t1`.`a`))))))))
SELECT a FROM t1, t2 WHERE a=b AND (b NOT IN (SELECT a FROM t1));
a
SELECT a FROM t1, t2 WHERE a=b AND (b NOT IN (SELECT a FROM t1 WHERE a > 4));
@@ -1114,7 +1115,7 @@ 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 <derived2> ALL NULL NULL NULL NULL 11
-1 PRIMARY t1 ALL NULL NULL NULL NULL 20 Using where; FirstMatch(<derived2>)
+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);
@@ -1133,9 +1134,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;
@@ -1423,6 +1424,53 @@ CALL p1;
ERROR 42S22: Unknown column 'f1' in 'where clause'
DROP PROCEDURE p1;
DROP TABLE t1, t2;
+#
+# fix of lp:824425 (prohibiting subqueries in row in
+# left part of IN/ALL/ANY)
+#
+CREATE TABLE t1 ( a int) ;
+INSERT INTO t1 VALUES (20),(30);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (3),(9);
+CREATE TABLE t3 ( a int, b int) ;
+INSERT INTO t3 VALUES (20,5),(30,6);
+set @optimizer_switch_save=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=OFF,in_to_exists=OFF,materialization=ON,partial_match_rowid_merge=ON,partial_match_table_scan=OFF';
+SELECT * FROM t1
+WHERE (
+( SELECT a FROM t2 WHERE a = 9 )
+) NOT IN (
+SELECT b
+FROM t3
+);
+a
+20
+30
+explain extended
+SELECT * FROM t1
+WHERE (
+( SELECT a FROM t2 WHERE a = 9 )
+) NOT IN (
+SELECT b
+FROM t3
+);
+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
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (not(<expr_cache><(select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`a` = 9))>(<in_optimizer>((select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`a` = 9)),(select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`a` = 9)) in ( <materialize> (select `test`.`t3`.`b` from `test`.`t3` ), <primary_index_lookup>(9 in <temporary table> on distinct_key where ((9 = `<subquery3>`.`b`))))))))
+SELECT * FROM t1
+WHERE (
+( SELECT a FROM t2 WHERE a = 9 ),
+( SELECT a FROM t2 WHERE a = 3 )
+) NOT IN (
+SELECT b , a
+FROM t3
+);
+ERROR 42000: This version of MySQL doesn't yet support 'SUBQUERY in ROW in left expression of IN/ALL/ANY'
+set optimizer_switch=@optimizer_switch_save;
+drop table t1,t2,t3;
End of 5.3 tests
#
# BUG#48920: COUNT DISTINCT returns 1 for NULL values when in a subquery
@@ -1471,7 +1519,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t2.v' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`i` AS `i`,`test`.`t2`.`v` AS `v`,(select count(distinct `test`.`t1`.`i`) from `test`.`t1` where (`test`.`t1`.`v` = `test`.`t2`.`v`)) AS `subsel` from `test`.`t2`
+Note 1003 select `test`.`t2`.`i` AS `i`,`test`.`t2`.`v` AS `v`,<expr_cache><`test`.`t2`.`v`>((select count(distinct `test`.`t1`.`i`) from `test`.`t1` where (`test`.`t1`.`v` = `test`.`t2`.`v`))) AS `subsel` from `test`.`t2`
DROP TABLE t1,t2;
End of 5.6 tests
set @@optimizer_switch=@subselect3_tmp;
diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result
index ffd55264dc6..645e3a1d84e 100644
--- a/mysql-test/r/subselect3_jcl6.result
+++ b/mysql-test/r/subselect3_jcl6.result
@@ -9,7 +9,7 @@ Variable_name Value
join_cache_level 6
drop table if exists t0, t1, t2, t3, t4, t5, t11, t12, t21, t22;
set @subselect3_tmp= @@optimizer_switch;
-set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on';
create table t1 (oref int, grp int, ie int) ;
insert into t1 (oref, grp, ie) values
(1, 1, 1),
@@ -41,7 +41,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary
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`.`oref` AS `oref`,<in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`))))))) AS `Z` from `test`.`t2`
explain extended
select a, oref from t2
where a in (select max(ie) from t1 where oref=t2.oref group by grp);
@@ -50,7 +50,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary
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`.`oref` AS `oref` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having (<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) group by `test`.`t1`.`grp` having (<cache>(`test`.`t2`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`))))))
select a, oref, a in (
select max(ie) from t1 where oref=t2.oref group by grp union
select max(ie) from t1 where oref=t2.oref group by grp
@@ -81,7 +81,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 6 100.00 Using where; Using temporary
Warnings:
-Note 1003 select <in_optimizer>(`test`.`t3`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = 4) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t3`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`)))))) AS `a in (select max(ie) from t1 where oref=4 group by grp)` from `test`.`t3`
+Note 1003 select <expr_cache><`test`.`t3`.`a`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select max(`test`.`t1`.`ie`) from `test`.`t1` where (`test`.`t1`.`oref` = 4) group by `test`.`t1`.`grp` having trigcond((<cache>(`test`.`t3`.`a`) = <ref_null_helper>(max(`test`.`t1`.`ie`))))))) AS `a in (select max(ie) from t1 where oref=4 group by grp)` from `test`.`t3`
set @@optimizer_switch=@save_optimizer_switch;
drop table t1, t2, t3;
create table t1 (a int, oref int, key(a));
@@ -91,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;
@@ -106,14 +107,14 @@ 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`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,<in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) having trigcond(<is_not_null_test>(`test`.`t1`.`a`))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`oref` AS `oref`,`test`.`t2`.`a` AS `a`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(<index_lookup>(<cache>(`test`.`t2`.`a`) in t1 on a checking NULL where (`test`.`t1`.`oref` = `test`.`t2`.`oref`) having trigcond(<is_not_null_test>(`test`.`t1`.`a`)))))) AS `Z` from `test`.`t2`
flush status;
select oref, a from t2 where a in (select a from t1 where oref=t2.oref);
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';
@@ -132,7 +133,7 @@ Handler_read_last 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.
@@ -174,7 +175,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 ref a a 5 test.t1.b 1 100.00 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
Warnings:
Note 1276 Field or reference 'test.t3.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<in_optimizer>(`test`.`t3`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond(((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and (`test`.`t2`.`a` = `test`.`t1`.`b`)) having trigcond(<is_not_null_test>(`test`.`t1`.`a`)))) AS `Z` from `test`.`t3`
+Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<expr_cache><`test`.`t3`.`a`,`test`.`t3`.`oref`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond(((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) and (`test`.`t2`.`a` = `test`.`t1`.`b`)) having trigcond(<is_not_null_test>(`test`.`t1`.`a`))))) AS `Z` from `test`.`t3`
drop table t1, t2, t3;
create table t1 (a int NOT NULL, b int NOT NULL, key(a));
insert into t1 values
@@ -202,7 +203,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 ref a a 4 test.t1.b 1 100.00 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
Warnings:
Note 1276 Field or reference 'test.t3.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<in_optimizer>(`test`.`t3`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`)) and (`test`.`t2`.`a` = `test`.`t1`.`b`)))) AS `Z` from `test`.`t3`
+Note 1003 select `test`.`t3`.`a` AS `a`,`test`.`t3`.`oref` AS `oref`,<expr_cache><`test`.`t3`.`a`,`test`.`t3`.`oref`>(<in_optimizer>(`test`.`t3`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t3`.`oref`) and trigcond((<cache>(`test`.`t3`.`a`) = `test`.`t1`.`a`)) and (`test`.`t2`.`a` = `test`.`t1`.`b`))))) AS `Z` from `test`.`t3`
drop table t1,t2,t3;
create table t1 (oref int, grp int);
insert into t1 (oref, grp) values
@@ -226,7 +227,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 temporary
Warnings:
Note 1276 Field or reference 't2.oref' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<in_optimizer>(`test`.`t2`.`a`,<exists>(select count(0) from `test`.`t1` group by `test`.`t1`.`grp` having ((`test`.`t1`.`grp` = `test`.`t2`.`oref`) and trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(count(0))))))) AS `Z` from `test`.`t2`
+Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`oref` AS `oref`,<expr_cache><`test`.`t2`.`a`,`test`.`t2`.`oref`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select count(0) from `test`.`t1` group by `test`.`t1`.`grp` having ((`test`.`t1`.`grp` = `test`.`t2`.`oref`) and trigcond((<cache>(`test`.`t2`.`a`) = <ref_null_helper>(count(0)))))))) AS `Z` from `test`.`t2`
drop table t1, t2;
create table t1 (a int, b int, primary key (a));
insert into t1 values (1,1), (3,1),(100,1);
@@ -258,7 +259,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`,<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
@@ -275,7 +276,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`,<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;
@@ -320,7 +321,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`,<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
@@ -590,7 +591,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`,<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
@@ -721,7 +722,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Using index
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t1`.`a`) and (not(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` where trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) having trigcond(<is_not_null_test>(`test`.`t1`.`a`)))))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` join `test`.`t2` where ((`test`.`t2`.`b` = `test`.`t1`.`a`) and (not(<expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` where trigcond(((<cache>(`test`.`t2`.`b`) = `test`.`t1`.`a`) or isnull(`test`.`t1`.`a`))) having trigcond(<is_not_null_test>(`test`.`t1`.`a`))))))))
SELECT a FROM t1, t2 WHERE a=b AND (b NOT IN (SELECT a FROM t1));
a
SELECT a FROM t1, t2 WHERE a=b AND (b NOT IN (SELECT a FROM t1 WHERE a > 4));
@@ -1142,9 +1143,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;
@@ -1432,6 +1433,53 @@ CALL p1;
ERROR 42S22: Unknown column 'f1' in 'where clause'
DROP PROCEDURE p1;
DROP TABLE t1, t2;
+#
+# fix of lp:824425 (prohibiting subqueries in row in
+# left part of IN/ALL/ANY)
+#
+CREATE TABLE t1 ( a int) ;
+INSERT INTO t1 VALUES (20),(30);
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (3),(9);
+CREATE TABLE t3 ( a int, b int) ;
+INSERT INTO t3 VALUES (20,5),(30,6);
+set @optimizer_switch_save=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=OFF,in_to_exists=OFF,materialization=ON,partial_match_rowid_merge=ON,partial_match_table_scan=OFF';
+SELECT * FROM t1
+WHERE (
+( SELECT a FROM t2 WHERE a = 9 )
+) NOT IN (
+SELECT b
+FROM t3
+);
+a
+20
+30
+explain extended
+SELECT * FROM t1
+WHERE (
+( SELECT a FROM t2 WHERE a = 9 )
+) NOT IN (
+SELECT b
+FROM t3
+);
+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
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (not(<expr_cache><(select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`a` = 9))>(<in_optimizer>((select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`a` = 9)),(select `test`.`t2`.`a` from `test`.`t2` where (`test`.`t2`.`a` = 9)) in ( <materialize> (select `test`.`t3`.`b` from `test`.`t3` ), <primary_index_lookup>(9 in <temporary table> on distinct_key where ((9 = `<subquery3>`.`b`))))))))
+SELECT * FROM t1
+WHERE (
+( SELECT a FROM t2 WHERE a = 9 ),
+( SELECT a FROM t2 WHERE a = 3 )
+) NOT IN (
+SELECT b , a
+FROM t3
+);
+ERROR 42000: This version of MySQL doesn't yet support 'SUBQUERY in ROW in left expression of IN/ALL/ANY'
+set optimizer_switch=@optimizer_switch_save;
+drop table t1,t2,t3;
End of 5.3 tests
#
# BUG#48920: COUNT DISTINCT returns 1 for NULL values when in a subquery
@@ -1480,7 +1528,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t2.v' of SELECT #2 was resolved in SELECT #1
-Note 1003 select `test`.`t2`.`i` AS `i`,`test`.`t2`.`v` AS `v`,(select count(distinct `test`.`t1`.`i`) from `test`.`t1` where (`test`.`t1`.`v` = `test`.`t2`.`v`)) AS `subsel` from `test`.`t2`
+Note 1003 select `test`.`t2`.`i` AS `i`,`test`.`t2`.`v` AS `v`,<expr_cache><`test`.`t2`.`v`>((select count(distinct `test`.`t1`.`i`) from `test`.`t1` where (`test`.`t1`.`v` = `test`.`t2`.`v`))) AS `subsel` from `test`.`t2`
DROP TABLE t1,t2;
End of 5.6 tests
set @@optimizer_switch=@subselect3_tmp;
diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result
index 84317beba32..9c81a0f552d 100644
--- a/mysql-test/r/subselect4.result
+++ b/mysql-test/r/subselect4.result
@@ -2,6 +2,7 @@ drop table if exists t0,t1,t2,t3,t4,t5,t6;
drop view if exists v1, v2;
set @subselect4_tmp= @@optimizer_switch;
set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='semijoin_with_cache=on';
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
#
# Bug #46791: Assertion failed:(table->key_read==0),function unknown
@@ -225,7 +226,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 (select 1 from `test`.`t2` where 0) AS `RESULT` from dual
+Note 1003 select <expr_cache><>((select 1 from `test`.`t2` where 0)) AS `RESULT` from dual
first equivalent variant
SELECT (SELECT 1 FROM t2 WHERE d = IFNULL(c,NULL)) AS RESULT FROM t1 GROUP BY c ;
RESULT
@@ -236,7 +237,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 (select 1 from `test`.`t2` where 0) AS `RESULT` from dual group by NULL
+Note 1003 select <expr_cache><>((select 1 from `test`.`t2` where 0)) AS `RESULT` from dual group by NULL
second equivalent variant
SELECT (SELECT 1 FROM t2 WHERE d = c) AS RESULT FROM t1 GROUP BY c ;
RESULT
@@ -247,7 +248,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 (select 1 from `test`.`t2` where 0) AS `RESULT` from dual group by NULL
+Note 1003 select <expr_cache><>((select 1 from `test`.`t2` where 0)) AS `RESULT` from dual group by NULL
DROP TABLE t1,t2;
#
# BUG#45928 "Differing query results depending on MRR and
@@ -278,31 +279,6 @@ Warnings:
Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MySQL 7.0. Please use '@@optimizer_switch' instead
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
@@ -1234,7 +1210,8 @@ FROM t2 JOIN t1 ON t1.f3
WHERE ('v') IN (SELECT f4 FROM t2)
GROUP BY f9;
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 t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2
SELECT COUNT(t2.f3),
@@ -1250,7 +1227,8 @@ FROM t2 JOIN t1 ON t1.f3
WHERE ('v') IN (SELECT f4 FROM t2)
ORDER BY f9;
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 t2 system NULL NULL NULL NULL 1
+1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
3 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2
SELECT COUNT(t2.f3),
@@ -1894,7 +1872,9 @@ 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 NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+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
@@ -1905,7 +1885,9 @@ 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 NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+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
@@ -1943,4 +1925,71 @@ 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 e57010b026c..9b515ba8e52 100644
--- a/mysql-test/r/subselect_cache.result
+++ b/mysql-test/r/subselect_cache.result
@@ -1,4 +1,5 @@
drop table if exists t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
+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);
@@ -3546,5 +3547,31 @@ 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
index 9d2ff08cdb0..bb2ae830c20 100644
--- a/mysql-test/r/subselect_extra.result
+++ b/mysql-test/r/subselect_extra.result
@@ -1,6 +1,8 @@
drop table if exists t1,t2,t3,t4;
+drop view if exists v1,v2,v3;
set @subselect_extra_tmp=@@optimizer_switch;
-set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_extra_test,
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
# From explain.test:
#
# Bug#37870: Usage of uninitialized value caused failed assertion.
@@ -227,7 +229,7 @@ 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)
+2 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index; FirstMatch(t2); Using join buffer (flat, BNL join)
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
@@ -258,7 +260,7 @@ 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)
+2 DEPENDENT SUBQUERY t3 index NULL idx_t3_1 10 NULL 192 Using where; Using index; FirstMatch(t2); Using join buffer (flat, BNL join)
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
@@ -305,7 +307,7 @@ 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)
+1 PRIMARY t1 ALL NULL NULL NULL NULL 144 Using where; FirstMatch(t1); Using join buffer (flat, BNL join)
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;
@@ -318,6 +320,159 @@ 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)
+1 PRIMARY t1 ALL NULL NULL NULL NULL 144 Using where; FirstMatch(t2); Using join buffer (flat, BNL join)
DROP TABLE t1, t2;
-set optimizer_switch= @subselect_extra_tmp;
+#
+# 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`.`t2` semi join (dual) 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`.`t2` semi join (dual) 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
+1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 Using where; Start temporary; End temporary
+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..78d122cfcd4
--- /dev/null
+++ b/mysql-test/r/subselect_extra_no_semijoin.result
@@ -0,0 +1,484 @@
+set @subselect_extra_no_sj_tmp=@@optimizer_switch;
+set @optimizer_switch_for_subselect_extra_test='semijoin=off,firstmatch=off,loosescan=off,semijoin_with_cache=off';
+drop table if exists t1,t2,t3,t4;
+drop view if exists v1,v2,v3;
+set @subselect_extra_tmp=@@optimizer_switch;
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_extra_test,
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
+# 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 dual 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 dual 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`.`t2` where <expr_cache><0>(<in_optimizer>(0,<exists>(select 0 from dual 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`.`t2` where <expr_cache><0>(<in_optimizer>(0,<exists>(select 0 from dual 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;
+set @optimizer_switch_for_subselect_extra_test=null;
diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result
index 68cfdff775b..b134e849bbe 100644
--- a/mysql-test/r/subselect_innodb.result
+++ b/mysql-test/r/subselect_innodb.result
@@ -258,4 +258,62 @@ a b
Warnings:
Warning 1292 Incorrect datetime value: '0'
DROP TABLE t1;
+#
+# lp: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: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 f240c2ba492..d155a2cd3a8 100644
--- a/mysql-test/r/subselect_mat.result
+++ b/mysql-test/r/subselect_mat.result
@@ -1,9 +1,9 @@
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=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=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, 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;
@@ -48,7 +48,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
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` 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`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` 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`))))))
select * from t1 where a1 in (select b1 from t2 where b1 > '0');
a1 a2
1 - 01 2 - 01
@@ -59,7 +59,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 <in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` 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`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` 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`))))))
select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -70,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 <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
@@ -81,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 <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
@@ -92,7 +92,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 it2i1 # NULL 5 100.00 Using where;
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (select `test`.`t2i`.`b1` 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`)))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`>(<in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (select `test`.`t2i`.`b1` 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`))))))
select * from t1i where a1 in (select b1 from t2i where b1 > '0');
a1 a2
1 - 01 2 - 01
@@ -103,7 +103,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1i index NULL # 18 # 3 100.00 #
2 SUBQUERY t2i range it2i1,it2i3 # 9 # 3 100.00 #
Warnings:
-Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (select `test`.`t2i`.`b1` 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`)))))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where <expr_cache><`test`.`t1i`.`a1`>(<in_optimizer>(`test`.`t1i`.`a1`,`test`.`t1i`.`a1` in ( <materialize> (select `test`.`t2i`.`b1` 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`))))))
select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
a1 a2
1 - 01 2 - 01
@@ -114,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 <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
@@ -125,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 <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
@@ -136,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 <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
@@ -147,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 <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
@@ -176,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 <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
@@ -223,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 <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
@@ -234,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 <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
@@ -289,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 (<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 <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 <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
@@ -308,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 (<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 <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 <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
@@ -331,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 (<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 (<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 <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 <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 <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
@@ -356,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 (<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<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 <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 <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 <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
@@ -392,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 (<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 (<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 <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 <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 <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 (<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 <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 <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
@@ -421,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 (<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 <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 <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
@@ -444,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 <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 <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 <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
@@ -466,7 +466,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`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t3` where <in_optimizer>(`test`.`t3`.`c1`,<exists>(select `test`.`t1`.`a1` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t3`.`c1`) = `test`.`t1`.`a1`)) union select `test`.`t2`.`b1` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t3`.`c1`) = `test`.`t2`.`b1`))))
+Note 1003 select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`>(<in_optimizer>(`test`.`t3`.`c1`,<exists>(select `test`.`t1`.`a1` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t3`.`c1`) = `test`.`t1`.`a1`)) union select `test`.`t2`.`b1` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t3`.`c1`) = `test`.`t2`.`b1`)))))
select * from t3
where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
c1 c2
@@ -490,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 (<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where ((<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 <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 <in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),<exists>(select `test`.`t3c`.`c1`,`test`.`t3c`.`c2` from `test`.`t3` `t3c` where (<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 <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
@@ -507,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 <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
@@ -539,7 +539,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 temporary; Using filesort
2 DEPENDENT SUBQUERY columns unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where; Full scan on NULL key
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` group by <in_optimizer>(`test`.`t1`.`a1`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`a1`) in columns on PRIMARY where trigcond((<cache>(`test`.`t1`.`a1`) = `test`.`columns`.`col`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` group by <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`a1`) in columns on PRIMARY where trigcond((<cache>(`test`.`t1`.`a1`) = `test`.`columns`.`col`))))))
select * from t1 group by (a1 in (select col from columns));
a1 a2
1 - 00 2 - 00
@@ -596,7 +596,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 <in_optimizer>(`test`.`t1_16`.`a1`,<exists>(select `test`.`t2_16`.`b1` from `test`.`t2_16` where ((`test`.`t2_16`.`b1` > '0') and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`))))
+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`>(<in_optimizer>(`test`.`t1_16`.`a1`,<exists>(select `test`.`t2_16`.`b1` from `test`.`t2_16` where ((`test`.`t2_16`.`b1` > '0') and (<cache>(`test`.`t1_16`.`a1`) = `test`.`t2_16`.`b1`)))))
select left(a1,7), left(a2,7)
from t1_16
where a1 in (select b1 from t2_16 where b1 > '0');
@@ -610,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 <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');
@@ -624,7 +624,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 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 <in_optimizer>(`test`.`t1_16`.`a1`,`test`.`t1_16`.`a1` in ( <materialize> (select substr(`test`.`t2_16`.`b1`,1,16) from `test`.`t2_16` where (`test`.`t2_16`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1_16`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_16`.`a1` = `<subquery2>`.`substring(b1,1,16)`)))))
+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`>(<in_optimizer>(`test`.`t1_16`.`a1`,`test`.`t1_16`.`a1` in ( <materialize> (select substr(`test`.`t2_16`.`b1`,1,16) from `test`.`t2_16` where (`test`.`t2_16`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1_16`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_16`.`a1` = `<subquery2>`.`substring(b1,1,16)`))))))
select left(a1,7), left(a2,7)
from t1_16
where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
@@ -638,7 +638,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 filesort
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 <in_optimizer>(`test`.`t1_16`.`a1`,<exists>(select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2` having (<cache>(`test`.`t1_16`.`a1`) = <ref_null_helper>(group_concat(`test`.`t2_16`.`b1` separator ',')))))
+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`>(<in_optimizer>(`test`.`t1_16`.`a1`,<exists>(select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2` having (<cache>(`test`.`t1_16`.`a1`) = <ref_null_helper>(group_concat(`test`.`t2_16`.`b1` separator ','))))))
select left(a1,7), left(a2,7)
from t1_16
where a1 in (select group_concat(b1) from t2_16 group by b2);
@@ -653,7 +653,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 SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using filesort
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 <in_optimizer>(`test`.`t1_16`.`a1`,`test`.`t1_16`.`a1` in ( <materialize> (select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2` ), <primary_index_lookup>(`test`.`t1_16`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_16`.`a1` = `<subquery2>`.`group_concat(b1)`)))))
+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`>(<in_optimizer>(`test`.`t1_16`.`a1`,`test`.`t1_16`.`a1` in ( <materialize> (select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2` ), <primary_index_lookup>(`test`.`t1_16`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_16`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
select left(a1,7), left(a2,7)
from t1_16
where a1 in (select group_concat(b1) from t2_16 group by b2);
@@ -675,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 <in_optimizer>(concat(`test`.`t1`.`a1`,'x'),<exists>(select left(`test`.`t1_16`.`a1`,8) from `test`.`t1_16` where (<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 <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;
@@ -709,7 +709,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 <in_optimizer>(`test`.`t1_512`.`a1`,<exists>(select `test`.`t2_512`.`b1` from `test`.`t2_512` where ((`test`.`t2_512`.`b1` > '0') and (<cache>(`test`.`t1_512`.`a1`) = `test`.`t2_512`.`b1`))))
+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`>(<in_optimizer>(`test`.`t1_512`.`a1`,<exists>(select `test`.`t2_512`.`b1` from `test`.`t2_512` where ((`test`.`t2_512`.`b1` > '0') and (<cache>(`test`.`t1_512`.`a1`) = `test`.`t2_512`.`b1`)))))
select left(a1,7), left(a2,7)
from t1_512
where a1 in (select b1 from t2_512 where b1 > '0');
@@ -723,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 <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');
@@ -737,7 +737,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 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 <in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select substr(`test`.`t2_512`.`b1`,1,512) from `test`.`t2_512` where (`test`.`t2_512`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `<subquery2>`.`substring(b1,1,512)`)))))
+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`>(<in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select substr(`test`.`t2_512`.`b1`,1,512) from `test`.`t2_512` where (`test`.`t2_512`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `<subquery2>`.`substring(b1,1,512)`))))))
select left(a1,7), left(a2,7)
from t1_512
where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
@@ -751,7 +751,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 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
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 <in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2` ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `<subquery2>`.`group_concat(b1)`)))))
+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`>(<in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2` ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
select left(a1,7), left(a2,7)
from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2);
@@ -764,7 +764,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 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
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 <in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2` ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `<subquery2>`.`group_concat(b1)`)))))
+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`>(<in_optimizer>(`test`.`t1_512`.`a1`,`test`.`t1_512`.`a1` in ( <materialize> (select group_concat(`test`.`t2_512`.`b1` separator ',') from `test`.`t2_512` group by `test`.`t2_512`.`b2` ), <primary_index_lookup>(`test`.`t1_512`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_512`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
select left(a1,7), left(a2,7)
from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2);
@@ -802,7 +802,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 <in_optimizer>(`test`.`t1_1024`.`a1`,<exists>(select `test`.`t2_1024`.`b1` from `test`.`t2_1024` where ((`test`.`t2_1024`.`b1` > '0') and (<cache>(`test`.`t1_1024`.`a1`) = `test`.`t2_1024`.`b1`))))
+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`>(<in_optimizer>(`test`.`t1_1024`.`a1`,<exists>(select `test`.`t2_1024`.`b1` from `test`.`t2_1024` where ((`test`.`t2_1024`.`b1` > '0') and (<cache>(`test`.`t1_1024`.`a1`) = `test`.`t2_1024`.`b1`)))))
select left(a1,7), left(a2,7)
from t1_1024
where a1 in (select b1 from t2_1024 where b1 > '0');
@@ -816,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 <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');
@@ -830,7 +830,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 <in_optimizer>(`test`.`t1_1024`.`a1`,<exists>(select substr(`test`.`t2_1024`.`b1`,1,1024) from `test`.`t2_1024` where ((`test`.`t2_1024`.`b1` > '0') and (<cache>(`test`.`t1_1024`.`a1`) = substr(`test`.`t2_1024`.`b1`,1,1024)))))
+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`>(<in_optimizer>(`test`.`t1_1024`.`a1`,<exists>(select substr(`test`.`t2_1024`.`b1`,1,1024) from `test`.`t2_1024` where ((`test`.`t2_1024`.`b1` > '0') and (<cache>(`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');
@@ -844,7 +844,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
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 <in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2` ), <primary_index_lookup>(`test`.`t1_1024`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1024`.`a1` = `<subquery2>`.`group_concat(b1)`)))))
+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`>(<in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2` ), <primary_index_lookup>(`test`.`t1_1024`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1024`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
select left(a1,7), left(a2,7)
from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2);
@@ -857,7 +857,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 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
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 <in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2` ), <primary_index_lookup>(`test`.`t1_1024`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1024`.`a1` = `<subquery2>`.`group_concat(b1)`)))))
+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`>(<in_optimizer>(`test`.`t1_1024`.`a1`,`test`.`t1_1024`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1024`.`b1` separator ',') from `test`.`t2_1024` group by `test`.`t2_1024`.`b2` ), <primary_index_lookup>(`test`.`t1_1024`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1024`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
select left(a1,7), left(a2,7)
from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2);
@@ -895,7 +895,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 <in_optimizer>(`test`.`t1_1025`.`a1`,<exists>(select `test`.`t2_1025`.`b1` from `test`.`t2_1025` where ((`test`.`t2_1025`.`b1` > '0') and (<cache>(`test`.`t1_1025`.`a1`) = `test`.`t2_1025`.`b1`))))
+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`>(<in_optimizer>(`test`.`t1_1025`.`a1`,<exists>(select `test`.`t2_1025`.`b1` from `test`.`t2_1025` where ((`test`.`t2_1025`.`b1` > '0') and (<cache>(`test`.`t1_1025`.`a1`) = `test`.`t2_1025`.`b1`)))))
select left(a1,7), left(a2,7)
from t1_1025
where a1 in (select b1 from t2_1025 where b1 > '0');
@@ -909,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 <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');
@@ -923,7 +923,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 <in_optimizer>(`test`.`t1_1025`.`a1`,<exists>(select substr(`test`.`t2_1025`.`b1`,1,1025) from `test`.`t2_1025` where ((`test`.`t2_1025`.`b1` > '0') and (<cache>(`test`.`t1_1025`.`a1`) = substr(`test`.`t2_1025`.`b1`,1,1025)))))
+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`>(<in_optimizer>(`test`.`t1_1025`.`a1`,<exists>(select substr(`test`.`t2_1025`.`b1`,1,1025) from `test`.`t2_1025` where ((`test`.`t2_1025`.`b1` > '0') and (<cache>(`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');
@@ -937,7 +937,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 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
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 <in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2` ), <primary_index_lookup>(`test`.`t1_1025`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1025`.`a1` = `<subquery2>`.`group_concat(b1)`)))))
+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`>(<in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2` ), <primary_index_lookup>(`test`.`t1_1025`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1025`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
select left(a1,7), left(a2,7)
from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2);
@@ -950,7 +950,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 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
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 <in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2` ), <primary_index_lookup>(`test`.`t1_1025`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1025`.`a1` = `<subquery2>`.`group_concat(b1)`)))))
+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`>(<in_optimizer>(`test`.`t1_1025`.`a1`,`test`.`t1_1025`.`a1` in ( <materialize> (select group_concat(`test`.`t2_1025`.`b1` separator ',') from `test`.`t2_1025` group by `test`.`t2_1025`.`b2` ), <primary_index_lookup>(`test`.`t1_1025`.`a1` in <temporary table> on distinct_key where ((`test`.`t1_1025`.`a1` = `<subquery2>`.`group_concat(b1)`))))))
select left(a1,7), left(a2,7)
from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2);
@@ -971,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 <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);
@@ -994,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 <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);
@@ -1042,7 +1042,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`))))))
select a from t1 where a in (select c from t2 where d >= 20);
a
2
@@ -1056,7 +1056,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using where; Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`))))))
select a from t1 where a in (select c from t2 where d >= 20);
a
2
@@ -1070,7 +1070,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using where; Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`))))))
select a from t1 where a in (select c from t2 where d >= 20);
a
2
@@ -1083,7 +1083,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`))))))
select a from t1 group by a having a in (select c from t2 where d >= 20);
a
2
@@ -1095,7 +1095,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`))))))
select a from t1 group by a having a in (select c from t2 where d >= 20);
a
2
@@ -1109,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 <in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`c` from `test`.`t2` where (<nop>(<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
@@ -1124,7 +1124,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` where <in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`c` from `test`.`t2` where (<nop>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`))))) and (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`,`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`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))))) and (<cache>(`test`.`t1`.`a`) = `test`.`t2`.`c`)))))
select a from t1
where a in (select c from t2 where d >= some(select e from t3 where b=e));
a
@@ -1235,7 +1235,8 @@ GROUP BY t3i
)
);
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
+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;
@@ -1368,7 +1369,8 @@ 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 NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+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);
@@ -1560,6 +1562,170 @@ 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';
@@ -1797,7 +1963,7 @@ 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 <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`)))))
+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
@@ -1808,5 +1974,37 @@ 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 <in_optimizer>(9,<exists>(select `test`.`t2`.`a` from `test`.`t2` where (9 = `test`.`t2`.`a`)))
+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 a642c498e53..5531c7e107f 100644
--- a/mysql-test/r/subselect_mat_cost.result
+++ b/mysql-test/r/subselect_mat_cost.result
@@ -1,5 +1,6 @@
set @subselect_mat_cost=@@optimizer_switch;
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+set long_query_time=0.1;
TEST GROUP 1:
Typical cases of in-to-exists and materialization subquery strategies
=====================================================================
@@ -284,7 +285,7 @@ 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; Rowid-ordered scan
+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
@@ -343,18 +344,20 @@ 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));
+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 index NULL PRIMARY 33 NULL 984 Using where; Using index
-2 DEPENDENT SUBQUERY City ref CityName CityName 35 func 2 Using index condition
+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));
+FROM City LEFT JOIN Country ON (Country = Code and City.Population < 10000))
+AND Language IN ('English','Spanish');
count(*)
-979
+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
diff --git a/mysql-test/r/subselect_mat_cost_bugs.result b/mysql-test/r/subselect_mat_cost_bugs.result
index 7988d93a389..2f5d799a44d 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 <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`.`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
@@ -327,4 +333,63 @@ 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 cd805fb8e86..0bddfb5f477 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -7,7 +7,7 @@ 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");
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=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)
@@ -60,7 +60,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 dual having ((select 1) = 1)
+Note 1003 select 1 AS `1` from dual having (<expr_cache><1>((select 1)) = 1)
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
1
1
@@ -234,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
@@ -280,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`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`)))
+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
@@ -324,7 +324,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 (select 2 from dual 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 <expr_cache><`test`.`t2`.`a`>((select 2 from dual 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));
@@ -342,7 +342,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 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 <expr_cache><`test`.`t6`.`clinic_uq`>(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;
@@ -372,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)
@@ -548,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 = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where multiple equal(1, `test`.`t1`.`numeropost`))))
+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);
@@ -756,7 +762,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 <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 <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)))))
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
id
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
@@ -904,7 +910,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`,<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`,<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`
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;
@@ -919,8 +925,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`,<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`,<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'
@@ -1480,27 +1611,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(<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(<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`
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`
+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`
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`
+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`
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`
+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);
@@ -1513,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`,((select max(NULL) from `test`.`t2`) > `test`.`t3`.`a`)))
+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);
@@ -1521,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`,((select min(NULL) from `test`.`t2`) <= `test`.`t3`.`a`)))
+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
@@ -1532,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`,(<max>(select NULL from `test`.`t2` group by 1) > `test`.`t3`.`a`)))
+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);
@@ -1540,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`,(<min>(select NULL from `test`.`t2` group by 1) <= `test`.`t3`.`a`)))
+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);
@@ -1583,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`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= `test`.`t3`.`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());
@@ -1753,14 +1884,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(<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(<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`))))))))
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))))
+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)))))
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');
@@ -2296,7 +2427,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 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 <expr_cache><`test`.`up`.`a`>(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);
@@ -2767,6 +2898,8 @@ select * from (select max(fld) from t1) as foo;
max(fld)
1
drop table t1;
+set @tmp11867_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin_with_cache=off';
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');
@@ -2837,7 +2970,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`,<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
@@ -2849,8 +2982,9 @@ 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`
+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=@tmp11867_optimizer_switch;
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'));
@@ -4295,7 +4429,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 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 2 AS `2` from `test`.`t1` where exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))
+Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a));
@@ -4307,7 +4441,7 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select 2 AS `2` from `test`.`t1` where exists((select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) union (select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
+Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists((select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) union (select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))))
DROP TABLE t1,t2;
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
@@ -4385,13 +4519,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 <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 <expr_cache><1>(<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))))
+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)))))
DROP TABLE t1;
#
# Bug#45061: Incorrectly market field caused wrong result.
@@ -5511,6 +5645,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: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
@@ -5533,24 +5828,30 @@ ON t2.f10 = t3.f10
f1
DROP TABLE t1,t2,t3;
#
-# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+# 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 ( 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;
+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.
#
@@ -5669,6 +5970,57 @@ id select_type table type possible_keys key key_len ref rows Extra
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: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%';
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
index fa633f4b838..af0fc163f80 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -1,9 +1,9 @@
-set @optimizer_switch_for_subselect_test='materialization=off,semijoin=off,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+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 @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");
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=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)
@@ -276,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`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`)))
+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 +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)
@@ -544,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 = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where multiple equal(1, `test`.`t1`.`numeropost`))))
+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 +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`,<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'
@@ -1496,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(<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 +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`,((select max(NULL) from `test`.`t2`) > `test`.`t3`.`a`)))
+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 +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`,((select min(NULL) from `test`.`t2`) <= `test`.`t3`.`a`)))
+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 +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`,(<max>(select NULL from `test`.`t2` group by 1) > `test`.`t3`.`a`)))
+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 +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`,(<min>(select NULL from `test`.`t2` group by 1) <= `test`.`t3`.`a`)))
+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);
@@ -1579,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`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= `test`.`t3`.`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());
@@ -2763,6 +2894,8 @@ select * from (select max(fld) from t1) as foo;
max(fld)
1
drop table t1;
+set @tmp11867_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin_with_cache=off';
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');
@@ -2847,6 +2980,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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;
+set optimizer_switch=@tmp11867_optimizer_switch;
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'));
@@ -5507,6 +5641,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: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
@@ -5529,24 +5824,30 @@ ON t2.f10 = t3.f10
f1
DROP TABLE t1,t2,t3;
#
-# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+# 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 ( 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;
+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.
#
@@ -5665,5 +5966,56 @@ id select_type table type possible_keys key key_len ref rows Extra
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: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_scache.result b/mysql-test/r/subselect_no_scache.result
index 8a6284acdd1..febb522254c 100644
--- a/mysql-test/r/subselect_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -1,12 +1,12 @@
select @@optimizer_switch like '%subquery_cache=on%';
@@optimizer_switch like '%subquery_cache=on%'
-0
-set optimizer_switch='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");
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=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)
@@ -59,7 +59,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 dual having (<expr_cache><1>((select 1)) = 1)
+Note 1003 select 1 AS `1` from dual having ((select 1) = 1)
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
1
1
@@ -233,7 +233,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`,<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`
+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
@@ -279,7 +279,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`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`)))
+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
@@ -323,7 +323,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 dual 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 dual 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));
@@ -341,7 +341,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;
@@ -371,12 +371,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)
@@ -547,18 +547,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 = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where multiple equal(1, `test`.`t1`.`numeropost`))))
+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);
@@ -755,7 +761,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);
@@ -903,7 +909,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;
@@ -918,8 +924,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'
@@ -1479,27 +1610,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);
@@ -1512,7 +1643,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`,((select max(NULL) from `test`.`t2`) > `test`.`t3`.`a`)))
+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);
@@ -1520,7 +1651,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`,((select min(NULL) from `test`.`t2`) <= `test`.`t3`.`a`)))
+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
@@ -1531,7 +1662,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`,(<max>(select NULL from `test`.`t2` group by 1) > `test`.`t3`.`a`)))
+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);
@@ -1539,7 +1670,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`,(<min>(select NULL from `test`.`t2` group by 1) <= `test`.`t3`.`a`)))
+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);
@@ -1582,7 +1713,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`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= `test`.`t3`.`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());
@@ -1752,14 +1883,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');
@@ -2295,7 +2426,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);
@@ -2766,6 +2897,8 @@ select * from (select max(fld) from t1) as foo;
max(fld)
1
drop table t1;
+set @tmp11867_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin_with_cache=off';
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');
@@ -2836,7 +2969,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`.`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`
+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
@@ -2848,8 +2981,9 @@ 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`.`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`
+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;
+set optimizer_switch=@tmp11867_optimizer_switch;
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'));
@@ -4294,7 +4428,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 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 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
+Note 1003 select 2 AS `2` from `test`.`t1` where exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a));
@@ -4306,7 +4440,7 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists((select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) union (select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))))
+Note 1003 select 2 AS `2` from `test`.`t1` where exists((select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) union (select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
DROP TABLE t1,t2;
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
@@ -4384,13 +4518,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.
@@ -5510,6 +5644,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: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
@@ -5532,24 +5827,30 @@ ON t2.f10 = t3.f10
f1
DROP TABLE t1,t2,t3;
#
-# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+# 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 ( 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;
+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.
#
@@ -5668,8 +5969,59 @@ id select_type table type possible_keys key key_len ref rows Extra
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: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%'
-0
+1
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
index e1caa60bfc0..5130442b56d 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -3,7 +3,7 @@ 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");
+"semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=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)
@@ -56,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 dual having ((select 1) = 1)
+Note 1003 select 1 AS `1` from dual having (<expr_cache><1>((select 1)) = 1)
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
1
1
@@ -230,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
@@ -276,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`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`)))
+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
@@ -320,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 (select 2 from dual 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 <expr_cache><`test`.`t2`.`a`>((select 2 from dual 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));
@@ -338,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 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 <expr_cache><`test`.`t6`.`clinic_uq`>(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;
@@ -368,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)
@@ -544,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 = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where multiple equal(1, `test`.`t1`.`numeropost`))))
+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);
@@ -752,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 <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 <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)))))
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
id
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
@@ -900,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`,<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`,<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`
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;
@@ -915,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`,<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`,<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'
@@ -1305,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 <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 <expr_cache><`test`.`t2`.`a`>(<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
@@ -1315,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 <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 <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`))))))
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
a
2
@@ -1326,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 <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 <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`)))))
drop table t1, t2, t3;
create table t1 (a int, b int, index a (a,b));
create table t2 (a int, index a (a));
@@ -1348,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 <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 <expr_cache><`test`.`t2`.`a`>(<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
@@ -1358,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 <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 <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`))))))
select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
a
2
@@ -1369,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 <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 <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`)))))
insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
@@ -1385,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 <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 <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`))))))
drop table t0, t1, t2, t3;
create table t1 (a int, b int);
create table t2 (a int, b int);
@@ -1476,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(<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(<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`
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`
+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`
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`
+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`
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`
+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 +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`,((select max(NULL) from `test`.`t2`) > `test`.`t3`.`a`)))
+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 +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`,((select min(NULL) from `test`.`t2`) <= `test`.`t3`.`a`)))
+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 +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`,(<max>(select NULL from `test`.`t2` group by 1) > `test`.`t3`.`a`)))
+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 +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`,(<min>(select NULL from `test`.`t2` group by 1) <= `test`.`t3`.`a`)))
+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);
@@ -1579,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`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= `test`.`t3`.`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());
@@ -1749,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(<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(<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`))))))))
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))))
+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)))))
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');
@@ -2292,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 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 <expr_cache><`test`.`up`.`a`>(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);
@@ -2763,6 +2894,8 @@ select * from (select max(fld) from t1) as foo;
max(fld)
1
drop table t1;
+set @tmp11867_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin_with_cache=off';
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');
@@ -2833,20 +2966,21 @@ 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`
+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 <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`,<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=@tmp11867_optimizer_switch;
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'));
@@ -4291,7 +4425,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 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 2 AS `2` from `test`.`t1` where exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))
+Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a));
@@ -4303,7 +4437,7 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select 2 AS `2` from `test`.`t1` where exists((select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) union (select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
+Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists((select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) union (select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))))
DROP TABLE t1,t2;
create table t0(a int);
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
@@ -4381,13 +4515,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 <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 <expr_cache><1>(<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))))
+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)))))
DROP TABLE t1;
#
# Bug#45061: Incorrectly market field caused wrong result.
@@ -5507,6 +5641,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: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
@@ -5529,24 +5824,30 @@ ON t2.f10 = t3.f10
f1
DROP TABLE t1,t2,t3;
#
-# Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+# 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 ( 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;
+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.
#
@@ -5665,5 +5966,56 @@ id select_type table type possible_keys key key_len ref rows Extra
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: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 85aa96df714..dddf5e2d8d6 100644
--- a/mysql-test/r/subselect_partial_match.result
+++ b/mysql-test/r/subselect_partial_match.result
@@ -3,11 +3,13 @@ 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";
-
+set @@optimizer_switch = "materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off";
+set @test_default_opt_switch = @@optimizer_switch;
+set @in_exists = "materialization=off,in_to_exists=on,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');
@@ -26,9 +28,9 @@ 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');
@@ -55,17 +57,532 @@ NULL 2 - 00 NULL
1 - 01 2 - 01 1
NULL NULL NULL
drop table t1, t2;
-
+-------------------------------------------------------------------------
+NULLs in the outer column, NULLs in the subquery, there is
+no value match in any column, but there is a partial match
+such that some of the matching NULLs are in the outer columns,
+the other NULLs are in the inner columns.
+-------------------------------------------------------------------------
+create table t1 (a1 char(1), a2 char(1), a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+insert into t1 values ('c', NULL, 'a');
+insert into t2 values (NULL, 'x', NULL);
+insert into t2 values (NULL, 'y', NULL);
+insert into t2 values ('o', 'z', 'p');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+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 3
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+c NULL a NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+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 3
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+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 3
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+c NULL a NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+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 3
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+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 t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+c NULL a NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+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 t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch = @test_default_opt_switch;
+drop table t1, t2;
+create table t1 (a1 char(1), a2 char(1) not null, a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+insert into t1 values (NULL, 'y', NULL);
+insert into t2 values ('v', 'x', NULL);
+insert into t2 values (NULL, 'y', 'w');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+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
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+NULL y NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+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
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+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
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+NULL y NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+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
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+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 t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+NULL y NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+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 t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch = @test_default_opt_switch;
+drop table t1, t2;
+-------------------------------------------------------------------------
+There is only one column in the subquery to complement the NULLs in the
+outer reference. It is a NULL column, so a match is guaranteed.
+-------------------------------------------------------------------------
+create table t1 (a1 char(1), a2 char(1), a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+insert into t1 values (NULL, 'g', NULL);
+insert into t2 values ('z', NULL, 'y');
+insert into t2 values (NULL, 'z', 'y');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+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
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+NULL g NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+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
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+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
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+NULL g NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+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
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+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 t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+NULL g NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+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 t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+set @@optimizer_switch = @test_default_opt_switch;
+drop table t1, t2;
+-------------------------------------------------------------------------
+The intersection of the NULL bitmaps is empty because the ranges
+of NULL bits do not overlap.
+-------------------------------------------------------------------------
+create table t1 (a1 char(1), a2 char(1), a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+insert into t1 values ('b', 'g', NULL);
+insert into t2 values ('z', NULL, 'y');
+insert into t2 values (NULL, 'z', 'y');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+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
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+b g NULL 0
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+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
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+b g NULL
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+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
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+b g NULL 0
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+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
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+b g NULL
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+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 t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+a1 a2 a3 in_res
+b g NULL 0
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+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 t2 ALL NULL NULL NULL NULL 2 Using where
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+a1 a2 a3
+b g NULL
+drop table t1, t2;
+-------------------------------------------------------------------------
+The intersection of the NULL bitmaps is non-empty, and there is a
+non-NULL column.
+-------------------------------------------------------------------------
+create table t1 (a1 char(1), a2 char(1), a3 char(1) not null, a4 char(10));
+create table t2 (b1 char(1), b2 char(1), b3 char(1), b4 char(1));
+insert into t1 values ('a', 'g', 'x', NULL);
+insert into t2 values ('z', NULL, 'y', 'x');
+insert into t2 values (NULL, NULL, 'x', 'y');
+insert into t2 values ('x', 'w', 'z', NULL);
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+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 t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+a g x NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+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 t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+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 t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+a g x NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+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 t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+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 t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+a g x NULL NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+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 t2 ALL NULL NULL NULL NULL 3 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+drop table t1, t2;
+-------------------------------------------------------------------------
+Value match in one row, but the NULL complement match in another.
+The result must be false.
+-------------------------------------------------------------------------
+create table t1 (a1 char(2), a2 char(1), a3 char(1) not null, a4 char(10));
+create table t2 (b1 char(2), b2 char(1), b3 char(1), b4 char(1));
+insert into t1 values ('99', NULL, 'j', 'f');
+insert into t2 values ('01', NULL, 'y', NULL);
+insert into t2 values ('02', NULL, 'x', 'y');
+insert into t2 values ('03', 'q', 'y', 'x');
+insert into t2 values (NULL, 'q', 'm', 'p');
+insert into t2 values ('m', 'z', 'j', NULL);
+insert into t2 values (NULL, 'z', 'b', NULL);
+insert into t2 values (NULL, 'z', 'a', NULL);
+insert into t2 values ('34', 'q', 'y', 'x');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+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 t2 ALL NULL NULL NULL NULL 8 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+99 NULL j f 0
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+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 t2 ALL NULL NULL NULL NULL 8 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+99 NULL j f
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+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 t2 ALL NULL NULL NULL NULL 8 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+99 NULL j f 0
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+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 t2 ALL NULL NULL NULL NULL 8 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+99 NULL j f
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+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 t2 ALL NULL NULL NULL NULL 8 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+99 NULL j f 0
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+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 t2 ALL NULL NULL NULL NULL 8 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+99 NULL j f
+drop table t1, t2;
+-------------------------------------------------------------------------
+Test the intersection of larger number of rows with NULL, such that
+the number is at the boundary 32. This test is based on the implementation
+of MY_BITMAP which uses 32 bit words, and the intersection operation works
+by intersecting the bitmap word by word.
+-------------------------------------------------------------------------
+create table t1 (a1 char(2), a2 char(2), a3 char(1), a4 char(10)) ENGINE=MyISAM;
+create table t2 (b1 char(2), b2 char(2), b3 char(1), b4 char(1)) ENGINE=MyISAM;
+insert into t1 values (NULL, '98', NULL, 'b');
+insert into t1 values (NULL, '99', NULL, 'c');
+insert into t2 values ('00', 'rr', 'y', NULL);
+insert into t2 values ('01', 'rr', 'y', NULL);
+insert into t2 values ('02', NULL, 'x', 'y');
+insert into t2 values ('03', 'qq', 'y', 'x');
+insert into t2 values ('04', 'qq', 'm', 'p');
+insert into t2 values ('05', 'rr', 'y', NULL);
+insert into t2 values ('06', NULL, 'x', 'y');
+insert into t2 values ('07', 'qq', 'y', 'x');
+insert into t2 values ('08', 'qq', 'm', 'q');
+insert into t2 values ('09', 'rr', 'y', NULL);
+insert into t2 values ('10', NULL, 'x', 'y');
+insert into t2 values ('11', 'qq', 'y', 'x');
+insert into t2 values ('12', 'qq', 'm', 'k');
+insert into t2 values ('13', 'rr', 'y', NULL);
+insert into t2 values ('14', NULL, 'x', 'y');
+insert into t2 values ('15', 'qq', 'y', 'x');
+insert into t2 values ('16', 'qq', 'm', 's');
+insert into t2 values ('17', 'rr', 'y', NULL);
+insert into t2 values ('18', NULL, 'x', 'y');
+insert into t2 values ('19', 'qq', 'y', 'x');
+insert into t2 values ('20', 'qq', 'm', 't');
+insert into t2 values ('21', 'rr', 'y', NULL);
+insert into t2 values ('22', NULL, 'x', 'y');
+insert into t2 values ('23', 'qq', 'y', 'x');
+insert into t2 values ('24', 'qq', 'm', 'u');
+insert into t2 values ('25', 'rr', 'y', NULL);
+insert into t2 values ('26', NULL, 'x', 'y');
+insert into t2 values ('27', 'qq', 'y', 'x');
+insert into t2 values ('28', 'qq', 'm', 'y');
+insert into t2 values ('29', 'rr', 'y', NULL);
+insert into t2 values ('30', NULL, 'x', 'z');
+insert into t2 values ('31', 'ss', 'h', NULL);
+insert into t2 values ('32', 'vv', 'i', NULL);
+the only partial matching row
+insert into t2 values ('33', NULL, 'j', NULL);
+insert into t2 values ('34', 'qq', 'y', 'x');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b NULL
+NULL 99 NULL c NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b NULL
+NULL 99 NULL c NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b NULL
+NULL 99 NULL c NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+change the mathcing row to be the last one in the first bitmap word
+update t2 set b2 = 'zz' where b1 = 33;
+update t2 set b2 = NULL where b1 = 31;
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b NULL
+NULL 99 NULL c NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b NULL
+NULL 99 NULL c NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b NULL
+NULL 99 NULL c NULL
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 35 Using where
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+a1 a2 a3 a4
+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');
@@ -98,9 +615,9 @@ 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);
@@ -149,9 +666,9 @@ 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');
@@ -174,9 +691,9 @@ 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');
@@ -198,6 +715,32 @@ a1 a2 a3 in_res
1 - 00 2 - 00 3 - 00 NULL
1 - 01 2 - 01 3 - 01 NULL
drop table t1, t2;
+-------------------------------------------------------------------------
+Small buffer for the rowid_merge partial match algorithm that forces
+reverting to table scan partial match.
+-------------------------------------------------------------------------
+set @save_rowid_merge_buff_size = @@rowid_merge_buff_size;
+set @@rowid_merge_buff_size = 0;
+create table t1 (a1 char(2), a2 char(2), a3 char(1), a4 char(10));
+create table t2 (b1 char(2), b2 char(2), b3 char(1), b4 char(1));
+insert into t1 values (NULL, '98', NULL, 'b');
+insert into t1 values (NULL, '99', NULL, 'c');
+insert into t2 values ('00', 'rr', 'y', NULL);
+insert into t2 values ('01', 'rr', 'y', NULL);
+insert into t2 values ('02', NULL, 'x', 'y');
+insert into t2 values ('03', 'qq', 'y', 'x');
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res 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 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 4 Using where
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+a1 a2 a3 a4 in_res
+NULL 98 NULL b 0
+NULL 99 NULL c 0
+drop table t1, t2;
+set @@rowid_merge_buff_size = @save_rowid_merge_buff_size;
-------------------------------
Part 2: Test cases for bugs.
-------------------------------
@@ -348,4 +891,61 @@ 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;
+#
+# LP BUG#869036 Wrong result with in_to_exists=ON and NOT IN
+#
+create table outer_sq (f1 char(1), f2 char(1));
+insert into outer_sq values (NULL, 'c'), ('g', 'c');
+create table inner_sq (f3 char(1), f4 char(1));
+insert into inner_sq values(null, 'i'), ('v', null);
+All three strategies below must produce the same result.
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+SELECT outer_sq.*, (f1, f2) IN (select * from inner_sq) from outer_sq;
+f1 f2 (f1, f2) IN (select * from inner_sq)
+NULL c NULL
+g c 0
+SELECT * from outer_sq where (f1, f2) NOT IN (select * from inner_sq);
+f1 f2
+g c
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=off,partial_match_table_scan=on';
+SELECT outer_sq.*, (f1, f2) IN (select * from inner_sq) from outer_sq;
+f1 f2 (f1, f2) IN (select * from inner_sq)
+NULL c NULL
+g c 0
+SELECT * from outer_sq where (f1, f2) NOT IN (select * from inner_sq);
+f1 f2
+g c
+set @@optimizer_switch='in_to_exists=on,materialization=off';
+SELECT outer_sq.*, (f1, f2) IN (select * from inner_sq) from outer_sq;
+f1 f2 (f1, f2) IN (select * from inner_sq)
+NULL c NULL
+g c 0
+SELECT * from outer_sq where (f1, f2) NOT IN (select * from inner_sq);
+f1 f2
+g c
+drop table outer_sq, inner_sq;
set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/subselect_sj.result b/mysql-test/r/subselect_sj.result
index c1ed2a03973..42f8f3ca009 100644
--- a/mysql-test/r/subselect_sj.result
+++ b/mysql-test/r/subselect_sj.result
@@ -1,4 +1,4 @@
-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;
@@ -726,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 int_key,datetime_key NULL NULL NULL 20 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY it2 ALL int_key,datetime_key NULL NULL NULL 20 Using where; End temporary
DROP TABLE ot1, it1, it2;
# End of BUG#38075
#
@@ -761,11 +761,11 @@ 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` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`c`) and <nop>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`))))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`c`) and <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))))))
show warnings;
Level Code Message
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` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`c`) and <nop>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`))))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`c`) and <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))))))
select a from t1
where a in (select c from t2 where d >= some(select e from t3 where b=e));
a
@@ -1047,8 +1047,8 @@ AND t1.val IN (SELECT t3.val FROM t3
WHERE t3.val LIKE 'a%' OR t3.val LIKE 'e%');
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Start temporary
-1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
-1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t3 ALL NULL NULL NULL NULL 5 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; End temporary
SELECT *
FROM t1
WHERE t1.val IN (SELECT t2.val FROM t2
@@ -1238,7 +1238,7 @@ A.t1field IN (SELECT C.t2field FROM t2 C
WHERE C.t2field IN (SELECT D.t2field FROM t2 D));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY A index PRIMARY PRIMARY 4 NULL 3 Using index; Start temporary
-1 PRIMARY B index NULL PRIMARY 4 NULL 3 Using index; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY B index NULL PRIMARY 4 NULL 3 Using index; End temporary
1 PRIMARY C eq_ref PRIMARY PRIMARY 4 test.A.t1field 1 Using index
1 PRIMARY D eq_ref PRIMARY PRIMARY 4 test.A.t1field 1 Using index
SELECT * FROM t1 A
@@ -1268,8 +1268,8 @@ where A.a = B.a and A.a in (select a from t2 C) and B.a in (select a from t2 D);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY A ALL NULL NULL NULL NULL 3 Start temporary
1 PRIMARY B ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
-1 PRIMARY C ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
-1 PRIMARY D ALL NULL NULL NULL NULL 3 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY C ALL NULL NULL NULL NULL 3 Using where
+1 PRIMARY D ALL NULL NULL NULL NULL 3 Using where; End temporary
drop table t1, t2;
#
# BUG#784441: Abort on semijoin with a view as the inner table
@@ -1388,7 +1388,7 @@ 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 t2 ALL NULL NULL NULL NULL 2 Using where
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
@@ -1442,7 +1442,7 @@ 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 t1 ALL NULL NULL NULL NULL 4 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 t2 on t1.a=t2.a);
a
@@ -1501,7 +1501,7 @@ 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 t1 ALL NULL NULL NULL NULL 4 Using where
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
@@ -1519,7 +1519,7 @@ 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 t1 ALL NULL NULL NULL NULL 4 Using where
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
@@ -1674,8 +1674,6 @@ 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
@@ -1694,6 +1692,8 @@ f10 f10 f11 f10
0 0 b 0
0 0 a 0
0 0 a 0
+0 0 b 0
+0 0 b 0
drop table t1,t2,t3,t4;
#
# BUG#803457: Wrong result with semijoin + view + outer join in maria-5.3-subqueries-mwl90
@@ -1716,7 +1716,7 @@ 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)
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; End temporary
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
@@ -1739,4 +1739,325 @@ 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
+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
+1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary
+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 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;
+#
+# Bug #889750: semijoin=on + firstmatch=off + semijoin_with_cache=off
+#
+create table t1 (a int);
+insert into t1 values (7), (1), (5), (3);
+create table t2 (a int);
+insert into t2 values (4), (1), (8), (3), (9), (2);
+set @tmp_otimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=on';
+set optimizer_switch='firstmatch=off';
+set optimizer_switch='semijoin_with_cache=on';
+explain
+select * from t1 where t1.a in (select t2.a from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+select * from t1 where t1.a in (select t2.a from t2);
+a
+1
+3
+set optimizer_switch='semijoin_with_cache=off';
+explain
+select * from t1 where t1.a in (select t2.a from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; End temporary
+select * from t1 where t1.a in (select t2.a from t2);
+a
+1
+3
+set optimizer_switch= @tmp_otimizer_switch;
+drop table t1,t2;
set optimizer_switch=@subselect_sj_tmp;
diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result
index ce16f3b95ba..b410df3bab9 100644
--- a/mysql-test/r/subselect_sj2.result
+++ b/mysql-test/r/subselect_sj2.result
@@ -16,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
@@ -33,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
@@ -51,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
@@ -58,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;
@@ -417,6 +431,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 +440,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,4 +759,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
+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 4489b0dad25..f47fa06996e 100644
--- a/mysql-test/r/subselect_sj2_jcl6.result
+++ b/mysql-test/r/subselect_sj2_jcl6.result
@@ -25,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
@@ -42,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
@@ -60,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
@@ -67,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;
@@ -426,6 +440,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
@@ -433,12 +448,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:
@@ -755,6 +770,120 @@ 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';
diff --git a/mysql-test/r/subselect_sj2_mat.result b/mysql-test/r/subselect_sj2_mat.result
index 8cd0101278c..a07f43dd288 100644
--- a/mysql-test/r/subselect_sj2_mat.result
+++ b/mysql-test/r/subselect_sj2_mat.result
@@ -18,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
@@ -35,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
@@ -54,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;
@@ -103,9 +117,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
@@ -275,7 +288,7 @@ 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
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 9 func 1
+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
@@ -429,6 +442,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
@@ -437,11 +451,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
@@ -590,7 +604,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);
@@ -757,6 +771,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
+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%';
diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result
index 10a1cb47cf1..17ed56092c3 100644
--- a/mysql-test/r/subselect_sj_jcl6.result
+++ b/mysql-test/r/subselect_sj_jcl6.result
@@ -9,7 +9,7 @@ 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;
@@ -772,11 +772,11 @@ 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` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`c`) and <nop>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`))))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`c`) and <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))))))
show warnings;
Level Code Message
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` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`c`) and <nop>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`))))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`c`) and <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))))))
select a from t1
where a in (select c from t2 where d >= some(select e from t3 where b=e));
a
@@ -1750,6 +1750,327 @@ 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 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;
+#
+# Bug #889750: semijoin=on + firstmatch=off + semijoin_with_cache=off
+#
+create table t1 (a int);
+insert into t1 values (7), (1), (5), (3);
+create table t2 (a int);
+insert into t2 values (4), (1), (8), (3), (9), (2);
+set @tmp_otimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=on';
+set optimizer_switch='firstmatch=off';
+set optimizer_switch='semijoin_with_cache=on';
+explain
+select * from t1 where t1.a in (select t2.a from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+select * from t1 where t1.a in (select t2.a from t2);
+a
+1
+3
+set optimizer_switch='semijoin_with_cache=off';
+explain
+select * from t1 where t1.a in (select t2.a from t2);
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Start temporary
+1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; End temporary
+select * from t1 where t1.a in (select t2.a from t2);
+a
+1
+3
+set optimizer_switch= @tmp_otimizer_switch;
+drop table t1,t2;
set optimizer_switch=@subselect_sj_tmp;
#
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
@@ -1758,6 +2079,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 97754415504..350d3fe62d7 100644
--- a/mysql-test/r/subselect_sj_mat.result
+++ b/mysql-test/r/subselect_sj_mat.result
@@ -1,8 +1,8 @@
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=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=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, 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;
@@ -349,7 +349,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` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (<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 <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`)))))) and (`test`.`t3`.`c2` > '0'))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3`.`c2` > '0'))
select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 where c2 LIKE '%02') or
@@ -375,7 +375,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
3 DEPENDENT SUBQUERY t3a ALL NULL NULL NULL NULL 4 100.00 Using where
Warnings:
Note 1276 Field or reference 'test.t1.a1' of SELECT #3 was resolved in SELECT #1
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b2` = `test`.`t3c`.`c2`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b1` = `test`.`t3c`.`c1`) and (<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 <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`)))))) and (`test`.`t3c`.`c2` > '0'))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b2` = `test`.`t3c`.`c2`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b1` = `test`.`t3c`.`c1`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3c`.`c2` > '0'))
select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 t3a where c1 = a1) or
@@ -414,7 +414,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
9 SUBQUERY t3i index it3i1,it3i2,it3i3 # # # 4 75.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 <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<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 <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`) semi join (`test`.`t2i` join `test`.`t3`) join `test`.`t1` where ((`test`.`t3`.`c2` = `<subquery2>`.`b2`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`) and (`test`.`t2i`.`b2` = `<subquery2>`.`b2`) and (`test`.`t3`.`c1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t2i`.`b1` = `<subquery2>`.`b1`) and (`<subquery2>`.`b2` > '0'))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where ((`test`.`t3i`.`c2` = `test`.`t2i`.`b2`) and (`test`.`t3i`.`c1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` > '0') and (`test`.`t2i`.`b2` > '0')))
+Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <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`) semi join (`test`.`t2i` join `test`.`t3`) join `test`.`t1` where ((`test`.`t3`.`c2` = `<subquery2>`.`b2`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`) and (`test`.`t2i`.`b2` = `<subquery2>`.`b2`) and (`test`.`t3`.`c1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t2i`.`b1` = `<subquery2>`.`b1`) and (`<subquery2>`.`b2` > '0'))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where ((`test`.`t3i`.`c2` = `test`.`t2i`.`b2`) and (`test`.`t3i`.`c1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` > '0') and (`test`.`t2i`.`b2` > '0')))
(select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 where c2 LIKE '%02') or
@@ -444,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 <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
@@ -468,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 <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
@@ -490,7 +490,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`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t3` where <in_optimizer>(`test`.`t3`.`c1`,<exists>(select `test`.`t1`.`a1` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t3`.`c1`) = `test`.`t1`.`a1`)) union select `test`.`t2`.`b1` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t3`.`c1`) = `test`.`t2`.`b1`))))
+Note 1003 select `test`.`t3`.`c1` AS `c1`,`test`.`t3`.`c2` AS `c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`>(<in_optimizer>(`test`.`t3`.`c1`,<exists>(select `test`.`t1`.`a1` from `test`.`t1` where ((`test`.`t1`.`a1` > '0') and (<cache>(`test`.`t3`.`c1`) = `test`.`t1`.`a1`)) union select `test`.`t2`.`b1` from `test`.`t2` where ((`test`.`t2`.`b1` < '9') and (<cache>(`test`.`t3`.`c1`) = `test`.`t2`.`b1`)))))
select * from t3
where c1 in (select a1 from t1 where a1 > '0' UNION select b1 from t2 where b1 < '9');
c1 c2
@@ -514,14 +514,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` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2i`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t3c`.`c2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t3c`.`c1` = `test`.`t1`.`a1`) and (<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 <in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`)))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2i`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t3c`.`c2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t3c`.`c1` = `test`.`t1`.`a1`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))))
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 <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
@@ -531,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 <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
@@ -563,7 +563,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 temporary; Using filesort
2 DEPENDENT SUBQUERY columns unique_subquery PRIMARY PRIMARY 4 func 1 100.00 Using index; Using where; Full scan on NULL key
Warnings:
-Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` group by <in_optimizer>(`test`.`t1`.`a1`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`a1`) in columns on PRIMARY where trigcond((<cache>(`test`.`t1`.`a1`) = `test`.`columns`.`col`)))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` group by <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,<exists>(<primary_index_lookup>(<cache>(`test`.`t1`.`a1`) in columns on PRIMARY where trigcond((<cache>(`test`.`t1`.`a1`) = `test`.`columns`.`col`))))))
select * from t1 group by (a1 in (select col from columns));
a1 a2
1 - 00 2 - 00
@@ -646,7 +646,7 @@ from t1_16
where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
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
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 20 func 1 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 20 func 1 100.00 Using where
2 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` semi join (`test`.`t2_16`) where ((`test`.`t2_16`.`b1` > '0') and (`test`.`t1_16`.`a1` = substr(`test`.`t2_16`.`b1`,1,16)))
@@ -663,7 +663,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 filesort
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 <in_optimizer>(`test`.`t1_16`.`a1`,<exists>(select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2` having (<cache>(`test`.`t1_16`.`a1`) = <ref_null_helper>(group_concat(`test`.`t2_16`.`b1` separator ',')))))
+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`>(<in_optimizer>(`test`.`t1_16`.`a1`,<exists>(select group_concat(`test`.`t2_16`.`b1` separator ',') from `test`.`t2_16` group by `test`.`t2_16`.`b2` having (<cache>(`test`.`t1_16`.`a1`) = <ref_null_helper>(group_concat(`test`.`t2_16`.`b1` separator ','))))))
select left(a1,7), left(a2,7)
from t1_16
where a1 in (select group_concat(b1) from t2_16 group by b2);
@@ -761,7 +761,7 @@ from t1_512
where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
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
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 517 func 1 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 517 func 1 100.00 Using where
2 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` semi join (`test`.`t2_512`) where ((`test`.`t2_512`.`b1` > '0') and (`test`.`t1_512`.`a1` = substr(`test`.`t2_512`.`b1`,1,512)))
@@ -856,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 13 func,func 1 100.00
-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);
@@ -950,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 13 func,func 1 100.00
-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);
@@ -1118,7 +1120,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`))))))
select a from t1 group by a having a in (select c from t2 where d >= 20);
a
2
@@ -1130,7 +1132,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`)))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` group by `test`.`t1`.`a` having <expr_cache><`test`.`t1`.`a`>(<in_optimizer>(`test`.`t1`.`a`,`test`.`t1`.`a` in ( <materialize> (select `test`.`t2`.`c` from `test`.`t2` where (`test`.`t2`.`d` >= 20) ), <primary_index_lookup>(`test`.`t1`.`a` in <temporary table> on distinct_key where ((`test`.`t1`.`a` = `<subquery2>`.`c`))))))
select a from t1 group by a having a in (select c from t2 where d >= 20);
a
2
@@ -1144,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 <in_optimizer>(`test`.`t1`.`a`,<exists>(select `test`.`t2`.`c` from `test`.`t2` where (<nop>(<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
@@ -1159,7 +1161,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` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`c`) and <nop>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`))))))
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`a` = `test`.`t2`.`c`) and <nop>(<expr_cache><`test`.`t2`.`d`,`test`.`t1`.`b`>(<in_optimizer>(`test`.`t2`.`d`,<exists>(select `test`.`t3`.`e` from `test`.`t3` where ((`test`.`t1`.`b` = `test`.`t3`.`e`) and (<cache>(`test`.`t2`.`d`) >= `test`.`t3`.`e`)))))))
select a from t1
where a in (select c from t2 where d >= some(select e from t3 where b=e));
a
@@ -1235,7 +1237,7 @@ insert into t1 values ('aa', 'aaaa');
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 NULL NULL NULL NULL 2
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1 Using where
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
select a,b from t1 where b in (select a from t1);
a b
@@ -1600,4 +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/system_mysql_db.result b/mysql-test/r/system_mysql_db.result
index 033659ba5d7..d5409136ed4 100644
--- a/mysql-test/r/system_mysql_db.result
+++ b/mysql-test/r/system_mysql_db.result
@@ -119,7 +119,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(64) CHARACTER SET latin1 NOT NULL DEFAULT '',
`authentication_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 3ad02914ca8..892ac29d6d5 100644
--- a/mysql-test/r/table_elim.result
+++ b/mysql-test/r/table_elim.result
@@ -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
@@ -566,3 +567,22 @@ id select_type table type possible_keys key key_len ref rows Extra
# ^^ The above must not produce a QEP of t3,t5,t2,t4
# as that violates the "no interleaving of outer join nests" rule.
DROP TABLE t1,t2,t3,t4,t5;
+#
+# BUG#884184: Wrong result with RIGHT JOIN + derived_merge
+#
+CREATE TABLE t1 (a int(11), b varchar(1)) ;
+INSERT IGNORE INTO t1 VALUES (0,'g');
+CREATE TABLE t3 ( a varchar(1)) ;
+INSERT IGNORE INTO t3 VALUES ('g');
+CREATE TABLE t2 ( a int(11) NOT NULL, PRIMARY KEY (a)) ;
+create view v1 as SELECT t1.* FROM t1 LEFT JOIN t2 ON ( t1.a = t2.a ) WHERE t2.a <> 0;
+SELECT alias1.* FROM t3 LEFT JOIN v1 as alias1 ON ( t3.a = alias1.b );
+a b
+NULL NULL
+EXPLAIN SELECT alias1.* FROM t3 LEFT JOIN v1 as alias1 ON ( t3.a = alias1.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 t1 ALL NULL NULL NULL NULL 1 Using where
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using index
+drop view v1;
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index faea2e791d5..daddbe5ceca 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -2098,6 +2098,25 @@ 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.
#
# Bug#34453 Can't change size of file (Errcode: 1224)
#
@@ -2181,7 +2200,6 @@ trigger_name
# Clean-up.
drop temporary table t1;
drop table t1;
-
#
# Bug #12362125: SP INOUT HANDLING IS BROKEN FOR TEXT TYPE.
#
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index e04cd76d2ba..ff052101753 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -514,11 +514,10 @@ 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
+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 dual where <in_optimizer>(1,<exists>(select `test`.`x1`.`id` from `test`.`t1` `x1` where 0))
+Note 1003 select 1 AS `id`,'2007-04-25 18:30:22' AS `cur_date` from (dual) 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
@@ -526,11 +525,10 @@ 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
+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 dual where <in_optimizer>(1,<exists>(select `test`.`x1`.`id` from `test`.`t2` `x1` where 0))
+Note 1003 select 1 AS `id`,'2007-04-25' AS `cur_date` from (dual) 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
@@ -540,11 +538,11 @@ 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
+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
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 <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`))))
+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
@@ -552,11 +550,11 @@ 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
+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
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 <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`))))
+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
diff --git a/mysql-test/r/user_limits.result b/mysql-test/r/user_limits.result
index 80ec5517b16..688704f528a 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: SESSION variable 'max_user_connections' is read-only. Use SET GLOBAL to assign the value
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.result b/mysql-test/r/variables.result
index 68b0e04d89c..8cc51cc86ac 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"
@@ -1047,7 +1049,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;
@@ -1066,6 +1068,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';
Variable_name Value
table_definition_cache #
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index e057a3d2630..f48d65c2dc0 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -4446,7 +4446,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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` where (not(<in_optimizer>(10,<exists>(select NULL from `test`.`t4` where ((`test`.`t4`.`a` >= `test`.`t1`.`a`) and trigcond(((<cache>(10) = NULL) or <cache>(isnull(NULL))))) having trigcond(<is_not_null_test>(NULL))))))
+Note 1003 select `test`.`t1`.`a` AS `a`,10 AS `a` from `test`.`t1` where (not(<expr_cache><10,`test`.`t1`.`a`>(<in_optimizer>(10,<exists>(select NULL from `test`.`t4` where ((`test`.`t4`.`a` >= `test`.`t1`.`a`) and trigcond(((<cache>(10) = NULL) or <cache>(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);
@@ -4462,7 +4462,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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` where (not(<in_optimizer>(10,<exists>(select NULL from `test`.`t4` where ((`test`.`t4`.`a` >= `test`.`t1`.`a`) and trigcond(((<cache>(10) = NULL) or <cache>(isnull(NULL))))) having trigcond(<is_not_null_test>(NULL))))))
+Note 1003 select `test`.`t1`.`a` AS `a`,10 AS `a` from `test`.`t1` where (not(<expr_cache><10,`test`.`t1`.`a`>(<in_optimizer>(10,<exists>(select NULL from `test`.`t4` where ((`test`.`t4`.`a` >= `test`.`t1`.`a`) and trigcond(((<cache>(10) = NULL) or <cache>(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);
@@ -4547,3 +4547,23 @@ UNLOCK TABLES;
# Connection default
DROP PROCEDURE p1;
DROP TABLE t1;
+#
+# lp: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/r/xtradb_mrr.result b/mysql-test/r/xtradb_mrr.result
index 3f686f1abaf..785fa0174dd 100644
--- a/mysql-test/r/xtradb_mrr.result
+++ b/mysql-test/r/xtradb_mrr.result
@@ -186,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
@@ -208,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
@@ -871,6 +871,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');
diff --git a/mysql-test/suite/binlog/r/binlog_row_annotate.result b/mysql-test/suite/binlog/r/binlog_row_annotate.result
index 9442dd63efb..0c008661784 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/r/innodb_func_view.result b/mysql-test/suite/funcs_1/r/innodb_func_view.result
index cea131523e8..29a2a2aa861 100644
--- a/mysql-test/suite/funcs_1/r/innodb_func_view.result
+++ b/mysql-test/suite/funcs_1/r/innodb_func_view.result
@@ -3716,8 +3716,8 @@ NULL 1.7976931348623e308 3
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 2
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 3
+Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 1
DROP VIEW v1;
@@ -4068,10 +4068,10 @@ NULL 1.7976931348623e308 3
NULL -1 5
NULL 200506271758 19
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 2
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 3
-Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 5
-Warning 1292 Incorrect datetime value: '200506271758' for column 'my_double' at row 19
+Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '200506271758' for column 'my_double' at row 1
DROP VIEW v1;
@@ -4429,9 +4429,9 @@ NULL 1.7976931348623e308 3
NULL -1 5
2005-06-27 20050627 13
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 2
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 3
-Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 5
+Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 1
DROP VIEW v1;
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 417228db52d..4eff12dab7b 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
@@ -205,7 +205,7 @@ def mysql user Lock_tables_priv 21 N NO enum 1 3 NULL NULL NULL utf8 utf8_genera
def mysql user max_connections 39 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references
def mysql user max_questions 37 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references
def mysql user max_updates 38 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references
-def mysql user max_user_connections 40 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) unsigned select,insert,update,references
+def mysql user max_user_connections 40 0 NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
def mysql user Password 3 NO char 41 41 NULL NULL NULL latin1 latin1_bin char(41) select,insert,update,references
def mysql user plugin 41 NO char 64 64 NULL NULL NULL latin1 latin1_swedish_ci char(64) select,insert,update,references
def mysql user Process_priv 12 N NO enum 1 3 NULL NULL NULL utf8 utf8_general_ci enum('N','Y') select,insert,update,references
@@ -515,6 +515,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 64 64 latin1 latin1_swedish_ci char(64)
1.0000 mysql user authentication_string text 65535 65535 utf8 utf8_bin text
diff --git a/mysql-test/suite/funcs_1/r/memory_func_view.result b/mysql-test/suite/funcs_1/r/memory_func_view.result
index 23aba87e7bf..d8f26c81e58 100644
--- a/mysql-test/suite/funcs_1/r/memory_func_view.result
+++ b/mysql-test/suite/funcs_1/r/memory_func_view.result
@@ -3717,8 +3717,8 @@ NULL 1.7976931348623e308 3
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 2
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 3
+Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 1
DROP VIEW v1;
@@ -4069,10 +4069,10 @@ NULL 1.7976931348623e308 3
NULL -1 5
NULL 200506271758 19
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 2
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 3
-Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 5
-Warning 1292 Incorrect datetime value: '200506271758' for column 'my_double' at row 6
+Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '200506271758' for column 'my_double' at row 1
DROP VIEW v1;
@@ -4430,9 +4430,9 @@ NULL 1.7976931348623e308 3
NULL -1 5
2005-06-27 20050627 13
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 2
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 3
-Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 5
+Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 1
DROP VIEW v1;
diff --git a/mysql-test/suite/funcs_1/r/myisam_func_view.result b/mysql-test/suite/funcs_1/r/myisam_func_view.result
index 23aba87e7bf..d8f26c81e58 100644
--- a/mysql-test/suite/funcs_1/r/myisam_func_view.result
+++ b/mysql-test/suite/funcs_1/r/myisam_func_view.result
@@ -3717,8 +3717,8 @@ NULL 1.7976931348623e308 3
-00:00:01 -1 5
00:17:58 1758 25
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 2
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 3
+Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 1
DROP VIEW v1;
@@ -4069,10 +4069,10 @@ NULL 1.7976931348623e308 3
NULL -1 5
NULL 200506271758 19
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 2
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 3
-Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 5
-Warning 1292 Incorrect datetime value: '200506271758' for column 'my_double' at row 6
+Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '200506271758' for column 'my_double' at row 1
DROP VIEW v1;
@@ -4430,9 +4430,9 @@ NULL 1.7976931348623e308 3
NULL -1 5
2005-06-27 20050627 13
Warnings:
-Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 2
-Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 3
-Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 5
+Warning 1292 Incorrect datetime value: '-1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '1.7976931348623e308' for column 'my_double' at row 1
+Warning 1292 Incorrect datetime value: '-1' for column 'my_double' at row 1
DROP VIEW v1;
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index 5f37ae6e2c6..efb47f65e6d 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -785,7 +785,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');
diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
index b8b507112b7..44cd2bd9573 100644
--- a/mysql-test/suite/innodb/t/innodb.test
+++ b/mysql-test/suite/innodb/t/innodb.test
@@ -532,6 +532,7 @@ 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);
--replace_column 9 #
+--replace_result "Using where" "Using index condition"
explain select * from t1 where a > 0 and a < 50;
drop table t1;
diff --git a/mysql-test/suite/maria/r/maria.result b/mysql-test/suite/maria/r/maria.result
index 7baf561eea3..320c081382f 100644
--- a/mysql-test/suite/maria/r/maria.result
+++ b/mysql-test/suite/maria/r/maria.result
@@ -361,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;
@@ -372,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 Index_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
@@ -397,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 where
+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 where
+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));
diff --git a/mysql-test/suite/maria/r/maria3.result b/mysql-test/suite/maria/r/maria3.result
index fce5fa61034..21de234dad6 100644
--- a/mysql-test/suite/maria/r/maria3.result
+++ b/mysql-test/suite/maria/r/maria3.result
@@ -304,6 +304,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/t/maria.test b/mysql-test/suite/maria/t/maria.test
index 9d04e564e56..b371394b2b3 100644
--- a/mysql-test/suite/maria/t/maria.test
+++ b/mysql-test/suite/maria/t/maria.test
@@ -386,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/optimizer_unfixed_bugs/r/bug45219.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug45219.result
index e3cee8cd055..1335120b6b0 100644
--- a/mysql-test/suite/optimizer_unfixed_bugs/r/bug45219.result
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug45219.result
@@ -56,27 +56,6 @@ WHERE ( `int_nokey` , `pk` ) IN (
SELECT INNR .`pk` , INNR .`pk`
FROM CC LEFT JOIN BB INNR ON INNR .`varchar_key` ) AND `pk` = 9 ;
datetime_key
-Warnings:
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
-Warning 1292 Truncated incorrect DOUBLE value: 'i'
DROP TABLE CC, C, BB;
DROP TABLE IF EXISTS CC, C, BB;
CREATE TABLE `CC` (
diff --git a/mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result b/mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result
index 060955d84a4..657f1f57b2d 100644
--- a/mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result
+++ b/mysql-test/suite/optimizer_unfixed_bugs/r/bug45221.result
@@ -25,10 +25,10 @@ SELECT `int_key`
FROM CC
WHERE `date_nokey` < `datetime_nokey` XOR OUTR .`date_nokey` ) ;
pk
+9
2
5
6
-9
SELECT `pk`
FROM C
WHERE `pk` IN (
@@ -36,11 +36,11 @@ SELECT `int_key`
FROM CC
WHERE `date_nokey` < `datetime_nokey` XOR '2009-11-25' ) ;
pk
+9
2
-4
5
6
-9
+4
Warnings:
Warning 1292 Truncated incorrect INTEGER value: '2009-11-25'
Warning 1292 Truncated incorrect INTEGER value: '2009-11-25'
@@ -52,6 +52,12 @@ Warning 1292 Truncated incorrect INTEGER value: '2009-11-25'
Warning 1292 Truncated incorrect INTEGER value: '2009-11-25'
Warning 1292 Truncated incorrect INTEGER value: '2009-11-25'
Warning 1292 Truncated incorrect INTEGER value: '2009-11-25'
+Warning 1292 Truncated incorrect INTEGER value: '2009-11-25'
+Warning 1292 Truncated incorrect INTEGER value: '2009-11-25'
+Warning 1292 Truncated incorrect INTEGER value: '2009-11-25'
+Warning 1292 Truncated incorrect INTEGER value: '2009-11-25'
+Warning 1292 Truncated incorrect INTEGER value: '2009-11-25'
+Warning 1292 Truncated incorrect INTEGER value: '2009-11-25'
DROP TABLE CC;
DROP TABLE C;
CREATE TABLE `CC` (
diff --git a/mysql-test/suite/parts/r/partition_repair_myisam.result b/mysql-test/suite/parts/r/partition_repair_myisam.result
index 4b6d4dc6ec0..a9d7ce8aeb4 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 565a3bd1a58..9294b658595 100644
--- a/mysql-test/suite/pbxt/r/derived.result
+++ b/mysql-test/suite/pbxt/r/derived.result
@@ -190,13 +190,13 @@ pla_id test
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> ALL NULL $hj 7 test.m2.matintnum 9 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 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> ALL NULL $hj 7 test.m2.matintnum 9 Using where
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 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;
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_by.result b/mysql-test/suite/pbxt/r/group_by.result
index c2f31b2165b..b33c9ac87c2 100644
--- a/mysql-test/suite/pbxt/r/group_by.result
+++ b/mysql-test/suite/pbxt/r/group_by.result
@@ -1171,8 +1171,8 @@ id select_type table type possible_keys key key_len ref rows Extra
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
+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;
@@ -1184,6 +1184,6 @@ id select_type table type possible_keys key key_len ref rows Extra
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
+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;
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/mysqlshow.result b/mysql-test/suite/pbxt/r/mysqlshow.result
index 96e45e84b77..a8bd5904600 100644
--- a/mysql-test/suite/pbxt/r/mysqlshow.result
+++ b/mysql-test/suite/pbxt/r/mysqlshow.result
@@ -132,11 +132,11 @@ Database: information_schema
| INNODB_SYS_TABLES |
| INNODB_SYS_FIELDS |
| INNODB_SYS_COLUMNS |
-| INNODB_TABLE_STATS |
| INNODB_SYS_STATS |
| INNODB_SYS_FOREIGN |
| INNODB_SYS_INDEXES |
| XTRADB_ADMIN_COMMAND |
+| INNODB_TABLE_STATS |
+---------------------------------------+
Database: INFORMATION_SCHEMA
+---------------------------------------+
@@ -195,11 +195,11 @@ Database: INFORMATION_SCHEMA
| INNODB_SYS_TABLES |
| INNODB_SYS_FIELDS |
| INNODB_SYS_COLUMNS |
-| INNODB_TABLE_STATS |
| INNODB_SYS_STATS |
| INNODB_SYS_FOREIGN |
| INNODB_SYS_INDEXES |
| XTRADB_ADMIN_COMMAND |
+| INNODB_TABLE_STATS |
+---------------------------------------+
Wildcard: inf_rmation_schema
+--------------------+
diff --git a/mysql-test/suite/pbxt/r/subselect.result b/mysql-test/suite/pbxt/r/subselect.result
index f8f75a6f543..c012c2d1c29 100644
--- a/mysql-test/suite/pbxt/r/subselect.result
+++ b/mysql-test/suite/pbxt/r/subselect.result
@@ -50,7 +50,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 dual having ((select 1) = 1)
+Note 1003 select 1 AS `1` from dual having (<expr_cache><1>((select 1)) = 1)
SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1;
1
1
@@ -224,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
@@ -270,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`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`)))
+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
@@ -314,7 +314,7 @@ NULL UNION RESULT <union2,3> ALL 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 `test`.`t1`.`a` from `test`.`t1` where (`test`.`t1`.`a` = `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 <expr_cache><`test`.`t2`.`a`>((select `test`.`t1`.`a` from `test`.`t1` where (`test`.`t1`.`a` = `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));
@@ -332,7 +332,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 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 <expr_cache><`test`.`t6`.`clinic_uq`>(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;
@@ -362,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)
@@ -535,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 = (select max(`test`.`t1`.`numreponse`) from `test`.`t1` where multiple equal(1, `test`.`t1`.`numeropost`))))
+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);
@@ -743,7 +749,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 <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 <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)))))
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
id
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
@@ -893,7 +899,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`,<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`,<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`
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;
@@ -908,7 +914,7 @@ 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`,<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`,<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;
create table t1 (a float);
select 10.5 IN (SELECT * from t1 LIMIT 1);
@@ -1295,31 +1301,31 @@ a
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 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
+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`.`t2` where <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`.`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 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
+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`.`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`)))))
+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 NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
-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
+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`.`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`))))
+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));
@@ -1334,31 +1340,31 @@ a
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 NULL a 5 NULL 4 100.00 Using where; Using index
-2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1 100.00 Using index
+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 1 100.00 Using index; FirstMatch(t2)
Warnings:
-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)))
+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 NULL a 5 NULL 4 100.00 Using where; Using index
-2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1 100.00 Using index; Using where
+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 1 100.00 Using where; Using index; FirstMatch(t2)
Warnings:
-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`)))))
+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 NULL a 5 NULL 4 100.00 Using where; Using index
-2 DEPENDENT SUBQUERY t1 ref a a 5 func 1 100.00 Using where; Using index
-2 DEPENDENT SUBQUERY t3 ref a a 5 test.t1.b 1 100.00 Using index
+1 PRIMARY t2 index a a 5 NULL 4 100.00 Using where; Using index; Start temporary
+1 PRIMARY t1 ref a a 5 test.t2.a 1 100.00 Using index
+1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index; End temporary
Warnings:
-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`))))
+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`.`t3`.`a` = `test`.`t1`.`b`))
insert into t1 values (3,31);
select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
a
@@ -1371,10 +1377,10 @@ a
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 NULL a 5 NULL 4 100.00 Using where; Using index
-2 DEPENDENT SUBQUERY t1 index_subquery a a 5 func 1 100.00 Using index; Using where
+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 1 100.00 Using where; Using index; FirstMatch(t2)
Warnings:
-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`)))))
+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 t1, t2, t3;
create table t1 (a int, b int);
create table t2 (a int, b int);
@@ -1465,27 +1471,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(<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(<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`
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`
+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`
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`
+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`
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`
+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);
@@ -1498,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`,((select max(`test`.`t2`.`b`) from `test`.`t2`) > `test`.`t3`.`a`)))
+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);
@@ -1506,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`,((select min(`test`.`t2`.`b`) from `test`.`t2`) <= `test`.`t3`.`a`)))
+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
@@ -1517,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`,(<max>(select `test`.`t2`.`b` from `test`.`t2` group by 1) > `test`.`t3`.`a`)))
+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);
@@ -1525,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`,(<min>(select `test`.`t2`.`b` from `test`.`t2` group by 1) <= `test`.`t3`.`a`)))
+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);
@@ -1568,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`,(<max>(select max(`test`.`t2`.`b`) from `test`.`t2` group by `test`.`t2`.`a`) >= `test`.`t3`.`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());
@@ -1738,14 +1744,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(<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(<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`))))))))
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))))
+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)))))
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');
@@ -2282,7 +2288,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 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 <expr_cache><`test`.`up`.`a`>(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);
@@ -2825,19 +2831,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`,<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
+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` 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`))))
+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`
+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));
@@ -4220,8 +4226,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 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 1 Using index; 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));
@@ -4230,15 +4236,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 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t2 index_subquery I1 I1 4 func 1 Using index; 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 ALL NULL NULL NULL NULL 2 Using where
-2 DEPENDENT SUBQUERY t1 index_subquery I1 I1 2 func 1 Using index; 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;
@@ -4282,7 +4288,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t2 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 2 AS `2` from `test`.`t1` where exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))
+Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists(select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a));
@@ -4294,7 +4300,7 @@ NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL NULL
Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #1
-Note 1003 select 2 AS `2` from `test`.`t1` where exists((select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) union (select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)))
+Note 1003 select 2 AS `2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a`>(exists((select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) union (select 1 from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))))
DROP TABLE t1,t2;
create table t1(f11 int, f12 int);
create table t2(f21 int unsigned not null, f22 int, f23 varchar(10));
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/mysqlshow.test b/mysql-test/suite/pbxt/t/mysqlshow.test
index 41505cc0b10..b54eeaeab34 100644
--- a/mysql-test/suite/pbxt/t/mysqlshow.test
+++ b/mysql-test/suite/pbxt/t/mysqlshow.test
@@ -30,7 +30,9 @@ DROP TABLE t1, t2;
#
# Bug #19147: mysqlshow INFORMATION_SCHEMA does not work
#
+--sorted_result
--exec $MYSQL_SHOW information_schema
+--sorted_result
--exec $MYSQL_SHOW INFORMATION_SCHEMA
--exec $MYSQL_SHOW inf_rmation_schema
diff --git a/mysql-test/suite/pbxt/t/subselect.test b/mysql-test/suite/pbxt/t/subselect.test
index 891e23d923e..651f47fcee1 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/perfschema/r/pfs_upgrade.result b/mysql-test/suite/perfschema/r/pfs_upgrade.result
index b2e415637d9..a7c47d8d64a 100644
--- a/mysql-test/suite/perfschema/r/pfs_upgrade.result
+++ b/mysql-test/suite/perfschema/r/pfs_upgrade.result
@@ -25,7 +25,7 @@ ERROR 1050 (42S01) at line 427: Table 'setup_consumers' already exists
ERROR 1050 (42S01) at line 444: Table 'setup_instruments' already exists
ERROR 1050 (42S01) at line 460: Table 'setup_timers' already exists
ERROR 1050 (42S01) at line 477: Table 'threads' already exists
-ERROR 1644 (HY000) at line 1122: Unexpected content found in the performance_schema database.
+ERROR 1644 (HY000) at line 1125: Unexpected content found in the performance_schema database.
FATAL ERROR: Upgrade failed
show tables like "user_table";
Tables_in_performance_schema (user_table)
@@ -55,7 +55,7 @@ ERROR 1050 (42S01) at line 427: Table 'setup_consumers' already exists
ERROR 1050 (42S01) at line 444: Table 'setup_instruments' already exists
ERROR 1050 (42S01) at line 460: Table 'setup_timers' already exists
ERROR 1050 (42S01) at line 477: Table 'threads' already exists
-ERROR 1644 (HY000) at line 1122: Unexpected content found in the performance_schema database.
+ERROR 1644 (HY000) at line 1125: Unexpected content found in the performance_schema database.
FATAL ERROR: Upgrade failed
show tables like "user_view";
Tables_in_performance_schema (user_view)
@@ -83,7 +83,7 @@ ERROR 1050 (42S01) at line 427: Table 'setup_consumers' already exists
ERROR 1050 (42S01) at line 444: Table 'setup_instruments' already exists
ERROR 1050 (42S01) at line 460: Table 'setup_timers' already exists
ERROR 1050 (42S01) at line 477: Table 'threads' already exists
-ERROR 1644 (HY000) at line 1122: Unexpected content found in the performance_schema database.
+ERROR 1644 (HY000) at line 1125: Unexpected content found in the performance_schema database.
FATAL ERROR: Upgrade failed
select name from mysql.proc where db='performance_schema';
name
@@ -111,7 +111,7 @@ ERROR 1050 (42S01) at line 427: Table 'setup_consumers' already exists
ERROR 1050 (42S01) at line 444: Table 'setup_instruments' already exists
ERROR 1050 (42S01) at line 460: Table 'setup_timers' already exists
ERROR 1050 (42S01) at line 477: Table 'threads' already exists
-ERROR 1644 (HY000) at line 1122: Unexpected content found in the performance_schema database.
+ERROR 1644 (HY000) at line 1125: Unexpected content found in the performance_schema database.
FATAL ERROR: Upgrade failed
select name from mysql.proc where db='performance_schema';
name
@@ -139,7 +139,7 @@ ERROR 1050 (42S01) at line 427: Table 'setup_consumers' already exists
ERROR 1050 (42S01) at line 444: Table 'setup_instruments' already exists
ERROR 1050 (42S01) at line 460: Table 'setup_timers' already exists
ERROR 1050 (42S01) at line 477: Table 'threads' already exists
-ERROR 1644 (HY000) at line 1122: Unexpected content found in the performance_schema database.
+ERROR 1644 (HY000) at line 1125: Unexpected content found in the performance_schema database.
FATAL ERROR: Upgrade failed
select name from mysql.event where db='performance_schema';
name
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 eb421d1adc4..80a3240021a 100644
--- a/mysql-test/suite/rpl/r/rpl_stm_000001.result
+++ b/mysql-test/suite/rpl/r/rpl_stm_000001.result
@@ -49,7 +49,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_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 268a10ad1fa..16f89123d75 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/sys_vars/r/aria_checkpoint_log_activity_basic.result b/mysql-test/suite/sys_vars/r/aria_checkpoint_log_activity_basic.result
new file mode 100644
index 00000000000..8a0247471ff
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/aria_checkpoint_log_activity_basic.result
@@ -0,0 +1,43 @@
+SET @start_global_value = @@global.aria_checkpoint_log_activity;
+select @@global.aria_checkpoint_log_activity;
+@@global.aria_checkpoint_log_activity
+1048576
+select @@session.aria_checkpoint_log_activity;
+ERROR HY000: Variable 'aria_checkpoint_log_activity' is a GLOBAL variable
+show global variables like 'aria_checkpoint_log_activity';
+Variable_name Value
+aria_checkpoint_log_activity 1048576
+show session variables like 'aria_checkpoint_log_activity';
+Variable_name Value
+aria_checkpoint_log_activity 1048576
+select * from information_schema.global_variables where variable_name='aria_checkpoint_log_activity';
+VARIABLE_NAME VARIABLE_VALUE
+ARIA_CHECKPOINT_LOG_ACTIVITY 1048576
+select * from information_schema.session_variables where variable_name='aria_checkpoint_log_activity';
+VARIABLE_NAME VARIABLE_VALUE
+ARIA_CHECKPOINT_LOG_ACTIVITY 1048576
+set global aria_checkpoint_log_activity=1;
+select @@global.aria_checkpoint_log_activity;
+@@global.aria_checkpoint_log_activity
+1
+set session aria_checkpoint_log_activity=1;
+ERROR HY000: Variable 'aria_checkpoint_log_activity' is a GLOBAL variable and should be set with SET GLOBAL
+set global aria_checkpoint_log_activity=1.1;
+ERROR 42000: Incorrect argument type to variable 'aria_checkpoint_log_activity'
+set global aria_checkpoint_log_activity=1e1;
+ERROR 42000: Incorrect argument type to variable 'aria_checkpoint_log_activity'
+set global aria_checkpoint_log_activity="foo";
+ERROR 42000: Incorrect argument type to variable 'aria_checkpoint_log_activity'
+set global aria_checkpoint_log_activity=0;
+select @@global.aria_checkpoint_log_activity;
+@@global.aria_checkpoint_log_activity
+0
+set global aria_checkpoint_log_activity=cast(-1 as unsigned int);
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1292 Truncated incorrect aria_checkpoint_log_activity value: '18446744073709551615'
+select @@global.aria_checkpoint_log_activity;
+@@global.aria_checkpoint_log_activity
+4294967295
+SET @@global.aria_checkpoint_log_activity = @start_global_value;
diff --git a/mysql-test/suite/sys_vars/r/binlog_annotate_row_events_basic.result b/mysql-test/suite/sys_vars/r/binlog_annotate_row_events_basic.result
new file mode 100644
index 00000000000..6fef4fc1d32
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/binlog_annotate_row_events_basic.result
@@ -0,0 +1,50 @@
+SET @start_global_value = @@global.binlog_annotate_row_events;
+select @@global.binlog_annotate_row_events;
+@@global.binlog_annotate_row_events
+0
+select @@session.binlog_annotate_row_events;
+@@session.binlog_annotate_row_events
+0
+show global variables like 'binlog_annotate_row_events';
+Variable_name Value
+binlog_annotate_row_events OFF
+show session variables like 'binlog_annotate_row_events';
+Variable_name Value
+binlog_annotate_row_events OFF
+select * from information_schema.global_variables where variable_name='binlog_annotate_row_events';
+VARIABLE_NAME VARIABLE_VALUE
+BINLOG_ANNOTATE_ROW_EVENTS OFF
+select * from information_schema.session_variables where variable_name='binlog_annotate_row_events';
+VARIABLE_NAME VARIABLE_VALUE
+BINLOG_ANNOTATE_ROW_EVENTS OFF
+set global binlog_annotate_row_events=ON;
+select @@global.binlog_annotate_row_events;
+@@global.binlog_annotate_row_events
+1
+set global binlog_annotate_row_events=OFF;
+select @@global.binlog_annotate_row_events;
+@@global.binlog_annotate_row_events
+0
+set global binlog_annotate_row_events=1;
+select @@global.binlog_annotate_row_events;
+@@global.binlog_annotate_row_events
+1
+set session binlog_annotate_row_events=ON;
+select @@session.binlog_annotate_row_events;
+@@session.binlog_annotate_row_events
+1
+set session binlog_annotate_row_events=OFF;
+select @@session.binlog_annotate_row_events;
+@@session.binlog_annotate_row_events
+0
+set session binlog_annotate_row_events=1;
+select @@session.binlog_annotate_row_events;
+@@session.binlog_annotate_row_events
+1
+set global binlog_annotate_row_events=1.1;
+ERROR 42000: Incorrect argument type to variable 'binlog_annotate_row_events'
+set session binlog_annotate_row_events=1e1;
+ERROR 42000: Incorrect argument type to variable 'binlog_annotate_row_events'
+set session binlog_annotate_row_events="foo";
+ERROR 42000: Variable 'binlog_annotate_row_events' can't be set to the value of 'foo'
+SET @@global.binlog_annotate_row_events = @start_global_value;
diff --git a/mysql-test/suite/sys_vars/r/binlog_annotate_rows_events_basic.result b/mysql-test/suite/sys_vars/r/binlog_annotate_rows_events_basic.result
deleted file mode 100644
index af6b27972e5..00000000000
--- a/mysql-test/suite/sys_vars/r/binlog_annotate_rows_events_basic.result
+++ /dev/null
@@ -1,50 +0,0 @@
-SET @start_global_value = @@global.binlog_annotate_rows_events;
-select @@global.binlog_annotate_rows_events;
-@@global.binlog_annotate_rows_events
-0
-select @@session.binlog_annotate_rows_events;
-@@session.binlog_annotate_rows_events
-0
-show global variables like 'binlog_annotate_rows_events';
-Variable_name Value
-binlog_annotate_rows_events OFF
-show session variables like 'binlog_annotate_rows_events';
-Variable_name Value
-binlog_annotate_rows_events OFF
-select * from information_schema.global_variables where variable_name='binlog_annotate_rows_events';
-VARIABLE_NAME VARIABLE_VALUE
-BINLOG_ANNOTATE_ROWS_EVENTS OFF
-select * from information_schema.session_variables where variable_name='binlog_annotate_rows_events';
-VARIABLE_NAME VARIABLE_VALUE
-BINLOG_ANNOTATE_ROWS_EVENTS OFF
-set global binlog_annotate_rows_events=ON;
-select @@global.binlog_annotate_rows_events;
-@@global.binlog_annotate_rows_events
-1
-set global binlog_annotate_rows_events=OFF;
-select @@global.binlog_annotate_rows_events;
-@@global.binlog_annotate_rows_events
-0
-set global binlog_annotate_rows_events=1;
-select @@global.binlog_annotate_rows_events;
-@@global.binlog_annotate_rows_events
-1
-set session binlog_annotate_rows_events=ON;
-select @@session.binlog_annotate_rows_events;
-@@session.binlog_annotate_rows_events
-1
-set session binlog_annotate_rows_events=OFF;
-select @@session.binlog_annotate_rows_events;
-@@session.binlog_annotate_rows_events
-0
-set session binlog_annotate_rows_events=1;
-select @@session.binlog_annotate_rows_events;
-@@session.binlog_annotate_rows_events
-1
-set global binlog_annotate_rows_events=1.1;
-ERROR 42000: Incorrect argument type to variable 'binlog_annotate_rows_events'
-set session binlog_annotate_rows_events=1e1;
-ERROR 42000: Incorrect argument type to variable 'binlog_annotate_rows_events'
-set session binlog_annotate_rows_events="foo";
-ERROR 42000: Variable 'binlog_annotate_rows_events' can't be set to the value of 'foo'
-SET @@global.binlog_annotate_rows_events = @start_global_value;
diff --git a/mysql-test/suite/sys_vars/r/debug_binlog_fsync_sleep_basic.result b/mysql-test/suite/sys_vars/r/debug_binlog_fsync_sleep_basic.result
new file mode 100644
index 00000000000..adf2b4c39b9
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/debug_binlog_fsync_sleep_basic.result
@@ -0,0 +1,41 @@
+SET @start_global_value = @@global.debug_binlog_fsync_sleep;
+select @@global.debug_binlog_fsync_sleep;
+@@global.debug_binlog_fsync_sleep
+0
+select @@session.debug_binlog_fsync_sleep;
+ERROR HY000: Variable 'debug_binlog_fsync_sleep' is a GLOBAL variable
+show global variables like 'debug_binlog_fsync_sleep';
+Variable_name Value
+debug_binlog_fsync_sleep 0
+show session variables like 'debug_binlog_fsync_sleep';
+Variable_name Value
+debug_binlog_fsync_sleep 0
+select * from information_schema.global_variables where variable_name='debug_binlog_fsync_sleep';
+VARIABLE_NAME VARIABLE_VALUE
+DEBUG_BINLOG_FSYNC_SLEEP 0
+select * from information_schema.session_variables where variable_name='debug_binlog_fsync_sleep';
+VARIABLE_NAME VARIABLE_VALUE
+DEBUG_BINLOG_FSYNC_SLEEP 0
+set global debug_binlog_fsync_sleep=20;
+select @@global.debug_binlog_fsync_sleep;
+@@global.debug_binlog_fsync_sleep
+20
+set session debug_binlog_fsync_sleep=1;
+ERROR HY000: Variable 'debug_binlog_fsync_sleep' is a GLOBAL variable and should be set with SET GLOBAL
+set global debug_binlog_fsync_sleep=1.1;
+ERROR 42000: Incorrect argument type to variable 'debug_binlog_fsync_sleep'
+set global debug_binlog_fsync_sleep=1e1;
+ERROR 42000: Incorrect argument type to variable 'debug_binlog_fsync_sleep'
+set global debug_binlog_fsync_sleep="foo";
+ERROR 42000: Incorrect argument type to variable 'debug_binlog_fsync_sleep'
+set global debug_binlog_fsync_sleep=0;
+select @@global.debug_binlog_fsync_sleep;
+@@global.debug_binlog_fsync_sleep
+0
+set global debug_binlog_fsync_sleep=cast(-1 as unsigned int);
+Warnings:
+Warning 1105 Cast to unsigned converted negative integer to it's positive complement
+select @@global.debug_binlog_fsync_sleep;
+@@global.debug_binlog_fsync_sleep
+18446744073709551615
+SET @@global.debug_binlog_fsync_sleep = @start_global_value;
diff --git a/mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result b/mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result
index 36dc9b6399e..0922113f8b6 100644
--- a/mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result
+++ b/mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result
@@ -9,7 +9,7 @@ SELECT @global_start_value;
select @old_session_opt_switch:=@@session.optimizer_switch,
@old_global_opt_switch:=@@global.optimizer_switch;
@old_session_opt_switch:=@@session.optimizer_switch @old_global_opt_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,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
'#--------------------FN_DYNVARS_028_01------------------------#'
SET @@session.engine_condition_pushdown = 0;
Warnings:
@@ -212,7 +212,7 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
set @@session.engine_condition_pushdown = TRUE;
Warnings:
Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MySQL 7.0. Please use '@@optimizer_switch' instead
@@ -220,7 +220,7 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-1 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+1 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
set @@session.engine_condition_pushdown = FALSE;
Warnings:
Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MySQL 7.0. Please use '@@optimizer_switch' instead
@@ -228,7 +228,7 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
set @@global.engine_condition_pushdown = TRUE;
Warnings:
Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MySQL 7.0. Please use '@@optimizer_switch' instead
@@ -236,7 +236,7 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+0 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,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,table_elimination=on
set @@global.engine_condition_pushdown = FALSE;
Warnings:
Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MySQL 7.0. Please use '@@optimizer_switch' instead
@@ -244,31 +244,31 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
set @@session.optimizer_switch = "engine_condition_pushdown=on";
select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-1 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+1 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
set @@session.optimizer_switch = "engine_condition_pushdown=off";
select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
set @@global.optimizer_switch = "engine_condition_pushdown=on";
select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+0 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,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,table_elimination=on
set @@global.optimizer_switch = "engine_condition_pushdown=off";
select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
SET @@session.engine_condition_pushdown = @session_start_value;
Warnings:
Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MySQL 7.0. Please use '@@optimizer_switch' instead
@@ -287,4 +287,4 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
diff --git a/mysql-test/suite/sys_vars/r/max_user_connections-2.result b/mysql-test/suite/sys_vars/r/max_user_connections-2.result
new file mode 100644
index 00000000000..d9daec5c089
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/max_user_connections-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/suite/sys_vars/r/max_user_connections_basic.result b/mysql-test/suite/sys_vars/r/max_user_connections_basic.result
index cc43b631085..26d82f3b215 100644
--- a/mysql-test/suite/sys_vars/r/max_user_connections_basic.result
+++ b/mysql-test/suite/sys_vars/r/max_user_connections_basic.result
@@ -1,11 +1,11 @@
SET @start_global_value = @@global.max_user_connections;
SELECT @start_global_value;
@start_global_value
-0
+10
SET @start_session_value = @@session.max_user_connections;
SELECT @start_session_value;
@start_session_value
-0
+10
'#--------------------FN_DYNVARS_087_01-------------------------#'
SET @@global.max_user_connections = 1000;
SET @@global.max_user_connections = DEFAULT;
@@ -37,14 +37,14 @@ SET @@global.max_user_connections = 65536;
SELECT @@global.max_user_connections;
@@global.max_user_connections
65536
-SET @@global.max_user_connections = 4294967295;
+SET @@global.max_user_connections = 2147483647;
SELECT @@global.max_user_connections;
@@global.max_user_connections
-4294967295
-SET @@global.max_user_connections = 4294967294;
+2147483647
+SET @@global.max_user_connections = 2147483646;
SELECT @@global.max_user_connections;
@@global.max_user_connections
-4294967294
+2147483646
'#------------------FN_DYNVARS_087_05-----------------------#'
SET @@global.max_user_connections = -1024;
Warnings:
@@ -57,7 +57,7 @@ Warnings:
Warning 1292 Truncated incorrect max_user_connections value: '4294967296'
SELECT @@global.max_user_connections;
@@global.max_user_connections
-4294967295
+2147483647
SET @@global.max_user_connections = -1;
Warnings:
Warning 1292 Truncated incorrect max_user_connections value: '-1'
@@ -69,17 +69,17 @@ Warnings:
Warning 1292 Truncated incorrect max_user_connections value: '429496729500'
SELECT @@global.max_user_connections;
@@global.max_user_connections
-4294967295
+2147483647
SET @@global.max_user_connections = 65530.34;
ERROR 42000: Incorrect argument type to variable 'max_user_connections'
SELECT @@global.max_user_connections;
@@global.max_user_connections
-4294967295
+2147483647
SET @@global.max_user_connections = test;
ERROR 42000: Incorrect argument type to variable 'max_user_connections'
SELECT @@global.max_user_connections;
@@global.max_user_connections
-4294967295
+2147483647
'#------------------FN_DYNVARS_087_06-----------------------#'
SELECT @@global.max_user_connections = VARIABLE_VALUE
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
@@ -114,4 +114,4 @@ ERROR 42S22: Unknown column 'max_user_connections' in 'field list'
SET @@global.max_user_connections = @start_global_value;
SELECT @@global.max_user_connections;
@@global.max_user_connections
-0
+10
diff --git a/mysql-test/suite/sys_vars/r/max_user_connections_func.result b/mysql-test/suite/sys_vars/r/max_user_connections_func.result
index 2ff2ac82ce7..04999a0a43f 100644
--- a/mysql-test/suite/sys_vars/r/max_user_connections_func.result
+++ b/mysql-test/suite/sys_vars/r/max_user_connections_func.result
@@ -2,18 +2,20 @@
SET @default_max_user_connections = @@global.max_user_connections;
Set Global max_user_connections=2;
+GRANT USAGE on *.* TO test@localhost;
'#--------------------FN_DYNVARS_114_01-------------------------#'
-** Connecting conn1 using username 'root' **
-** Connecting conn2 using username 'root' **
-** Connecting conn3 using username 'root' **
-ERROR 42000: User root already has more than 'max_user_connections' active connections
+** Connecting conn1 using username 'test' **
+** Connecting conn2 using username 'test' **
+** Connecting conn3 using username 'test' **
+ERROR 42000: User test already has more than 'max_user_connections' active connections
Expected error "too many connections"
** Disconnecting conn1 **
** Poll till disconnected conn1 disappears from processlist
'#--------------------FN_DYNVARS_114_02-------------------------#'
Set Global max_user_connections=3;
-** Connecting conn5 using username 'root' **
-** Connecting conn6 using username 'root' **
+** Connecting conn5 using username 'test' **
+** Connecting conn6 using username 'test' **
** Connection default **
** Disconnecting conn5, conn6 **
+drop user test@localhost;
SET @@global.max_user_connections = @default_max_user_connections;
diff --git a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
index a56bcc77886..1fa39374f9c 100644
--- a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
+++ b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
@@ -1,25 +1,25 @@
SET @start_global_value = @@global.optimizer_switch;
SELECT @start_global_value;
@start_global_value
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
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,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
select @@session.optimizer_switch;
@@session.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
show global variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
show session variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
select * from information_schema.global_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
select * from information_schema.session_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
set global optimizer_switch=10;
set session optimizer_switch=5;
select @@global.optimizer_switch;
@@ -63,4 +63,4 @@ ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'foobar'
SET @@global.optimizer_switch = @start_global_value;
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,engine_condition_pushdown=off,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=off,in_to_exists=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on,subquery_cache=off,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,table_elimination=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
diff --git a/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown1.result b/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown1.result
new file mode 100644
index 00000000000..ad618c1727f
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown1.result
@@ -0,0 +1,5 @@
+select @@session.engine_condition_pushdown,
+@@global.engine_condition_pushdown,
+@@session.optimizer_switch, @@global.optimizer_switch;
+@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
+1 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,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,table_elimination=on
diff --git a/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown2.result b/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown2.result
new file mode 100644
index 00000000000..daed5b2919c
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown2.result
@@ -0,0 +1,5 @@
+select @@session.engine_condition_pushdown,
+@@global.engine_condition_pushdown,
+@@session.optimizer_switch, @@global.optimizer_switch;
+@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=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,table_elimination=on
diff --git a/mysql-test/suite/sys_vars/r/replicate_annotate_row_events_basic.result b/mysql-test/suite/sys_vars/r/replicate_annotate_row_events_basic.result
new file mode 100644
index 00000000000..802c92268d6
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/replicate_annotate_row_events_basic.result
@@ -0,0 +1,21 @@
+select @@global.replicate_annotate_row_events;
+@@global.replicate_annotate_row_events
+0
+select @@session.replicate_annotate_row_events;
+ERROR HY000: Variable 'replicate_annotate_row_events' is a GLOBAL variable
+show global variables like 'replicate_annotate_row_events';
+Variable_name Value
+replicate_annotate_row_events OFF
+show session variables like 'replicate_annotate_row_events';
+Variable_name Value
+replicate_annotate_row_events OFF
+select * from information_schema.global_variables where variable_name='replicate_annotate_row_events';
+VARIABLE_NAME VARIABLE_VALUE
+REPLICATE_ANNOTATE_ROW_EVENTS OFF
+select * from information_schema.session_variables where variable_name='replicate_annotate_row_events';
+VARIABLE_NAME VARIABLE_VALUE
+REPLICATE_ANNOTATE_ROW_EVENTS OFF
+set global replicate_annotate_row_events=1;
+ERROR HY000: Variable 'replicate_annotate_row_events' is a read only variable
+set session replicate_annotate_row_events=1;
+ERROR HY000: Variable 'replicate_annotate_row_events' is a read only variable
diff --git a/mysql-test/suite/sys_vars/r/replicate_annotate_rows_events_basic.result b/mysql-test/suite/sys_vars/r/replicate_annotate_rows_events_basic.result
deleted file mode 100644
index ef0d29fad07..00000000000
--- a/mysql-test/suite/sys_vars/r/replicate_annotate_rows_events_basic.result
+++ /dev/null
@@ -1,21 +0,0 @@
-select @@global.replicate_annotate_rows_events;
-@@global.replicate_annotate_rows_events
-0
-select @@session.replicate_annotate_rows_events;
-ERROR HY000: Variable 'replicate_annotate_rows_events' is a GLOBAL variable
-show global variables like 'replicate_annotate_rows_events';
-Variable_name Value
-replicate_annotate_rows_events OFF
-show session variables like 'replicate_annotate_rows_events';
-Variable_name Value
-replicate_annotate_rows_events OFF
-select * from information_schema.global_variables where variable_name='replicate_annotate_rows_events';
-VARIABLE_NAME VARIABLE_VALUE
-REPLICATE_ANNOTATE_ROWS_EVENTS OFF
-select * from information_schema.session_variables where variable_name='replicate_annotate_rows_events';
-VARIABLE_NAME VARIABLE_VALUE
-REPLICATE_ANNOTATE_ROWS_EVENTS OFF
-set global replicate_annotate_rows_events=1;
-ERROR HY000: Variable 'replicate_annotate_rows_events' is a read only variable
-set session replicate_annotate_rows_events=1;
-ERROR HY000: Variable 'replicate_annotate_rows_events' is a read only variable
diff --git a/mysql-test/suite/sys_vars/t/aria_checkpoint_log_activity_basic.test b/mysql-test/suite/sys_vars/t/aria_checkpoint_log_activity_basic.test
new file mode 100644
index 00000000000..9fa5e5e2e2f
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/aria_checkpoint_log_activity_basic.test
@@ -0,0 +1,43 @@
+# ulong global
+--source include/have_maria.inc
+
+SET @start_global_value = @@global.aria_checkpoint_log_activity;
+
+#
+# exists as global only
+#
+select @@global.aria_checkpoint_log_activity;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.aria_checkpoint_log_activity;
+show global variables like 'aria_checkpoint_log_activity';
+show session variables like 'aria_checkpoint_log_activity';
+select * from information_schema.global_variables where variable_name='aria_checkpoint_log_activity';
+select * from information_schema.session_variables where variable_name='aria_checkpoint_log_activity';
+
+#
+# show that it's writable
+#
+set global aria_checkpoint_log_activity=1;
+select @@global.aria_checkpoint_log_activity;
+--error ER_GLOBAL_VARIABLE
+set session aria_checkpoint_log_activity=1;
+
+#
+# incorrect types
+#
+--error ER_WRONG_TYPE_FOR_VAR
+set global aria_checkpoint_log_activity=1.1;
+--error ER_WRONG_TYPE_FOR_VAR
+set global aria_checkpoint_log_activity=1e1;
+--error ER_WRONG_TYPE_FOR_VAR
+set global aria_checkpoint_log_activity="foo";
+
+#
+# min/max values
+#
+set global aria_checkpoint_log_activity=0;
+select @@global.aria_checkpoint_log_activity;
+set global aria_checkpoint_log_activity=cast(-1 as unsigned int);
+select @@global.aria_checkpoint_log_activity;
+
+SET @@global.aria_checkpoint_log_activity = @start_global_value;
diff --git a/mysql-test/suite/sys_vars/t/binlog_annotate_row_events_basic.test b/mysql-test/suite/sys_vars/t/binlog_annotate_row_events_basic.test
new file mode 100644
index 00000000000..9dd3545e1ec
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/binlog_annotate_row_events_basic.test
@@ -0,0 +1,39 @@
+# bool session
+
+SET @start_global_value = @@global.binlog_annotate_row_events;
+
+select @@global.binlog_annotate_row_events;
+select @@session.binlog_annotate_row_events;
+show global variables like 'binlog_annotate_row_events';
+show session variables like 'binlog_annotate_row_events';
+select * from information_schema.global_variables where variable_name='binlog_annotate_row_events';
+select * from information_schema.session_variables where variable_name='binlog_annotate_row_events';
+
+#
+# show that it's writable
+#
+set global binlog_annotate_row_events=ON;
+select @@global.binlog_annotate_row_events;
+set global binlog_annotate_row_events=OFF;
+select @@global.binlog_annotate_row_events;
+set global binlog_annotate_row_events=1;
+select @@global.binlog_annotate_row_events;
+
+set session binlog_annotate_row_events=ON;
+select @@session.binlog_annotate_row_events;
+set session binlog_annotate_row_events=OFF;
+select @@session.binlog_annotate_row_events;
+set session binlog_annotate_row_events=1;
+select @@session.binlog_annotate_row_events;
+#
+# incorrect types
+#
+--error ER_WRONG_TYPE_FOR_VAR
+set global binlog_annotate_row_events=1.1;
+--error ER_WRONG_TYPE_FOR_VAR
+set session binlog_annotate_row_events=1e1;
+--error ER_WRONG_VALUE_FOR_VAR
+set session binlog_annotate_row_events="foo";
+
+SET @@global.binlog_annotate_row_events = @start_global_value;
+
diff --git a/mysql-test/suite/sys_vars/t/binlog_annotate_rows_events_basic.test b/mysql-test/suite/sys_vars/t/binlog_annotate_rows_events_basic.test
deleted file mode 100644
index 89bdb0986e5..00000000000
--- a/mysql-test/suite/sys_vars/t/binlog_annotate_rows_events_basic.test
+++ /dev/null
@@ -1,39 +0,0 @@
-# bool session
-
-SET @start_global_value = @@global.binlog_annotate_rows_events;
-
-select @@global.binlog_annotate_rows_events;
-select @@session.binlog_annotate_rows_events;
-show global variables like 'binlog_annotate_rows_events';
-show session variables like 'binlog_annotate_rows_events';
-select * from information_schema.global_variables where variable_name='binlog_annotate_rows_events';
-select * from information_schema.session_variables where variable_name='binlog_annotate_rows_events';
-
-#
-# show that it's writable
-#
-set global binlog_annotate_rows_events=ON;
-select @@global.binlog_annotate_rows_events;
-set global binlog_annotate_rows_events=OFF;
-select @@global.binlog_annotate_rows_events;
-set global binlog_annotate_rows_events=1;
-select @@global.binlog_annotate_rows_events;
-
-set session binlog_annotate_rows_events=ON;
-select @@session.binlog_annotate_rows_events;
-set session binlog_annotate_rows_events=OFF;
-select @@session.binlog_annotate_rows_events;
-set session binlog_annotate_rows_events=1;
-select @@session.binlog_annotate_rows_events;
-#
-# incorrect types
-#
---error ER_WRONG_TYPE_FOR_VAR
-set global binlog_annotate_rows_events=1.1;
---error ER_WRONG_TYPE_FOR_VAR
-set session binlog_annotate_rows_events=1e1;
---error ER_WRONG_VALUE_FOR_VAR
-set session binlog_annotate_rows_events="foo";
-
-SET @@global.binlog_annotate_rows_events = @start_global_value;
-
diff --git a/mysql-test/suite/sys_vars/t/binlog_dbug_fsync_sleep_basic.test b/mysql-test/suite/sys_vars/t/binlog_dbug_fsync_sleep_basic.test
deleted file mode 100644
index 8e9f4651929..00000000000
--- a/mysql-test/suite/sys_vars/t/binlog_dbug_fsync_sleep_basic.test
+++ /dev/null
@@ -1,48 +0,0 @@
---source include/have_debug.inc
-
-# ulong global
-
-SET @start_global_value = @@global.binlog_dbug_fsync_sleep;
-
-#
-# exists as global only
-#
-select @@global.binlog_dbug_fsync_sleep;
---error ER_INCORRECT_GLOBAL_LOCAL_VAR
-select @@session.binlog_dbug_fsync_sleep;
-show global variables like 'binlog_dbug_fsync_sleep';
-show session variables like 'binlog_dbug_fsync_sleep';
-select * from information_schema.global_variables where variable_name='binlog_dbug_fsync_sleep';
-select * from information_schema.session_variables where variable_name='binlog_dbug_fsync_sleep';
-
-#
-# show that it's writable
-#
-set global binlog_dbug_fsync_sleep=200;
-select @@global.binlog_dbug_fsync_sleep;
---error ER_GLOBAL_VARIABLE
-set session binlog_dbug_fsync_sleep=1;
-
-#
-# incorrect types
-#
---error ER_WRONG_TYPE_FOR_VAR
-set global binlog_dbug_fsync_sleep=1.1;
---error ER_WRONG_TYPE_FOR_VAR
-set global binlog_dbug_fsync_sleep=1e1;
---error ER_WRONG_TYPE_FOR_VAR
-set global binlog_dbug_fsync_sleep="foo";
-
-#
-# min/max values, block size
-#
-set global binlog_dbug_fsync_sleep=1;
-select @@global.binlog_dbug_fsync_sleep;
-set global binlog_dbug_fsync_sleep=@@global.binlog_dbug_fsync_sleep + 100 - 1;
-select @@global.binlog_dbug_fsync_sleep;
-set global binlog_dbug_fsync_sleep=@@global.binlog_dbug_fsync_sleep + 100;
-select @@global.binlog_dbug_fsync_sleep;
-set global binlog_dbug_fsync_sleep=cast(-1 as unsigned int);
-select @@global.binlog_dbug_fsync_sleep;
-
-SET @@global.binlog_dbug_fsync_sleep = @start_global_value;
diff --git a/mysql-test/suite/sys_vars/t/debug_binlog_fsync_sleep_basic.test b/mysql-test/suite/sys_vars/t/debug_binlog_fsync_sleep_basic.test
new file mode 100644
index 00000000000..73f61c45623
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/debug_binlog_fsync_sleep_basic.test
@@ -0,0 +1,42 @@
+# ulong global
+
+SET @start_global_value = @@global.debug_binlog_fsync_sleep;
+
+#
+# exists as global only
+#
+select @@global.debug_binlog_fsync_sleep;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.debug_binlog_fsync_sleep;
+show global variables like 'debug_binlog_fsync_sleep';
+show session variables like 'debug_binlog_fsync_sleep';
+select * from information_schema.global_variables where variable_name='debug_binlog_fsync_sleep';
+select * from information_schema.session_variables where variable_name='debug_binlog_fsync_sleep';
+
+#
+# show that it's writable
+#
+set global debug_binlog_fsync_sleep=20;
+select @@global.debug_binlog_fsync_sleep;
+--error ER_GLOBAL_VARIABLE
+set session debug_binlog_fsync_sleep=1;
+
+#
+# incorrect types
+#
+--error ER_WRONG_TYPE_FOR_VAR
+set global debug_binlog_fsync_sleep=1.1;
+--error ER_WRONG_TYPE_FOR_VAR
+set global debug_binlog_fsync_sleep=1e1;
+--error ER_WRONG_TYPE_FOR_VAR
+set global debug_binlog_fsync_sleep="foo";
+
+#
+# min/max values, block size
+#
+set global debug_binlog_fsync_sleep=0;
+select @@global.debug_binlog_fsync_sleep;
+set global debug_binlog_fsync_sleep=cast(-1 as unsigned int);
+select @@global.debug_binlog_fsync_sleep;
+
+SET @@global.debug_binlog_fsync_sleep = @start_global_value;
diff --git a/mysql-test/suite/sys_vars/t/max_user_connections-2.test b/mysql-test/suite/sys_vars/t/max_user_connections-2.test
new file mode 100644
index 00000000000..a376c78a09b
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/max_user_connections-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/suite/sys_vars/t/max_user_connections_basic-master.opt b/mysql-test/suite/sys_vars/t/max_user_connections_basic-master.opt
new file mode 100644
index 00000000000..f507cd0406c
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/max_user_connections_basic-master.opt
@@ -0,0 +1 @@
+--max-user-connections=10
diff --git a/mysql-test/suite/sys_vars/t/max_user_connections_basic.test b/mysql-test/suite/sys_vars/t/max_user_connections_basic.test
index 1adcc012bc4..8c9d031030f 100644
--- a/mysql-test/suite/sys_vars/t/max_user_connections_basic.test
+++ b/mysql-test/suite/sys_vars/t/max_user_connections_basic.test
@@ -77,9 +77,9 @@ SET @@global.max_user_connections = 2;
SELECT @@global.max_user_connections;
SET @@global.max_user_connections = 65536;
SELECT @@global.max_user_connections;
-SET @@global.max_user_connections = 4294967295;
+SET @@global.max_user_connections = 2147483647;
SELECT @@global.max_user_connections;
-SET @@global.max_user_connections = 4294967294;
+SET @@global.max_user_connections = 2147483646;
SELECT @@global.max_user_connections;
diff --git a/mysql-test/suite/sys_vars/t/max_user_connections_func-master.opt b/mysql-test/suite/sys_vars/t/max_user_connections_func-master.opt
new file mode 100644
index 00000000000..f507cd0406c
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/max_user_connections_func-master.opt
@@ -0,0 +1 @@
+--max-user-connections=10
diff --git a/mysql-test/suite/sys_vars/t/max_user_connections_func.test b/mysql-test/suite/sys_vars/t/max_user_connections_func.test
index 841a630c5ce..74707c9b296 100644
--- a/mysql-test/suite/sys_vars/t/max_user_connections_func.test
+++ b/mysql-test/suite/sys_vars/t/max_user_connections_func.test
@@ -39,21 +39,23 @@ SET @default_max_user_connections = @@global.max_user_connections;
Set Global max_user_connections=2;
+GRANT USAGE on *.* TO test@localhost;
+
--echo '#--------------------FN_DYNVARS_114_01-------------------------#'
########################################
#Should not make more then 2 connection#
########################################
---echo ** Connecting conn1 using username 'root' **
-CONNECT (conn1,localhost,root,,);
+--echo ** Connecting conn1 using username 'test' **
+CONNECT (conn1,localhost,test,,);
---echo ** Connecting conn2 using username 'root' **
-CONNECT (conn2,localhost,root,,);
+--echo ** Connecting conn2 using username 'test' **
+CONNECT (conn2,localhost,test,,);
---echo ** Connecting conn3 using username 'root' **
+--echo ** Connecting conn3 using username 'test' **
--disable_query_log
--Error ER_TOO_MANY_USER_CONNECTIONS
-CONNECT (conn3,localhost,root,,);
+CONNECT (conn3,localhost,test,,);
--enable_query_log
--echo Expected error "too many connections"
@@ -62,7 +64,7 @@ DISCONNECT conn1;
--echo ** Poll till disconnected conn1 disappears from processlist
let $wait_condition= SELECT count(id) <= 2
- FROM information_schema.processlist WHERE user = 'root';
+ FROM information_schema.processlist WHERE user = 'test';
--source include/wait_condition.inc
--echo '#--------------------FN_DYNVARS_114_02-------------------------#'
@@ -70,11 +72,12 @@ let $wait_condition= SELECT count(id) <= 2
#Set value to 3 and see if 3 connections can be made#
#####################################################
+connection default;
Set Global max_user_connections=3;
---echo ** Connecting conn5 using username 'root' **
-CONNECT (conn5,localhost,root,,);
---echo ** Connecting conn6 using username 'root' **
-CONNECT (conn6,localhost,root,,);
+--echo ** Connecting conn5 using username 'test' **
+CONNECT (conn5,localhost,test,,);
+--echo ** Connecting conn6 using username 'test' **
+CONNECT (conn6,localhost,test,,);
#
# Cleanup
@@ -88,5 +91,7 @@ DISCONNECT conn2;
DISCONNECT conn5;
DISCONNECT conn6;
+drop user test@localhost;
+
SET @@global.max_user_connections = @default_max_user_connections;
diff --git a/mysql-test/t/optimizer_switch_eng_cond_pushdown1-master.opt b/mysql-test/suite/sys_vars/t/optimizer_switch_eng_cond_pushdown1-master.opt
index 89aa07976ac..89aa07976ac 100644
--- a/mysql-test/t/optimizer_switch_eng_cond_pushdown1-master.opt
+++ b/mysql-test/suite/sys_vars/t/optimizer_switch_eng_cond_pushdown1-master.opt
diff --git a/mysql-test/t/optimizer_switch_eng_cond_pushdown1.test b/mysql-test/suite/sys_vars/t/optimizer_switch_eng_cond_pushdown1.test
index 187aa145408..187aa145408 100644
--- a/mysql-test/t/optimizer_switch_eng_cond_pushdown1.test
+++ b/mysql-test/suite/sys_vars/t/optimizer_switch_eng_cond_pushdown1.test
diff --git a/mysql-test/t/optimizer_switch_eng_cond_pushdown2-master.opt b/mysql-test/suite/sys_vars/t/optimizer_switch_eng_cond_pushdown2-master.opt
index f48ab5b963b..f48ab5b963b 100644
--- a/mysql-test/t/optimizer_switch_eng_cond_pushdown2-master.opt
+++ b/mysql-test/suite/sys_vars/t/optimizer_switch_eng_cond_pushdown2-master.opt
diff --git a/mysql-test/t/optimizer_switch_eng_cond_pushdown2.test b/mysql-test/suite/sys_vars/t/optimizer_switch_eng_cond_pushdown2.test
index 187aa145408..187aa145408 100644
--- a/mysql-test/t/optimizer_switch_eng_cond_pushdown2.test
+++ b/mysql-test/suite/sys_vars/t/optimizer_switch_eng_cond_pushdown2.test
diff --git a/mysql-test/suite/sys_vars/t/replicate_annotate_row_events_basic.test b/mysql-test/suite/sys_vars/t/replicate_annotate_row_events_basic.test
new file mode 100644
index 00000000000..f4d7221f1b8
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/replicate_annotate_row_events_basic.test
@@ -0,0 +1,23 @@
+# bool readonly
+
+--source include/not_embedded.inc
+
+#
+# show values;
+#
+select @@global.replicate_annotate_row_events;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.replicate_annotate_row_events;
+show global variables like 'replicate_annotate_row_events';
+show session variables like 'replicate_annotate_row_events';
+select * from information_schema.global_variables where variable_name='replicate_annotate_row_events';
+select * from information_schema.session_variables where variable_name='replicate_annotate_row_events';
+
+#
+# show that it's read-only
+#
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set global replicate_annotate_row_events=1;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set session replicate_annotate_row_events=1;
+
diff --git a/mysql-test/suite/sys_vars/t/replicate_annotate_rows_events_basic.test b/mysql-test/suite/sys_vars/t/replicate_annotate_rows_events_basic.test
deleted file mode 100644
index b519859e971..00000000000
--- a/mysql-test/suite/sys_vars/t/replicate_annotate_rows_events_basic.test
+++ /dev/null
@@ -1,23 +0,0 @@
-# bool readonly
-
---source include/not_embedded.inc
-
-#
-# show values;
-#
-select @@global.replicate_annotate_rows_events;
---error ER_INCORRECT_GLOBAL_LOCAL_VAR
-select @@session.replicate_annotate_rows_events;
-show global variables like 'replicate_annotate_rows_events';
-show session variables like 'replicate_annotate_rows_events';
-select * from information_schema.global_variables where variable_name='replicate_annotate_rows_events';
-select * from information_schema.session_variables where variable_name='replicate_annotate_rows_events';
-
-#
-# show that it's read-only
-#
---error ER_INCORRECT_GLOBAL_LOCAL_VAR
-set global replicate_annotate_rows_events=1;
---error ER_INCORRECT_GLOBAL_LOCAL_VAR
-set session replicate_annotate_rows_events=1;
-
diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result
index 58bd048ec85..693ea0d9174 100644
--- a/mysql-test/suite/vcol/r/vcol_misc.result
+++ b/mysql-test/suite/vcol/r/vcol_misc.result
@@ -139,6 +139,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
select * from t1,t2 where t1.b=t2.c and d <= 100;
diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result
index dfae286e984..6dafda87647 100644
--- a/mysql-test/suite/vcol/r/vcol_select_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result
@@ -63,8 +63,8 @@ a b c
3 -3 -3
explain select * from t1 where b in (select c from t3);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where
-2 DEPENDENT SUBQUERY t3 index_subquery c c 5 func 1 Using index
+1 PRIMARY t3 index c c 5 NULL 3 Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
# select_type=PRIMARY, type=range,ref
select * from t1 where c in (select c from t3 where c between -2 and -1);
a b c
@@ -73,8 +73,8 @@ a b c
1 -1 -1
explain select * from t1 where c in (select c from t3 where c between -2 and -1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where
-2 DEPENDENT SUBQUERY t3 index_subquery c c 5 func 1 Using index; Using where
+1 PRIMARY t3 index c c 5 NULL 3 Using where; Using index
+1 PRIMARY t1 ALL c NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
# select_type=UNION, type=system
# select_type=UNION RESULT, type=<union1,2>
select * from t1 union select * from t2;
diff --git a/mysql-test/suite/vcol/r/vcol_select_myisam.result b/mysql-test/suite/vcol/r/vcol_select_myisam.result
index 24af9cd4256..4d74d791841 100644
--- a/mysql-test/suite/vcol/r/vcol_select_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result
@@ -63,8 +63,8 @@ a b c
3 -3 -3
explain select * from t1 where b in (select c from t3);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where
-2 DEPENDENT SUBQUERY t3 index_subquery c c 5 func 2 Using index
+1 PRIMARY t3 index c c 5 NULL 3 Using index
+1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
# select_type=PRIMARY, type=range,ref
select * from t1 where c in (select c from t3 where c between -2 and -1);
a b c
@@ -73,8 +73,8 @@ a b c
1 -1 -1
explain select * from t1 where c in (select c from t3 where c between -2 and -1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 5 Using where
-2 DEPENDENT SUBQUERY t3 index_subquery c c 5 func 2 Using index; Using where
+1 PRIMARY t3 index c c 5 NULL 3 Using where; Using index
+1 PRIMARY t1 ref c c 5 test.t3.c 2
# select_type=UNION, type=system
# select_type=UNION RESULT, type=<union1,2>
select * from t1 union select * from t2;
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 e1c807fe32b..9d6cc7d375a 100644
--- a/mysql-test/t/case.test
+++ b/mysql-test/t/case.test
@@ -173,3 +173,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 522007f6079..f5e2bc9ea57 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));
@@ -419,3 +419,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_view.test b/mysql-test/t/derived_view.test
index 72719ec9786..c1a9435ef6c 100644
--- a/mysql-test/t/derived_view.test
+++ b/mysql-test/t/derived_view.test
@@ -363,7 +363,9 @@ 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');
+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;
@@ -599,7 +601,10 @@ 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);
+ ('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');
@@ -783,5 +788,478 @@ WHERE EXISTS (SELECT t2.a FROM t3 RIGHT JOIN t2 ON (t3.a = t2.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/explain.test b/mysql-test/t/explain.test
index 8620a43cea5..ece2e968b83 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..14765ee9543
--- /dev/null
+++ b/mysql-test/t/feedback_plugin_send.test
@@ -0,0 +1,23 @@
+source t/feedback_plugin_load.test;
+
+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/fulltext.test b/mysql-test/t/fulltext.test
index e49970047a2..b4b09413896 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -437,6 +437,8 @@ show warnings;
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 5f09992d464..0e2f53d5b15 100644
--- a/mysql-test/t/fulltext_plugin.test
+++ b/mysql-test/t/fulltext_plugin.test
@@ -3,7 +3,7 @@
#
# BUG#39746 - Debug flag breaks struct definition (server crash)
#
---replace_regex /\.dll/.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;
diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test
index 77b2fd67ffa..a18ce6b5c51 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 e3c7cf8281f..7d0e5ae819a 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 85147e28cf9..30f5657ffdf 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -1336,3 +1336,20 @@ SELECT f1,MIN(f2),MAX(f2) FROM t1 GROUP BY 1;
DROP TABLE t1;
--echo #End of test#49771
+--echo #
+--echo # lp: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/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_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/join.test b/mysql-test/t/join.test
index c4f2b6cb61f..82e67904e9f 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -1015,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 ca0d10c3ee1..caf5af57df7 100644
--- a/mysql-test/t/join_cache.test
+++ b/mysql-test/t/join_cache.test
@@ -1220,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;
@@ -1241,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;
@@ -1564,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;
@@ -1602,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
@@ -2264,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;
@@ -2292,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;
@@ -2393,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;
@@ -2425,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,
@@ -2435,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,
@@ -2449,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;
@@ -2531,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 = 256;
@@ -2567,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;
@@ -2614,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,
@@ -2630,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 = 256;
@@ -2665,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;
@@ -2766,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);
@@ -2941,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;
@@ -3063,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;
@@ -3085,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 = 256;
@@ -3137,5 +3225,34 @@ SET SESSION join_cache_level = DEFAULT;
DROP TABLE t1, t2;
+--echo #
+--echo # Bug #887479: join_cache_level=3 + semijoin=on
+--echo #
+
+CREATE TABLE t1 (a int, b int);
+INSERT INTO t1 VALUES (3914,17), (3710,5), (3888,20);
+
+CREATE TABLE t2 (c int, KEY (c));
+INSERT INTO t2 VALUES (27), (17), (33), (20), (3), (7), (18), (2);
+
+SET @tmp887479_optimizer_switch=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=on';
+SET SESSION optimizer_switch='semijoin_with_cache=on';
+
+SET SESSION join_cache_level=1;
+EXPLAIN
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+
+SET SESSION join_cache_level=3;
+EXPLAIN
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
+
+SET SESSION join_cache_level = DEFAULT;
+SET optimizer_switch=@tmp887479_optimizer_switch;
+
+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 deda56eb8ee..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
diff --git a/mysql-test/t/join_nested_jcl6.test b/mysql-test/t/join_nested_jcl6.test
index 6b04d8d58b5..809755b1fbf 100644
--- a/mysql-test/t/join_nested_jcl6.test
+++ b/mysql-test/t/join_nested_jcl6.test
@@ -26,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
@@ -35,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
@@ -50,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 f98dbcdf7ac..059606d9f86 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -1329,6 +1329,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;
@@ -1419,3 +1421,56 @@ 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: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: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/kill.test b/mysql-test/t/kill.test
index 4aa765caa8c..7c6c37ecfc6 100644
--- a/mysql-test/t/kill.test
+++ b/mysql-test/t/kill.test
@@ -349,7 +349,7 @@ SET DEBUG_SYNC = 'RESET';
let $ID= `SELECT @id := CONNECTION_ID()`;
SET DEBUG_SYNC= 'thread_end SIGNAL con1_end';
--disable_reconnect
---error ER_QUERY_INTERRUPTED
+--error ER_CONNECTION_KILLED
KILL @id;
connection con2;
@@ -604,5 +604,33 @@ drop table t2;
###########################################################################
+--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;
+
SET DEBUG_SYNC = 'RESET';
DROP FUNCTION MY_KILL;
diff --git a/mysql-test/t/maria_mrr.test b/mysql-test/t/maria_mrr.test
index 9d26a01d5e0..d67572033c8 100644
--- a/mysql-test/t/maria_mrr.test
+++ b/mysql-test/t/maria_mrr.test
@@ -74,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;
@@ -105,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
diff --git a/mysql-test/t/mrr_icp_extra.test b/mysql-test/t/mrr_icp_extra.test
index 2d0fd527dcf..f1b21154449 100644
--- a/mysql-test/t/mrr_icp_extra.test
+++ b/mysql-test/t/mrr_icp_extra.test
@@ -57,6 +57,7 @@ DROP TABLE t1,t2,t3;
--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;
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index cab06a03498..fa82be90427 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 66ffbfa3821..bbff6c30e56 100644
--- a/mysql-test/t/myisam_icp.test
+++ b/mysql-test/t/myisam_icp.test
@@ -2,11 +2,11 @@
# ICP/MyISAM tests (Index Condition Pushdown)
#
---source include/icp_tests.inc
-
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
drop table if exists t0, t1, t1i, t1m;
--enable_warnings
@@ -209,4 +209,52 @@ INSERT INTO t1 VALUES
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 9c4c7be4fa2..1e070ec9a34 100644
--- a/mysql-test/t/myisam_mrr.test
+++ b/mysql-test/t/myisam_mrr.test
@@ -199,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,6 +226,47 @@ where
set join_cache_level= @save_join_cache_level;
set join_buffer_size= @save_join_buffer_size;
-set optimizer_switch= @myisam_mrr_tmp;
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 52d9b52b26e..069cf37c3e6 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/order_by.test b/mysql-test/t/order_by.test
index 99945a82c7f..d514ae88afd 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_pruning.test b/mysql-test/t/partition_pruning.test
index f2ca16b9259..da41b8e9428 100644
--- a/mysql-test/t/partition_pruning.test
+++ b/mysql-test/t/partition_pruning.test
@@ -892,6 +892,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/range.test b/mysql-test/t/range.test
index 0a34bac32ba..746d6bad896 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -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
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 e9ae69826e5..3781f7a5d43 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -1966,6 +1966,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;
diff --git a/mysql-test/t/select_safe.test b/mysql-test/t/select_safe.test
index cca736d4c1d..c76e337cd10 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/subselect.test b/mysql-test/t/subselect.test
index 0b368f5be67..6369e4edbeb 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -14,7 +14,7 @@ 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");
+ "semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=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);
@@ -292,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;
@@ -503,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
@@ -934,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);
@@ -1817,6 +1866,9 @@ drop table t1;
# Bug#11867 queries with ROW(,elems>) IN (SELECT DISTINCT <cols> FROM ...)
#
+set @tmp11867_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='semijoin_with_cache=off';
+
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');
@@ -1844,6 +1896,7 @@ explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FR
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;
DROP TABLE t1,t2;
+set optimizer_switch=@tmp11867_optimizer_switch;
#
# Bug#12392 where cond with IN predicate for rows and NULL values in table
@@ -4722,6 +4775,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: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
@@ -4748,20 +4882,29 @@ WHERE
DROP TABLE t1,t2,t3;
--echo #
---echo # Fix of LP BUG#780386 (NULL left part with empty ALL subquery).
+--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 ( 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);
+CREATE TABLE t1 (c int) ;
+INSERT INTO t1 VALUES (5),(6);
-DROP TABLE IF EXISTS t3;
-CREATE TABLE t3 ( f3 int) ;
-INSERT INTO t3 VALUES (0),(0);
+CREATE TABLE t2 (a int, b int) ;
+INSERT INTO t2 VALUES (20,9),(20,9);
-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;
+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
@@ -4860,4 +5003,64 @@ eval explain $query;
DROP TABLE t1,t2;
+--echo #
+--echo # lp: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/subselect3.test b/mysql-test/t/subselect3.test
index 1e92a147bcd..13c4b532c74 100644
--- a/mysql-test/t/subselect3.test
+++ b/mysql-test/t/subselect3.test
@@ -3,7 +3,7 @@ drop table if exists t0, t1, t2, t3, t4, t5, t11, t12, t21, t22;
--enable_warnings
set @subselect3_tmp= @@optimizer_switch;
-set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on';
#
# 1. Subquery with GROUP/HAVING
@@ -81,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);
@@ -1186,6 +1187,52 @@ CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1, t2;
+--echo #
+--echo # fix of lp:824425 (prohibiting subqueries in row in
+--echo # left part of IN/ALL/ANY)
+--echo #
+
+CREATE TABLE t1 ( a int) ;
+INSERT INTO t1 VALUES (20),(30);
+
+CREATE TABLE t2 (a int) ;
+INSERT INTO t2 VALUES (3),(9);
+
+CREATE TABLE t3 ( a int, b int) ;
+INSERT INTO t3 VALUES (20,5),(30,6);
+
+set @optimizer_switch_save=@@optimizer_switch;
+SET SESSION optimizer_switch='semijoin=OFF,in_to_exists=OFF,materialization=ON,partial_match_rowid_merge=ON,partial_match_table_scan=OFF';
+
+SELECT * FROM t1
+WHERE (
+ ( SELECT a FROM t2 WHERE a = 9 )
+) NOT IN (
+ SELECT b
+ FROM t3
+);
+explain extended
+SELECT * FROM t1
+WHERE (
+ ( SELECT a FROM t2 WHERE a = 9 )
+) NOT IN (
+ SELECT b
+ FROM t3
+);
+
+--error ER_NOT_SUPPORTED_YET
+SELECT * FROM t1
+WHERE (
+ ( SELECT a FROM t2 WHERE a = 9 ),
+ ( SELECT a FROM t2 WHERE a = 3 )
+) NOT IN (
+ SELECT b , a
+ FROM t3
+);
+set optimizer_switch=@optimizer_switch_save;
+
+drop table t1,t2,t3;
+
--echo End of 5.3 tests
--echo #
diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test
index b31ba9b8f89..41ca1762fef 100644
--- a/mysql-test/t/subselect4.test
+++ b/mysql-test/t/subselect4.test
@@ -7,6 +7,7 @@ drop view if exists v1, v2;
set @subselect4_tmp= @@optimizer_switch;
set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
+set optimizer_switch='semijoin_with_cache=on';
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
--echo #
@@ -239,35 +240,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
@@ -1591,5 +1563,72 @@ 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 e4671cf7b2a..d06bf06756a 100644
--- a/mysql-test/t/subselect_cache.test
+++ b/mysql-test/t/subselect_cache.test
@@ -1,6 +1,8 @@
--disable_warnings
drop table if exists t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
+drop view if exists v1;
--enable_warnings
+
set optimizer_switch='subquery_cache=on';
create table t1 (a int, b int);
@@ -1666,5 +1668,33 @@ 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
index 466f254e6ad..b76f3f70516 100644
--- a/mysql-test/t/subselect_extra.test
+++ b/mysql-test/t/subselect_extra.test
@@ -9,11 +9,12 @@
--disable_warnings
drop table if exists t1,t2,t3,t4;
+drop view if exists v1,v2,v3;
--enable_warnings
set @subselect_extra_tmp=@@optimizer_switch;
-set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
-
+set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_extra_test,
+ "semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=on,partial_match_rowid_merge=off,partial_match_table_scan=off");
--echo # From explain.test:
--echo #
@@ -273,6 +274,122 @@ 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);
-set optimizer_switch= @subselect_extra_tmp;
+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..8aba3dde72b
--- /dev/null
+++ b/mysql-test/t/subselect_extra_no_semijoin.test
@@ -0,0 +1,9 @@
+set @subselect_extra_no_sj_tmp=@@optimizer_switch;
+
+set @optimizer_switch_for_subselect_extra_test='semijoin=off,firstmatch=off,loosescan=off,semijoin_with_cache=off';
+
+--source t/subselect_extra.test
+
+set optimizer_switch= @subselect_extra_no_sj_tmp;
+
+set @optimizer_switch_for_subselect_extra_test=null; \ No newline at end of file
diff --git a/mysql-test/t/subselect_innodb.test b/mysql-test/t/subselect_innodb.test
index 3e2914eaef4..27ec36854f4 100644
--- a/mysql-test/t/subselect_innodb.test
+++ b/mysql-test/t/subselect_innodb.test
@@ -1,5 +1,7 @@
-- 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
@@ -250,5 +252,61 @@ INSERT INTO t1 VALUES ('2011-05-13', 0);
SELECT * FROM t1 WHERE b < (SELECT CAST(a as date) FROM t1 GROUP BY a);
DROP TABLE t1;
-# Cleanups
+--echo #
+--echo # lp: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: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 a70fb4783c5..09c6b3e1747 100644
--- a/mysql-test/t/subselect_mat.test
+++ b/mysql-test/t/subselect_mat.test
@@ -226,3 +226,31 @@ 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 8a0d1ac702d..5a1fb550ca4 100644
--- a/mysql-test/t/subselect_mat_cost.test
+++ b/mysql-test/t/subselect_mat_cost.test
@@ -15,6 +15,11 @@
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 long_query_time=0.1;
-- echo TEST GROUP 1:
@@ -222,13 +227,15 @@ 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));
+ 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));
+ 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
diff --git a/mysql-test/t/subselect_mat_cost_bugs.test b/mysql-test/t/subselect_mat_cost_bugs.test
index 37c7b617760..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;
@@ -348,4 +354,63 @@ 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_opts.test b/mysql-test/t/subselect_no_opts.test
index 005b2f041fa..724cbab6310 100644
--- a/mysql-test/t/subselect_no_opts.test
+++ b/mysql-test/t/subselect_no_opts.test
@@ -3,7 +3,7 @@
# (test in-to-exists)
-set @optimizer_switch_for_subselect_test='materialization=off,semijoin=off,mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+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_for_subselect_test=null;
diff --git a/mysql-test/t/subselect_scache.test b/mysql-test/t/subselect_no_scache.test
index 0032b148643..fe8ff749a59 100644
--- a/mysql-test/t/subselect_scache.test
+++ b/mysql-test/t/subselect_no_scache.test
@@ -2,7 +2,7 @@
# Run subselect.test without semi-join optimization (test materialize)
#
select @@optimizer_switch like '%subquery_cache=on%';
-set optimizer_switch='subquery_cache=on';
+set optimizer_switch='subquery_cache=off';
--source t/subselect.test
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 8d1fbd9b8d7..be78360c76b 100644
--- a/mysql-test/t/subselect_partial_match.test
+++ b/mysql-test/t/subselect_partial_match.test
@@ -10,12 +10,14 @@ set @save_optimizer_switch=@@optimizer_switch;
--echo -------------------------------
--echo Default for all tests.
-set @@optimizer_switch="materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off";
+set @@optimizer_switch = "materialization=on,in_to_exists=off,semijoin=off,subquery_cache=off";
+set @test_default_opt_switch = @@optimizer_switch;
+set @in_exists = "materialization=off,in_to_exists=on,semijoin=off,subquery_cache=off";
---echo
+--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
+--echo -------------------------------------------------------------------------
create table t1 (a1 char(8) not null, a2 char(8) not null);
create table t2 (b1 char(8), b2 char(8));
@@ -36,9 +38,9 @@ select a1, a2, (a1, a2) not in (select * from t2) as in_res from t1;
drop table t1, t2;
---echo
+--echo -------------------------------------------------------------------------
--echo NULLs in the outer columns, no NULLs in the suqbuery
---echo
+--echo -------------------------------------------------------------------------
create table t1 (a1 char(8), a2 char(8));
create table t2 (b1 char(8) not null, b2 char(8) not null);
@@ -63,21 +65,366 @@ select a1, a2, (a1, a2) in (select * from t2) as in_res from t1;
drop table t1, t2;
---echo
+--echo -------------------------------------------------------------------------
+--echo NULLs in the outer column, NULLs in the subquery, there is
+--echo no value match in any column, but there is a partial match
+--echo such that some of the matching NULLs are in the outer columns,
+--echo the other NULLs are in the inner columns.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(1), a2 char(1), a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+
+insert into t1 values ('c', NULL, 'a');
+insert into t2 values (NULL, 'x', NULL);
+insert into t2 values (NULL, 'y', NULL);
+insert into t2 values ('o', 'z', 'p');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch = @test_default_opt_switch;
+
+drop table t1, t2;
+
+create table t1 (a1 char(1), a2 char(1) not null, a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+
+insert into t1 values (NULL, 'y', NULL);
+insert into t2 values ('v', 'x', NULL);
+insert into t2 values (NULL, 'y', 'w');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch = @test_default_opt_switch;
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo There is only one column in the subquery to complement the NULLs in the
+--echo outer reference. It is a NULL column, so a match is guaranteed.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(1), a2 char(1), a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+
+insert into t1 values (NULL, 'g', NULL);
+insert into t2 values ('z', NULL, 'y');
+insert into t2 values (NULL, 'z', 'y');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch = @test_default_opt_switch;
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo The intersection of the NULL bitmaps is empty because the ranges
+--echo of NULL bits do not overlap.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(1), a2 char(1), a3 char(1));
+create table t2 (b1 char(1), b2 char(1), b3 char(1));
+
+insert into t1 values ('b', 'g', NULL);
+insert into t2 values ('z', NULL, 'y');
+insert into t2 values (NULL, 'z', 'y');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo The intersection of the NULL bitmaps is non-empty, and there is a
+--echo non-NULL column.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(1), a2 char(1), a3 char(1) not null, a4 char(10));
+create table t2 (b1 char(1), b2 char(1), b3 char(1), b4 char(1));
+
+insert into t1 values ('a', 'g', 'x', NULL);
+insert into t2 values ('z', NULL, 'y', 'x');
+insert into t2 values (NULL, NULL, 'x', 'y');
+insert into t2 values ('x', 'w', 'z', NULL);
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo Value match in one row, but the NULL complement match in another.
+--echo The result must be false.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(2), a2 char(1), a3 char(1) not null, a4 char(10));
+create table t2 (b1 char(2), b2 char(1), b3 char(1), b4 char(1));
+
+insert into t1 values ('99', NULL, 'j', 'f');
+
+insert into t2 values ('01', NULL, 'y', NULL);
+insert into t2 values ('02', NULL, 'x', 'y');
+insert into t2 values ('03', 'q', 'y', 'x');
+insert into t2 values (NULL, 'q', 'm', 'p');
+insert into t2 values ('m', 'z', 'j', NULL);
+insert into t2 values (NULL, 'z', 'b', NULL);
+insert into t2 values (NULL, 'z', 'a', NULL);
+insert into t2 values ('34', 'q', 'y', 'x');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+drop table t1, t2;
+
+--echo -------------------------------------------------------------------------
+--echo Test the intersection of larger number of rows with NULL, such that
+--echo the number is at the boundary 32. This test is based on the implementation
+--echo of MY_BITMAP which uses 32 bit words, and the intersection operation works
+--echo by intersecting the bitmap word by word.
+--echo -------------------------------------------------------------------------
+
+create table t1 (a1 char(2), a2 char(2), a3 char(1), a4 char(10)) ENGINE=MyISAM;
+create table t2 (b1 char(2), b2 char(2), b3 char(1), b4 char(1)) ENGINE=MyISAM;
+
+insert into t1 values (NULL, '98', NULL, 'b');
+insert into t1 values (NULL, '99', NULL, 'c');
+
+insert into t2 values ('00', 'rr', 'y', NULL);
+insert into t2 values ('01', 'rr', 'y', NULL);
+insert into t2 values ('02', NULL, 'x', 'y');
+insert into t2 values ('03', 'qq', 'y', 'x');
+insert into t2 values ('04', 'qq', 'm', 'p');
+insert into t2 values ('05', 'rr', 'y', NULL);
+insert into t2 values ('06', NULL, 'x', 'y');
+insert into t2 values ('07', 'qq', 'y', 'x');
+insert into t2 values ('08', 'qq', 'm', 'q');
+insert into t2 values ('09', 'rr', 'y', NULL);
+insert into t2 values ('10', NULL, 'x', 'y');
+insert into t2 values ('11', 'qq', 'y', 'x');
+insert into t2 values ('12', 'qq', 'm', 'k');
+insert into t2 values ('13', 'rr', 'y', NULL);
+insert into t2 values ('14', NULL, 'x', 'y');
+insert into t2 values ('15', 'qq', 'y', 'x');
+insert into t2 values ('16', 'qq', 'm', 's');
+insert into t2 values ('17', 'rr', 'y', NULL);
+insert into t2 values ('18', NULL, 'x', 'y');
+insert into t2 values ('19', 'qq', 'y', 'x');
+insert into t2 values ('20', 'qq', 'm', 't');
+insert into t2 values ('21', 'rr', 'y', NULL);
+insert into t2 values ('22', NULL, 'x', 'y');
+insert into t2 values ('23', 'qq', 'y', 'x');
+insert into t2 values ('24', 'qq', 'm', 'u');
+insert into t2 values ('25', 'rr', 'y', NULL);
+insert into t2 values ('26', NULL, 'x', 'y');
+insert into t2 values ('27', 'qq', 'y', 'x');
+insert into t2 values ('28', 'qq', 'm', 'y');
+insert into t2 values ('29', 'rr', 'y', NULL);
+insert into t2 values ('30', NULL, 'x', 'z');
+insert into t2 values ('31', 'ss', 'h', NULL);
+insert into t2 values ('32', 'vv', 'i', NULL);
+--echo the only partial matching row
+insert into t2 values ('33', NULL, 'j', NULL);
+insert into t2 values ('34', 'qq', 'y', 'x');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+--echo change the mathcing row to be the last one in the first bitmap word
+update t2 set b2 = 'zz' where b1 = 33;
+update t2 set b2 = NULL where b1 = 31;
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=on';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+set @@optimizer_switch=@in_exists;
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+EXPLAIN
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+SELECT * from t1 where (a1, a2, a3, a4) NOT IN (select * from t2);
+
+drop table t1, t2;
+
+
+--echo -------------------------------------------------------------------------
--echo All columns require partial matching (no non-null columns)
---echo
+--echo -------------------------------------------------------------------------
--echo TODO
---echo
+--echo -------------------------------------------------------------------------
--echo Both non-NULL columns and columns with NULLs
---echo
+--echo -------------------------------------------------------------------------
--echo TODO
---echo
+--echo -------------------------------------------------------------------------
--echo Covering NULL rows
---echo
+--echo -------------------------------------------------------------------------
create table t1 (a1 char(8), a2 char(8));
create table t2 (b1 char(8), b2 char(8));
@@ -110,9 +457,9 @@ select a1, a2, (a1, a2) in (select * from t2) as in_res from t1;
drop table t1, t2;
---echo
+--echo -------------------------------------------------------------------------
--echo Covering NULL columns
---echo
+--echo -------------------------------------------------------------------------
--echo this case affects only the rowid-merge algorithm
set @@optimizer_switch="partial_match_rowid_merge=on,partial_match_table_scan=off";
@@ -161,9 +508,9 @@ select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
drop table t1, t2;
---echo
+--echo -------------------------------------------------------------------------
--echo Covering NULL row, and a NULL column
---echo
+--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));
@@ -188,9 +535,9 @@ select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
drop table t1, t2;
---echo
+--echo -------------------------------------------------------------------------
--echo Covering NULL row, and covering NULL columns
---echo
+--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));
@@ -213,6 +560,34 @@ select *, (a1, a2, a3) in (select * from t2) as in_res from t1;
drop table t1, t2;
+--echo -------------------------------------------------------------------------
+--echo Small buffer for the rowid_merge partial match algorithm that forces
+--echo reverting to table scan partial match.
+--echo -------------------------------------------------------------------------
+
+set @save_rowid_merge_buff_size = @@rowid_merge_buff_size;
+set @@rowid_merge_buff_size = 0;
+
+create table t1 (a1 char(2), a2 char(2), a3 char(1), a4 char(10));
+create table t2 (b1 char(2), b2 char(2), b3 char(1), b4 char(1));
+
+insert into t1 values (NULL, '98', NULL, 'b');
+insert into t1 values (NULL, '99', NULL, 'c');
+
+insert into t2 values ('00', 'rr', 'y', NULL);
+insert into t2 values ('01', 'rr', 'y', NULL);
+insert into t2 values ('02', NULL, 'x', 'y');
+insert into t2 values ('03', 'qq', 'y', 'x');
+
+set @@optimizer_switch='partial_match_rowid_merge=on,partial_match_table_scan=off';
+EXPLAIN
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+SELECT t1.*, (a1, a2, a3, a4) IN (select * from t2) as in_res from t1;
+
+drop table t1, t2;
+
+set @@rowid_merge_buff_size = @save_rowid_merge_buff_size;
+
--echo -------------------------------
--echo Part 2: Test cases for bugs.
@@ -354,4 +729,50 @@ 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;
+
+--echo #
+--echo # LP BUG#869036 Wrong result with in_to_exists=ON and NOT IN
+--echo #
+
+create table outer_sq (f1 char(1), f2 char(1));
+insert into outer_sq values (NULL, 'c'), ('g', 'c');
+
+create table inner_sq (f3 char(1), f4 char(1));
+insert into inner_sq values(null, 'i'), ('v', null);
+
+--echo All three strategies below must produce the same result.
+
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off';
+SELECT outer_sq.*, (f1, f2) IN (select * from inner_sq) from outer_sq;
+SELECT * from outer_sq where (f1, f2) NOT IN (select * from inner_sq);
+
+set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_merge=off,partial_match_table_scan=on';
+SELECT outer_sq.*, (f1, f2) IN (select * from inner_sq) from outer_sq;
+SELECT * from outer_sq where (f1, f2) NOT IN (select * from inner_sq);
+
+set @@optimizer_switch='in_to_exists=on,materialization=off';
+SELECT outer_sq.*, (f1, f2) IN (select * from inner_sq) from outer_sq;
+SELECT * from outer_sq where (f1, f2) NOT IN (select * from inner_sq);
+
+drop table outer_sq, inner_sq;
+
set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/subselect_sj.test b/mysql-test/t/subselect_sj.test
index 66c7b1bc549..740289ffcc8 100644
--- a/mysql-test/t/subselect_sj.test
+++ b/mysql-test/t/subselect_sj.test
@@ -2,7 +2,7 @@
# 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
@@ -776,6 +776,7 @@ eval EXPLAIN EXTENDED $query;
eval $query;
DROP TABLE t1, t2;
+
--echo # End of Bug#48213
--echo #
@@ -1571,5 +1572,313 @@ SELECT * FROM t1 WHERE c1 IN ( SELECT t3.c1 FROM t3 LEFT JOIN t2 ON t2 .c1 = t3
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;
+
+--echo #
+--echo # Bug #889750: semijoin=on + firstmatch=off + semijoin_with_cache=off
+--echo #
+
+create table t1 (a int);
+insert into t1 values (7), (1), (5), (3);
+create table t2 (a int);
+insert into t2 values (4), (1), (8), (3), (9), (2);
+
+set @tmp_otimizer_switch= @@optimizer_switch;
+set optimizer_switch='semijoin=on';
+set optimizer_switch='firstmatch=off';
+
+set optimizer_switch='semijoin_with_cache=on';
+explain
+select * from t1 where t1.a in (select t2.a from t2);
+select * from t1 where t1.a in (select t2.a from t2);
+
+set optimizer_switch='semijoin_with_cache=off';
+explain
+select * from t1 where t1.a in (select t2.a from t2);
+select * from t1 where t1.a in (select t2.a from t2);
+
+set optimizer_switch= @tmp_otimizer_switch;
+
+drop table t1,t2;
+
# The following command must be the last one the file
set optimizer_switch=@subselect_sj_tmp;
diff --git a/mysql-test/t/subselect_sj2.test b/mysql-test/t/subselect_sj2.test
index 7972ff50450..0fd8cab1a04 100644
--- a/mysql-test/t/subselect_sj2.test
+++ b/mysql-test/t/subselect_sj2.test
@@ -28,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;
@@ -43,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);
@@ -578,6 +581,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;
@@ -947,4 +951,123 @@ 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_sj_jcl6.test b/mysql-test/t/subselect_sj_jcl6.test
index 44ee52686b3..e475adbf9a8 100644
--- a/mysql-test/t/subselect_sj_jcl6.test
+++ b/mysql-test/t/subselect_sj_jcl6.test
@@ -22,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 0ea1c3873eb..a72128bf5ed 100644
--- a/mysql-test/t/subselect_sj_mat.test
+++ b/mysql-test/t/subselect_sj_mat.test
@@ -4,12 +4,12 @@
#
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=ifnull(@subselect_mat_test_optimizer_switch_value, 'semijoin=on,firstmatch=on,loosescan=on,semijoin_with_cache=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;
@@ -1242,5 +1242,190 @@ select left(a1,7), left(a2,7) from t1_1024 where (a1,3) in (select substring(b1,
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/table_elim.test b/mysql-test/t/table_elim.test
index 5576362b396..3b584ce2b38 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;
@@ -499,3 +500,21 @@ WHERE t3.f2 ;
DROP TABLE t1,t2,t3,t4,t5;
+--echo #
+--echo # BUG#884184: Wrong result with RIGHT JOIN + derived_merge
+--echo #
+CREATE TABLE t1 (a int(11), b varchar(1)) ;
+INSERT IGNORE INTO t1 VALUES (0,'g');
+
+CREATE TABLE t3 ( a varchar(1)) ;
+INSERT IGNORE INTO t3 VALUES ('g');
+
+CREATE TABLE t2 ( a int(11) NOT NULL, PRIMARY KEY (a)) ;
+create view v1 as SELECT t1.* FROM t1 LEFT JOIN t2 ON ( t1.a = t2.a ) WHERE t2.a <> 0;
+
+SELECT alias1.* FROM t3 LEFT JOIN v1 as alias1 ON ( t3.a = alias1.b );
+EXPLAIN SELECT alias1.* FROM t3 LEFT JOIN v1 as alias1 ON ( t3.a = alias1.b );
+
+drop view v1;
+DROP TABLE t1,t2,t3;
+
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 85cf01a607f..1bd637f477c 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -2406,6 +2406,29 @@ 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.
--echo #
--echo # Bug#34453 Can't change size of file (Errcode: 1224)
@@ -2521,8 +2544,6 @@ select trigger_name from information_schema.triggers
drop temporary table t1;
drop table t1;
-
---echo
--echo #
--echo # Bug #12362125: SP INOUT HANDLING IS BROKEN FOR TEXT TYPE.
--echo #
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 1bf3f9a3103..a8b549ca774 100644
--- a/mysql-test/t/user_limits.test
+++ b/mysql-test/t/user_limits.test
@@ -1,3 +1,4 @@
+skip enable when max_user_connections can be negative
#
# Test behavior of various per-account limits (aka quotas)
#
@@ -8,6 +9,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 +123,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 +178,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 3f7c4541a43..e9b428ff26c 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";
@@ -817,7 +819,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;
@@ -832,6 +834,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 f464239b81e..df47526ef21 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -4465,7 +4465,27 @@ DROP TABLE t1;
disconnect con2;
disconnect con3;
-
# Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc
+
+--echo #
+--echo # lp: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/t/xtradb_mrr.test b/mysql-test/t/xtradb_mrr.test
index 0653f9859c3..37a0159babd 100644
--- a/mysql-test/t/xtradb_mrr.test
+++ b/mysql-test/t/xtradb_mrr.test
@@ -420,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');
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index 739cc587ac0..5174b04c054 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -414,6 +414,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/ma_dyncol.c b/mysys/ma_dyncol.c
index 0901fe6bea1..c717f69c3e5 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 */
}
@@ -1741,11 +1741,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;
@@ -1876,7 +1875,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
{
@@ -1913,17 +1912,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 908f5c65cf7..c84a41bbec9 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -168,11 +168,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.
@@ -1755,7 +1753,7 @@ int my_b_flush_io_cache(IO_CACHE *info,
*/
if (!append_cache && info->seek_not_done)
{ /* File touched, do seek */
- if (mysql_file_seek(info->file, pos_in_file, MY_SEEK_SET, MYF(0)) ==
+ if (mysql_file_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_bitmap.c b/mysys/my_bitmap.c
index 414d5acaaf0..8328efea8ac 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -96,6 +96,44 @@ void create_last_word_mask(MY_BITMAP *map)
}
+static inline my_bitmap_map last_word_mask(uint bit)
+{
+ my_bitmap_map last_word_mask;
+ uint n_bits= bit + 1;
+ unsigned char const mask= invers_last_byte_mask(n_bits);
+
+ /*
+ The first bytes are to be set to zero since they represent real bits
+ in the bitvector. The last bytes are set to 0xFF since they represent
+ bytes not used by the bitvector. Finally the last byte contains bits
+ as set by the mask above.
+ */
+ unsigned char *ptr= (unsigned char*)&last_word_mask;
+
+ switch ((n_bits + 7)/8 & 3) {
+ case 1:
+ last_word_mask= ~0U;
+ ptr[0]= mask;
+ break;
+ case 2:
+ last_word_mask= ~0U;
+ ptr[0]= 0;
+ ptr[1]= mask;
+ break;
+ case 3:
+ last_word_mask= 0U;
+ ptr[2]= mask;
+ ptr[3]= 0xFFU;
+ break;
+ case 0:
+ last_word_mask= 0U;
+ ptr[3]= mask;
+ break;
+ }
+ return last_word_mask;
+}
+
+
static inline void bitmap_lock(MY_BITMAP *map __attribute__((unused)))
{
if (map->mutex)
@@ -380,6 +418,58 @@ void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
}
}
+
+/*
+ Check if there is some bit index between start_bit and end_bit, such that
+ this is bit is set for all bitmaps in bitmap_list.
+
+ SYNOPSIS
+ bitmap_exists_intersection()
+ bitmpap_array [in] a set of MY_BITMAPs
+ bitmap_count [in] number of elements in bitmpap_array
+ start_bit [in] beginning (inclusive) of the range of bits to search
+ end_bit [in] end (inclusive) of the range of bits to search, must be
+ no bigger than the bits of the shortest bitmap.
+
+ NOTES
+ This function assumes that for at least one of the bitmaps in bitmap_array all
+ bits outside the range [start_bit, end_bit] are 0. As a result is not
+ necessary to take care of the bits outside the range [start_bit, end_bit].
+
+ RETURN
+ TRUE if an intersecion exists
+ FALSE no intersection
+*/
+
+my_bool bitmap_exists_intersection(const MY_BITMAP **bitmap_array,
+ uint bitmap_count,
+ uint start_bit, uint end_bit)
+{
+ uint i, j, start_idx, end_idx;
+ my_bitmap_map cur_res;
+
+ DBUG_ASSERT(bitmap_count && end_bit >= start_bit);
+ for (j= 0; j < bitmap_count; j++)
+ DBUG_ASSERT(end_bit < bitmap_array[j]->n_bits);
+
+ start_idx= start_bit/8/sizeof(my_bitmap_map);
+ end_idx= end_bit/8/sizeof(my_bitmap_map);
+
+ for (i= start_idx; i < end_idx; i++)
+ {
+ cur_res= ~0;
+ for (j= 0; cur_res && j < bitmap_count; j++)
+ cur_res &= bitmap_array[j]->bitmap[i];
+ if (cur_res)
+ return TRUE;
+ }
+ cur_res= ~last_word_mask(end_bit);
+ for (j= 0; cur_res && j < bitmap_count; j++)
+ cur_res &= bitmap_array[j]->bitmap[end_idx];
+ return cur_res != 0;
+}
+
+
/* True if union of bitmaps have all bits set */
my_bool bitmap_union_is_set_all(const MY_BITMAP *map1, const MY_BITMAP *map2)
diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c
index 54823a7c5ca..4360daca6f8 100644
--- a/mysys/my_gethwaddr.c
+++ b/mysys/my_gethwaddr.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2004, 2010, Oracle and/or its affiliates.
+ 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
@@ -21,8 +22,17 @@
#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,140 +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;
}
-#elif defined(__WIN__)
-
-/*
- Workaround for BUG#32082 (Definition of VOID in my_global.h conflicts with
- windows headers)
-*/
-#ifdef VOID
-#undef VOID
-#define VOID void
-#endif
-
+#elif defined(_WIN32)
+#include <winsock2.h>
#include <iphlpapi.h>
-/*
- The following typedef is for dynamically loading iphlpapi.dll /
- GetAdaptersAddresses. Dynamic loading is used because
- GetAdaptersAddresses is not available on Windows 2000 which MySQL
- still supports. Static linking would cause an unresolved export.
-*/
-typedef DWORD (WINAPI *pfnGetAdaptersAddresses)(IN ULONG Family,
- IN DWORD Flags,IN PVOID Reserved,
- OUT PIP_ADAPTER_ADDRESSES pAdapterAddresses,
- IN OUT PULONG pOutBufLen);
+#define ETHER_ADDR_LEN 6
-/*
- my_gethwaddr - Windows version
+my_bool my_gethwaddr(uchar *to)
+{
+ my_bool res= 1;
- @brief Retrieve MAC address from network hardware
+ IP_ADAPTER_INFO *info= NULL;
+ ULONG info_len= 0;
- @param[out] to MAC address exactly six bytes
+ if (GetAdaptersInfo(info, &info_len) != ERROR_BUFFER_OVERFLOW)
+ goto err;
- @return Operation status
- @retval 0 OK
- @retval <>0 FAILED
-*/
-my_bool my_gethwaddr(uchar *to)
-{
- PIP_ADAPTER_ADDRESSES pAdapterAddresses;
- PIP_ADAPTER_ADDRESSES pCurrAddresses;
- IP_ADAPTER_ADDRESSES adapterAddresses;
- ULONG address_len;
- my_bool return_val= 1;
- static pfnGetAdaptersAddresses fnGetAdaptersAddresses=
- (pfnGetAdaptersAddresses)-1;
-
- if(fnGetAdaptersAddresses == (pfnGetAdaptersAddresses)-1)
- {
- /* Get the function from the DLL */
- fnGetAdaptersAddresses= (pfnGetAdaptersAddresses)
- GetProcAddress(LoadLibrary("iphlpapi.dll"),
- "GetAdaptersAddresses");
- }
- if (!fnGetAdaptersAddresses)
- return 1; /* failed to get function */
- address_len= sizeof (IP_ADAPTER_ADDRESSES);
+ info= alloca(info_len);
- /* Get the required size for the address data. */
- if (fnGetAdaptersAddresses(AF_UNSPEC, 0, 0, &adapterAddresses, &address_len)
- == ERROR_BUFFER_OVERFLOW)
- {
- pAdapterAddresses= my_malloc(address_len, 0);
- if (!pAdapterAddresses)
- return 1; /* error, alloc failed */
- }
- else
- pAdapterAddresses= &adapterAddresses; /* one is enough don't alloc */
+ if (GetAdaptersInfo(info, &info_len) != NO_ERROR)
+ goto err;
- /* Get the hardware info. */
- if (fnGetAdaptersAddresses(AF_UNSPEC, 0, 0, pAdapterAddresses, &address_len)
- == NO_ERROR)
+ while (info && res)
{
- pCurrAddresses= pAdapterAddresses;
-
- while (pCurrAddresses)
+ if (info->Type == MIB_IF_TYPE_ETHERNET &&
+ info->AddressLength == ETHER_ADDR_LEN)
{
- /* Look for ethernet cards. */
- if (pCurrAddresses->IfType == IF_TYPE_ETHERNET_CSMACD)
- {
- /* check for a good address */
- if (pCurrAddresses->PhysicalAddressLength < 6)
- continue; /* bad address */
-
- /* save 6 bytes of the address in the 'to' parameter */
- memcpy(to, pCurrAddresses->PhysicalAddress, 6);
-
- /* Network card found, we're done. */
- return_val= 0;
- break;
- }
- pCurrAddresses= pCurrAddresses->Next;
+ res= memcpy_and_test(to, info->Address, ETHER_ADDR_LEN);
}
+ info = info->Next;
}
- /* Clean up memory allocation. */
- if (pAdapterAddresses != &adapterAddresses)
- my_free(pAdapterAddresses);
-
- return return_val;
+err:
+ return res;
}
-#else /* __FreeBSD__ || __linux__ || __WIN__ */
+#else /* unsupported system */
/* just fail */
my_bool my_gethwaddr(uchar *to __attribute__((unused)))
{
@@ -214,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 d9e34cbece6..ea09370280e 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -395,10 +395,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 6bbc11714ca..e366268936b 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -75,6 +75,7 @@ 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;
/* Default creation of new files */
if ((str= getenv("UMASK")) != 0)
diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c
index 2555c052fc3..24bccf37ece 100644
--- a/mysys/my_malloc.c
+++ b/mysys/my_malloc.c
@@ -30,6 +30,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;
/* Safety */
if (!size)
@@ -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_open.c b/mysys/my_open.c
index cfbc9257aec..645d6709358 100644
--- a/mysys/my_open.c
+++ b/mysys/my_open.c
@@ -41,6 +41,8 @@ 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 (!(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)
@@ -70,6 +72,8 @@ 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;
mysql_mutex_lock(&THR_LOCK_open);
#ifndef _WIN32
@@ -85,7 +89,8 @@ int my_close(File fd, myf MyFlags)
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)
{
@@ -151,8 +156,8 @@ 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);
diff --git a/mysys/my_pread.c b/mysys/my_pread.c
index 4aa12eec33c..51b4c5f5599 100644
--- a/mysys/my_pread.c
+++ b/mysys/my_pread.c
@@ -51,8 +51,13 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset,
int error= 0;
DBUG_ENTER("my_pread");
+
DBUG_PRINT("my",("fd: %d Seek: %llu Buffer: %p Count: %lu MyFlags: %d",
Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags));
+
+ if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP)))
+ MyFlags|= my_global_flags;
+
for (;;)
{
errno= 0; /* Linux, Windows don't reset this on EOF/success */
@@ -79,11 +84,13 @@ 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_filename(Filedes),my_errno);
- else if (MyFlags & (MY_NABP | MY_FNABP))
- my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG),
+ if (readbytes == (size_t) -1)
+ 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 | (MyFlags & (ME_JUST_INFO | ME_NOREFRESH))),
my_filename(Filedes),my_errno);
}
if (readbytes == (size_t) -1 || (MyFlags & (MY_FNABP | MY_NABP)))
@@ -127,6 +134,8 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
Filedes, (ulonglong)offset, Buffer, (ulong)Count, MyFlags));
errors= 0;
written= 0;
+ if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP)))
+ MyFlags|= my_global_flags;
for (;;)
{
@@ -159,20 +168,19 @@ size_t my_pwrite(int Filedes, const uchar *Buffer, size_t Count,
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_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 */
+ 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(writtenbytes+written); /* purecov: inspected */
+ DBUG_RETURN(0); /* Want only errors */
+ DBUG_RETURN(writtenbytes+written); /* purecov: inspected */
} /* my_pwrite */
diff --git a/mysys/my_read.c b/mysys/my_read.c
index ca5fbfaeef6..0afbf3773f3 100644
--- a/mysys/my_read.c
+++ b/mysys/my_read.c
@@ -40,6 +40,8 @@ size_t my_read(File Filedes, uchar *Buffer, size_t Count, myf MyFlags)
DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d",
Filedes, Buffer, (ulong) Count, MyFlags));
save_count= Count;
+ if (!(MyFlags & (MY_WME | MY_FAE | MY_FNABP)))
+ MyFlags|= my_global_flags;
for (;;)
{
@@ -70,10 +72,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_static.c b/mysys/my_static.c
index ae32ae6387e..5b088704acc 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -33,6 +33,8 @@ ulong my_stream_opened=0,my_file_opened=0, my_tmp_file_created=0;
ulong my_file_total_opened= 0;
int my_umask=0664, my_umask_dir=0777;
+myf my_global_flags= 0;
+my_bool my_assert_on_error= 0;
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_write.c b/mysys/my_write.c
index e873228620a..dc04b60f613 100644
--- a/mysys/my_write.c
+++ b/mysys/my_write.c
@@ -28,6 +28,8 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
DBUG_PRINT("my",("fd: %d Buffer: %p Count: %lu MyFlags: %d",
Filedes, 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))
@@ -87,19 +89,20 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags)
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(0); /* Want only errors */
DBUG_RETURN(writtenbytes+written);
} /* my_write */
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index de222e7047f..d268fb618d5 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/plugin/feedback/CMakeLists.txt b/plugin/feedback/CMakeLists.txt
new file mode 100644
index 00000000000..7407cc65637
--- /dev/null
+++ b/plugin/feedback/CMakeLists.txt
@@ -0,0 +1,18 @@
+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)
+
+INCLUDE (CheckIncludeFiles)
+CHECK_INCLUDE_FILES (netdb.h HAVE_NETDB_H)
+IF(HAVE_NETDB_H)
+ ADD_DEFINITIONS(-DHAVE_NETDB_H)
+ENDIF(HAVE_NETDB_H)
+
+IF(WIN32)
+ #SET(FEEDBACK_LIBS Ws2_32)
+ MYSQL_ADD_PLUGIN(FEEDBACK ${FEEDBACK_SOURCES} STATIC_ONLY)
+ELSE(WIN32)
+ MYSQL_ADD_PLUGIN(FEEDBACK ${FEEDBACK_SOURCES})
+ENDIF(WIN32)
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..975aaef7d38
--- /dev/null
+++ b/plugin/feedback/feedback.cc
@@ -0,0 +1,393 @@
+/* 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
+*/
+mysql_mutex_t sleep_mutex;
+mysql_cond_t sleep_condition;
+volatile bool shutdown_plugin;
+static pthread_t sender_thread;
+
+static PSI_mutex_key key_sleep_mutex;
+static PSI_mutex_info mutex_list[]=
+{{ &key_sleep_mutex, "sleep_mutex", PSI_FLAG_GLOBAL}};
+
+static PSI_cond_key key_sleep_cond;
+static PSI_cond_info cond_list[]=
+{{ &key_sleep_cond, "sleep_condition", PSI_FLAG_GLOBAL}};
+
+static PSI_thread_key key_sender_thread;
+static PSI_thread_info thread_list[] =
+{{&key_sender_thread, "sender_thread", 0}};
+
+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
+
+#define PSI_register(X) \
+ PSI_server->register_ ## X("feedback", X ## _list, array_elements(X ## _list))
+
+ PSI_register(mutex);
+ PSI_register(cond);
+ PSI_register(thread);
+
+ 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)
+ {
+ mysql_mutex_init(0, &sleep_mutex, 0);
+ mysql_cond_init(0, &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);
+ }
+
+ return 0;
+}
+
+/**
+ plugin deinitialization function
+*/
+static int free(void *p)
+{
+ if (url_count)
+ {
+ mysql_mutex_lock(&sleep_mutex);
+ shutdown_plugin= true;
+ mysql_cond_signal(&sleep_condition);
+ mysql_mutex_unlock(&sleep_mutex);
+ pthread_join(sender_thread, NULL);
+
+ mysql_mutex_destroy(&sleep_mutex);
+ mysql_cond_destroy(&sleep_condition);
+
+ for (uint i= 0; i < url_count; i++)
+ delete urls[i];
+ my_free(urls);
+ }
+ 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,
+ 0x0101,
+ NULL,
+ feedback::settings,
+ NULL,
+ 0
+}
+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,
+ 0x0101,
+ NULL,
+ feedback::settings,
+ "1.1",
+ 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..74fb806fac2
--- /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 <sql_class.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); }
+
+ 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 mysql_mutex_t sleep_mutex;
+extern mysql_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..4ab45998484
--- /dev/null
+++ b/plugin/feedback/sender_thread.cc
@@ -0,0 +1,305 @@
+/* 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 <sql_acl.h>
+#include <sql_parse.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;
+ mysql_mutex_lock(&LOCK_thread_count);
+ thread_count++;
+ threads.append(thd);
+ mysql_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->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,
+ INFORMATION_SCHEMA_NAME.length,
+ i_s_feedback->table_name,
+ strlen(i_s_feedback->table_name),
+ 0, 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);
+
+ mysql_mutex_lock(&sleep_mutex);
+ while (!going_down() && ret != ETIMEDOUT)
+ ret= mysql_cond_timedwait(&sleep_condition, &sleep_mutex, &abstime);
+ mysql_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.
+ */
+ mysql_mutex_lock(&LOCK_thread_count);
+ bzero(&thd->status_var, sizeof(thd->status_var));
+ thread_count--;
+ thd->killed= KILL_CONNECTION;
+ mysql_cond_broadcast(&COND_thread_count);
+ mysql_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;
+
+ mysql_mutex_lock(&LOCK_thread_count);
+ thd_thread_id= thread_id++;
+ mysql_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..e7d038f02e2
--- /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));
+
+ return self;
+}
+
+} // namespace feedback
diff --git a/plugin/feedback/url_http.cc b/plugin/feedback/url_http.cc
new file mode 100644
index 00000000000..a9d4c5bbbaf
--- /dev/null
+++ b/plugin/feedback/url_http.cc
@@ -0,0 +1,307 @@
+/* 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
+#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);
+ my_free(port.str);
+ my_free(path.str);
+ }
+
+ 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);
+ my_free(port.str);
+ my_free(path.str);
+ 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= 0;
+
+ 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.
+ */
+ for (;;)
+ {
+ size_t i= vio_read(vio, (uchar*)buf + len, sizeof(buf) - len - 1);
+ if ((int)i <= 0)
+ break;
+ len+= i;
+ }
+ 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..48bbd72d530
--- /dev/null
+++ b/plugin/feedback/utils.cc
@@ -0,0 +1,393 @@
+/* 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()
+{
+#ifdef _WIN32
+ MEMORYSTATUSEX memstatus;
+ memstatus.dwLength= sizeof(memstatus);
+ GlobalMemoryStatusEx(&memstatus);
+ return memstatus.ullTotalPhys;
+#else
+ ulonglong pages= 0;
+
+#ifdef _SC_PHYS_PAGES
+ pages= sysconf(_SC_PHYS_PAGES);
+#endif
+
+#ifdef _SC_PAGESIZE
+ return pages * sysconf(_SC_PAGESIZE);
+#else
+ return pages * my_getpagesize();
+#endif
+#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));
+ INSERT1("Now", (thd->query_start(), 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/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/make_binary_distribution.sh b/scripts/make_binary_distribution.sh
index 95de41d517b..7c9126f0d71 100644
--- a/scripts/make_binary_distribution.sh
+++ b/scripts/make_binary_distribution.sh
@@ -167,6 +167,7 @@ echo "PLATFORM NAME: $PLATFORM"
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
diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql
index 5179f35c0b6..c8e0aa7b435 100644
--- a/scripts/mysql_system_tables.sql
+++ b/scripts/mysql_system_tables.sql
@@ -28,7 +28,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, Create_tablespace_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(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, authentication_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, Create_tablespace_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(64) CHARACTER SET latin1 DEFAULT '' NOT NULL, authentication_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 697838b55a3..cc697092e6e 100644
--- a/scripts/mysql_system_tables_fix.sql
+++ b/scripts/mysql_system_tables_fix.sql
@@ -343,8 +343,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/sql-bench/crash-me.sh b/sql-bench/crash-me.sh
index 473a66933cc..4391a2afb40 100644
--- a/sql-bench/crash-me.sh
+++ b/sql-bench/crash-me.sh
@@ -40,7 +40,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;
@@ -620,6 +620,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",
@@ -633,8 +635,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)",
@@ -664,7 +665,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;
@@ -747,10 +748,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)",
@@ -1062,7 +1067,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]"}))
@@ -1137,7 +1142,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]",
@@ -3133,8 +3138,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);
@@ -4350,7 +4358,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;
@@ -4370,7 +4378,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
@@ -4392,14 +4400,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/my_time.c b/sql-common/my_time.c
index 0a00a09257d..83271aa91a0 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -343,7 +343,7 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
{
if (str[0] == 'p' || str[0] == 'P')
add_hours= 12;
- else if (str[0] != 'a' || str[0] != 'A')
+ else if (str[0] != 'a' && str[0] != 'A')
continue; /* Not AM/PM */
str+= 2; /* Skip AM/PM */
/* Skip space after AM/PM */
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index eb8e3b093c9..2f356122687 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -1123,7 +1123,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
@@ -1838,7 +1838,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/event_scheduler.cc b/sql/event_scheduler.cc
index 8944b749305..55a3f6b36c4 100644
--- a/sql/event_scheduler.cc
+++ b/sql/event_scheduler.cc
@@ -659,7 +659,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);
mysql_mutex_unlock(&scheduler_thd->LOCK_thd_data);
/* thd could be 0x0, when shutting down */
diff --git a/sql/filesort.cc b/sql/filesort.cc
index ebef3b2716b..a9db198e9d3 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -526,7 +526,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");
@@ -566,12 +566,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);
@@ -644,15 +643,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;
@@ -1243,9 +1248,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);
@@ -1253,7 +1258,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 040b5778dbd..3d140b92977 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -1870,7 +1870,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, TRUE,
schema->name[0] == 0 || thd->db[0] == 0,
diff --git a/sql/handler.cc b/sql/handler.cc
index 90889e046e9..1d0f676493d 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1478,9 +1478,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));
@@ -2609,7 +2613,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);
/*
@@ -4779,7 +4783,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
@@ -4812,7 +4816,7 @@ static int write_locked_table_maps(THD *thd)
MYSQL_LOCK *locks[2];
locks[0]= thd->extra_lock;
locks[1]= thd->lock;
- 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 )
@@ -4996,6 +5000,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 7a75253f040..fc38794a410 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -1788,7 +1788,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), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
+ ref(0), end_range(NULL), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
in_range_check_pushed_down(FALSE),
ref_length(sizeof(my_off_t)),
ft_handler(0), inited(NONE),
@@ -1845,6 +1845,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()
@@ -1852,6 +1853,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));
@@ -2567,6 +2569,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; }
diff --git a/sql/item.cc b/sql/item.cc
index d768c7a4218..028cc8c8e30 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -806,7 +806,9 @@ 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 < prm->nest_level)
+ 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;
}
@@ -2343,6 +2345,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
{
@@ -5011,6 +5018,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;
@@ -5544,6 +5552,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, TRUE);
@@ -6345,7 +6357,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)
@@ -7746,7 +7758,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;
}
/*
@@ -9521,6 +9537,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
@@ -9533,7 +9555,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 c3bdc5042c8..9186ba084db 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -541,6 +541,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 */
@@ -1144,9 +1145,11 @@ 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; }
+ virtual bool is_subquery_processor (uchar *opt_arg) { return 0; }
/* To call bool function for all arguments */
struct bool_func_call_args
@@ -1288,8 +1291,10 @@ public:
}
struct Collect_deps_prm
{
- int nest_level;
List<Item> *parameters;
+ /* unit from which we count nest_level */
+ st_select_lex_unit *nest_level_base;
+ int nest_level;
};
/**
Collect outer references
@@ -1461,6 +1466,8 @@ public:
be defined for Item_func.
*/
virtual void get_cache_parameters(List<Item> &parameters) { };
+
+ virtual void mark_as_condition_AND_part(TABLE_LIST *embedding) {};
};
@@ -2022,6 +2029,20 @@ public:
bool get_date_result(MYSQL_TIME *ltime,ulonglong 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);
@@ -2033,6 +2054,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; }
@@ -3153,6 +3175,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) ||
@@ -3848,6 +3871,20 @@ public:
{ return test(example && example->basic_const_item());}
virtual void clear() { null_value= TRUE; value_cached= FALSE; }
bool is_null() { return null_value; }
+ virtual bool is_expensive()
+ {
+ DBUG_ASSERT(example);
+ if (value_cached)
+ return false;
+ return example->is_expensive();
+ }
+ bool is_expensive_processor(uchar *arg)
+ {
+ DBUG_ASSERT(example);
+ if (value_cached)
+ return false;
+ return example->is_expensive_processor(arg);
+ }
};
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 7a062b413ce..14c8c9b9138 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -33,8 +33,6 @@
#include "sql_time.h" // make_truncated_value_warning
#include "sql_base.h" // dynamic_column_error_message
-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)
{
@@ -519,7 +517,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,
@@ -551,14 +548,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;
@@ -566,7 +563,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;
}
@@ -1401,6 +1399,16 @@ bool Item_in_optimizer::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;
@@ -1424,6 +1432,7 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
cache->setup(args[0]);
if (cache->cols() == 1)
{
+ DBUG_ASSERT(args[0]->type() != ROW_ITEM);
/*
Note: there can be cases when used_tables()==0 && !const_item(). See
Item_sum::update_used_tables for details.
@@ -1438,6 +1447,14 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
uint n= cache->cols();
for (uint i= 0; i < n; i++)
{
+ /* Check that the expression (part of row) do not contain a subquery */
+ if (args[0]->element_index(i)->walk(&Item::is_subquery_processor,
+ FALSE, NULL))
+ {
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0),
+ "SUBQUERY in ROW in left expression of IN/ALL/ANY");
+ return 1;
+ }
Item *element=args[0]->element_index(i);
if (element->used_tables() || !element->const_item())
((Item_cache *)cache->element_index(i))->set_used_tables(OUTER_REF_TABLE_BIT);
@@ -1784,7 +1801,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
{
@@ -2135,6 +2152,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;
@@ -2169,7 +2194,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
@@ -2519,6 +2545,15 @@ Item_func_if::eval_not_null_tables(uchar *opt_arg)
}
+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()
{
@@ -2771,7 +2806,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)))
@@ -2971,7 +3006,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();
/*
As the first expression and WHEN expressions
@@ -3023,14 +3058,18 @@ void Item_func_case::fix_length_and_dec()
change_item_tree_if_needed(thd, &args[nagg * 2], agg[nagg + 1]);
}
+ 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 == 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;
}
@@ -3624,10 +3663,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;
}
@@ -3830,6 +3872,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,
@@ -3928,7 +3978,8 @@ void Item_func_in::fix_length_and_dec()
!thd->lex->is_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++)
@@ -4151,13 +4202,10 @@ 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;
uchar buff[sizeof(char*)]; // Max local vars in function
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()
@@ -4217,7 +4265,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;
@@ -4229,6 +4276,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++))
{
@@ -4487,6 +4535,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 ...).
@@ -5740,7 +5799,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);
}
@@ -5843,7 +5902,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;
@@ -5868,8 +5926,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 ef12364ae68..1aa48034566 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -267,6 +267,7 @@ public:
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
@@ -679,6 +680,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);
};
@@ -785,6 +787,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);
};
@@ -1323,6 +1326,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
@@ -1807,6 +1811,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)
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 1c6a9c23b26..c771bfbf133 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -177,9 +177,7 @@ 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;
uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
- thd->thd_marker.emb_on_expr_nest= NULL;
used_tables_cache= not_null_tables_cache= 0;
const_item_cache=1;
@@ -233,7 +231,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;
}
@@ -5497,7 +5494,7 @@ void Item_func_get_system_var::fix_length_and_dec()
case SHOW_LONG:
case SHOW_INT:
case SHOW_HA_ROWS:
- unsigned_flag= TRUE;
+ unsigned_flag= TRUE; //var->show_type() != SHOW_INT;
collation.set_numeric();
fix_char_length(MY_INT64_NUM_DECIMAL_DIGITS);
decimals=0;
diff --git a/sql/item_row.cc b/sql/item_row.cc
index df03b0e0ebb..ccd7a37e9b7 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -156,11 +156,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_strfunc.cc b/sql/item_strfunc.cc
index 1b3c1a616b9..f570c309d79 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -3847,40 +3847,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
{
@@ -3889,13 +3889,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);
@@ -3904,7 +3904,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);
+ my_free(vals[i].x.string.value.str);
vals[i].type= DYN_COL_NULL;
}
}
@@ -3918,7 +3918,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);
+ my_free(vals[i].x.string.value.str);
}
}
@@ -4135,19 +4135,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
{
@@ -4156,24 +4156,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);
@@ -4191,7 +4191,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);
@@ -4221,20 +4221,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),
@@ -4247,14 +4247,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),
@@ -4267,18 +4267,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:
@@ -4300,24 +4300,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),
@@ -4329,13 +4329,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:
@@ -4357,22 +4357,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,
@@ -4383,14 +4383,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;
}
@@ -4419,37 +4419,37 @@ bool Item_dyncol_get::get_date(MYSQL_TIME *ltime, ulonglong 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(&my_charset_numeric,
- val.string_value.str,
- val.string_value.length,
+ 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 40f1e753d60..f25722ab30b 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -168,9 +168,11 @@ 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;
@@ -186,10 +188,9 @@ void Item_allany_subselect::cleanup()
*/
for (SELECT_LEX *sl= unit->first_select();
sl; sl= sl->next_select())
- if (in_strategy & SUBS_MAXMIN_INJECTED)
+ if (test_strategy(SUBS_MAXMIN_INJECTED))
sl->with_sum_func= false;
Item_in_subselect::cleanup();
-
}
@@ -239,7 +240,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)
@@ -502,6 +503,7 @@ 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));
@@ -524,6 +526,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 (this->*processor)(argument);
+ }
if (walk_subquery)
{
@@ -596,7 +612,9 @@ bool Item_subselect::exec()
void Item_subselect::get_cache_parameters(List<Item> &parameters)
{
- Collect_deps_prm prm= { unit->first_select()->nest_level, &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);
}
@@ -717,7 +735,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();
/*
@@ -834,7 +852,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;
@@ -1177,8 +1198,9 @@ 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),
+ 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)
@@ -1599,7 +1621,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_INJECTED | SUBS_MAXMIN_ENGINE)))
+ if (!test_strategy(SUBS_MAXMIN_INJECTED | SUBS_MAXMIN_ENGINE))
DBUG_RETURN(false);
Item **place= optimizer->arguments() + 1;
THD *thd= join->thd;
@@ -1610,11 +1632,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;
@@ -1664,7 +1695,7 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
Remove other strategies if any (we already changed the query and
can't apply other strategy).
*/
- in_strategy= SUBS_MAXMIN_INJECTED;
+ set_strategy(SUBS_MAXMIN_INJECTED);
}
else
{
@@ -1676,13 +1707,13 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
Remove other strategies if any (we already changed the query and
can't apply other strategy).
*/
- in_strategy= SUBS_MAXMIN_ENGINE;
+ set_strategy(SUBS_MAXMIN_ENGINE);
}
/*
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(left_expr, subs);
+ subs= func->create_swap(*(optimizer->get_cache()), subs);
thd->change_item_tree(place, subs);
if (subs->fix_fields(thd, &subs))
DBUG_RETURN(true);
@@ -2263,7 +2294,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);
+ }
}
}
@@ -2391,7 +2427,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
{
@@ -2407,7 +2443,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));
/*
@@ -2461,7 +2497,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;
}
@@ -2471,6 +2506,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()
@@ -2583,8 +2619,7 @@ Item_allany_subselect::select_transformer(JOIN *join)
{
DBUG_ENTER("Item_allany_subselect::select_transformer");
DBUG_ASSERT((in_strategy & ~(SUBS_MAXMIN_INJECTED | SUBS_MAXMIN_ENGINE |
- SUBS_IN_TO_EXISTS)) == 0);
- in_strategy|= SUBS_IN_TO_EXISTS;
+ SUBS_IN_TO_EXISTS | SUBS_STRATEGY_CHOSEN)) == 0);
if (upper_item)
upper_item->show= 1;
DBUG_RETURN(select_in_like_transformer(join));
@@ -2593,7 +2628,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
{
@@ -2979,7 +3014,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;
@@ -3917,6 +3952,8 @@ subselect_hash_sj_engine::get_strategy_using_data()
}
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. */
@@ -4395,7 +4432,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);
@@ -4585,7 +4628,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;
/*
@@ -4681,6 +4725,7 @@ int subselect_hash_sj_engine::exec()
count_pm_keys,
has_covering_null_row,
has_covering_null_columns,
+ count_columns_with_nulls,
item, result,
semi_join_conds->argument_list());
if (!pm_engine ||
@@ -4706,7 +4751,8 @@ int subselect_hash_sj_engine::exec()
item, result,
semi_join_conds->argument_list(),
has_covering_null_row,
- has_covering_null_columns)))
+ has_covering_null_columns,
+ count_columns_with_nulls)))
{
/* This is an irrecoverable error. */
res= 1;
@@ -4825,14 +4871,14 @@ bool Ordered_key::init(MY_BITMAP *columns_to_index)
Item_func_lt *fn_less_than;
key_column_count= bitmap_bits_set(columns_to_index);
-
- // TIMOUR: check for mem allocation err, revert to scan
-
key_columns= (Item_field**) thd->alloc(key_column_count *
sizeof(Item_field*));
compare_pred= (Item_func_lt**) thd->alloc(key_column_count *
sizeof(Item_func_lt*));
+ if (!key_columns || !compare_pred)
+ return TRUE; /* Revert to table scan partial match. */
+
for (uint i= 0; i < columns_to_index->n_bits; i++)
{
if (!bitmap_is_set(columns_to_index, i))
@@ -5143,43 +5189,48 @@ subselect_partial_match_engine::subselect_partial_match_engine(
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg,
- bool has_covering_null_columns_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),
has_covering_null_row(has_covering_null_row_arg),
- has_covering_null_columns(has_covering_null_columns_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;
@@ -5287,10 +5338,13 @@ subselect_rowid_merge_engine::init(MY_BITMAP *non_null_key_parts,
merge_keys_count == 1 && non_null_key_parts));
/*
Allocate buffers to hold the merged keys and the mapping between rowids and
- row numbers.
+ row numbers. All small buffers are allocated in the runtime memroot. Big
+ buffers are allocated from the OS via malloc.
*/
if (!(merge_keys= (Ordered_key**) thd->alloc(merge_keys_count *
sizeof(Ordered_key*))) ||
+ !(null_bitmaps= (MY_BITMAP**) thd->alloc(merge_keys_count *
+ sizeof(MY_BITMAP*))) ||
!(row_num_to_rowid= (uchar*) my_malloc((size_t)(row_count * rowid_length),
MYF(MY_WME))))
return TRUE;
@@ -5508,6 +5562,56 @@ bool subselect_rowid_merge_engine::test_null_row(rownum_t row_num)
}
+/**
+ Test if a subset of NULL-able columns contains a row of NULLs.
+*/
+
+bool subselect_rowid_merge_engine::
+exists_complementing_null_row(MY_BITMAP *keys_to_complement)
+{
+ rownum_t highest_min_row= 0;
+ rownum_t lowest_max_row= UINT_MAX;
+ uint count_null_keys, i, j;
+ Ordered_key *cur_key;
+
+ count_null_keys= keys_to_complement->n_bits -
+ bitmap_bits_set(keys_to_complement);
+ if (count_null_keys == 1)
+ {
+ /*
+ The caller guarantees that the complement to keys_to_complement
+ contains only columns with NULLs. Therefore if there is only one column,
+ it is guaranteed to contain NULLs.
+ */
+ return TRUE;
+ }
+
+ for (i= (non_null_key ? 1 : 0), j= 0; i < merge_keys_count; i++)
+ {
+ cur_key= merge_keys[i];
+ if (bitmap_is_set(keys_to_complement, cur_key->get_keyid()))
+ continue;
+ DBUG_ASSERT(cur_key->get_null_count());
+ if (cur_key->get_min_null_row() > highest_min_row)
+ highest_min_row= cur_key->get_min_null_row();
+ if (cur_key->get_max_null_row() < lowest_max_row)
+ lowest_max_row= cur_key->get_max_null_row();
+ null_bitmaps[j++]= cur_key->get_null_key();
+ }
+ DBUG_ASSERT(count_null_keys == j);
+
+ if (lowest_max_row < highest_min_row)
+ {
+ /* The intersection of NULL rows is empty. */
+ return FALSE;
+ }
+
+ return bitmap_exists_intersection((const MY_BITMAP**) null_bitmaps,
+ count_null_keys,
+ highest_min_row, lowest_max_row);
+}
+
+
/*
@retval TRUE there is a partial match (UNKNOWN)
@retval FALSE there is no match at all (FALSE)
@@ -5520,6 +5624,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_null_in_any_row=
+ ((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. */
@@ -5571,22 +5677,53 @@ bool subselect_rowid_merge_engine::partial_match()
/*
If the outer reference consists of only NULLs, or if it has NULLs in all
- nullable columns, the result is UNKNOWN.
+ nullable columns (above we guarantee there is a match for the non-null
+ coumns), the result is UNKNOWN.
*/
- if (count_nulls_in_search_key ==
- ((Item_in_subselect *) item)->left_expr->cols() -
- (non_null_key ? non_null_key->get_column_count() : 0))
+ if (count_nulls_in_search_key == merge_keys_count - test(non_null_key))
{
res= TRUE;
goto end;
}
/*
+ If the outer row has NULLs in some columns, and
+ there is no match for any of the remaining columns, and
+ there is a subquery row with NULLs in all unmatched columns,
+ then there is a partial match, otherwise the result is FALSE.
+ */
+ if (count_nulls_in_search_key && !pq.elements)
+ {
+ DBUG_ASSERT(!non_null_key);
+ /*
+ Check if the intersection of all NULL bitmaps of all keys that
+ are not in matching_outer_cols is non-empty.
+ */
+ res= exists_complementing_null_row(&matching_outer_cols);
+ goto end;
+ }
+
+ /*
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.
+ match for any of the NULL columns, the result is FALSE. Notice that if there
+ is a non-null key, and there is only one matching key, the non-null key is
+ the matching key. This is so, because this method returns FALSE if the
+ non-null key doesn't have a match.
*/
- if (pq.elements - test(non_null_key) == 0)
+ if (!count_nulls_in_search_key &&
+ (!pq.elements ||
+ (pq.elements == 1 && non_null_key &&
+ max_null_in_any_row < merge_keys_count-1)))
{
+ if (!pq.elements)
+ {
+ DBUG_ASSERT(!non_null_key);
+ /*
+ The case of a covering null row is handled by
+ subselect_partial_match_engine::exec()
+ */
+ DBUG_ASSERT(max_null_in_any_row != tmp_table->s->fields);
+ }
res= FALSE;
goto end;
}
@@ -5630,6 +5767,7 @@ bool subselect_rowid_merge_engine::partial_match()
{
min_key= cur_key;
min_row_num= cur_row_num;
+ bitmap_clear_all(&matching_keys);
bitmap_set_bit(&matching_keys, min_key->get_keyid());
bitmap_union(&matching_keys, &matching_outer_cols);
}
@@ -5650,6 +5788,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;
@@ -5663,11 +5803,13 @@ subselect_table_scan_engine::subselect_table_scan_engine(
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg,
- bool has_covering_null_columns_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,
has_covering_null_row_arg,
- has_covering_null_columns_arg)
+ has_covering_null_columns_arg,
+ count_columns_with_nulls_arg)
{}
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 5beabed9182..6007812fa7d 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -240,6 +240,7 @@ public:
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);
+ virtual bool is_subquery_processor (uchar *opt_arg) { return 1; }
friend class select_result_interceptor;
friend class Item_in_optimizer;
@@ -367,17 +368,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 */
/* The subquery has not aggregates, transform it into a MAX/MIN query. */
-#define SUBS_MAXMIN_INJECTED 32
+#define SUBS_MAXMIN_INJECTED 64
/* The subquery has aggregates, use a special max/min subselect engine. */
-#define SUBS_MAXMIN_ENGINE 64
+#define SUBS_MAXMIN_ENGINE 128
/**
@@ -412,6 +415,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:
@@ -442,7 +447,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;
/*
@@ -457,11 +461,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;
/*
@@ -473,7 +473,7 @@ public:
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.
@@ -502,8 +502,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)
{}
@@ -547,6 +547,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;
@@ -893,7 +957,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();
@@ -931,6 +995,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,
@@ -957,7 +1022,7 @@ protected:
/*
- Distinguish the type od (0-based) row numbers from the type of the index into
+ Distinguish the type of (0-based) row numbers from the type of the index into
an array of row numbers.
*/
typedef ha_rows rownum_t;
@@ -1033,9 +1098,9 @@ protected:
/* Count of NULLs per column. */
ha_rows null_count;
/* The row number that contains the first NULL in a column. */
- ha_rows min_null_row;
+ rownum_t min_null_row;
/* The row number that contains the last NULL in a column. */
- ha_rows max_null_row;
+ rownum_t max_null_row;
protected:
bool alloc_keys_buffers();
@@ -1068,6 +1133,10 @@ public:
DBUG_ASSERT(i < key_column_count);
return key_columns[i]->field->field_index;
}
+ rownum_t get_min_null_row() { return min_null_row; }
+ rownum_t get_max_null_row() { return max_null_row; }
+ MY_BITMAP * get_null_key() { return &null_key; }
+ ha_rows get_null_count() { return null_count; }
/*
Get the search key element that corresponds to the i-th key part of this
index.
@@ -1168,6 +1237,7 @@ protected:
guaranteed partial match.
*/
bool has_covering_null_columns;
+ uint count_columns_with_nulls;
protected:
virtual bool partial_match()= 0;
@@ -1178,7 +1248,8 @@ public:
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg,
- bool has_covering_null_columns_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**) {}
@@ -1236,6 +1307,8 @@ protected:
Ordered_key **merge_keys;
/* The number of elements in merge_keys. */
uint merge_keys_count;
+ /* The NULL bitmaps of merge keys.*/
+ MY_BITMAP **null_bitmaps;
/*
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
@@ -1261,6 +1334,7 @@ protected:
static int cmp_keys_by_cur_rownum(void *arg, uchar *k1, uchar *k2);
bool test_null_row(rownum_t row_num);
+ bool exists_complementing_null_row(MY_BITMAP *keys_to_complement);
bool partial_match();
public:
subselect_rowid_merge_engine(THD *thd_arg,
@@ -1268,13 +1342,15 @@ public:
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,
has_covering_null_row_arg,
- has_covering_null_columns_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();
@@ -1295,7 +1371,8 @@ public:
select_result_interceptor *result_arg,
List<Item> *equi_join_conds_arg,
bool has_covering_null_row_arg,
- bool has_covering_null_columns_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 55bcf868690..9bf786dbbd4 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -372,7 +372,9 @@ 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 < prm->nest_level)
+ 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;
}
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 37418e990a8..0d21d619421 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1486,7 +1486,8 @@ longlong Item_temporal_func::val_int()
MYSQL_TIME ltime;
if (get_date(&ltime, TIME_FUZZY_DATE | sql_mode))
return 0;
- return (longlong)TIME_to_ulonglong(&ltime);
+ longlong v= TIME_to_ulonglong(&ltime);
+ return ltime.neg ? -v : v;
}
@@ -2568,7 +2569,6 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
long days, microseconds;
longlong seconds;
int l_sign= sign, was_cut= 0;
- uint dec= decimals;
if (is_date) // TIMESTAMP function
{
@@ -2610,10 +2610,6 @@ bool Item_func_add_time::get_date(MYSQL_TIME *ltime, ulonglong 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 ea6e9fd9707..bb8f5825879 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -249,6 +249,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)},
@@ -515,6 +516,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 6819a1e767d..a7698fd3ae6 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -81,7 +81,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
mysql_mutex_t LOCK_prepare_ordered;
@@ -1256,17 +1256,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,
@@ -2088,7 +2077,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, FALSE, TRUE, errcode);
DBUG_RETURN(mysql_bin_log.write(&qinfo));
@@ -2112,7 +2101,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, FALSE, TRUE, errcode);
DBUG_RETURN(mysql_bin_log.write(&qinfo));
@@ -5614,7 +5603,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->stmt_da->sql_errno() : 0;
@@ -5623,7 +5612,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
@@ -7569,27 +7559,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 37245e6eb21..dddd24bc299 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -457,6 +457,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);
@@ -3793,7 +3794,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;
}
/*
Other cases: mostly we expected no error and get one.
diff --git a/sql/log_event.h b/sql/log_event.h
index 0383e746d94..c9810cbb140 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -3145,7 +3145,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 130ab676e7b..d8dc45d38c7 100644
--- a/sql/multi_range_read.cc
+++ b/sql/multi_range_read.cc
@@ -440,10 +440,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)
{
@@ -468,9 +468,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,
@@ -547,7 +547,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;
}
@@ -864,12 +864,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;
@@ -1651,7 +1653,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;
@@ -1676,7 +1679,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/mysqld.cc b/sql/mysqld.cc
index b6801d92ca8..46b6ec3978a 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -409,7 +409,7 @@ my_bool opt_local_infile, opt_slave_compressed_protocol;
my_bool opt_safe_user_create = 0;
my_bool opt_show_slave_auth_info;
my_bool opt_log_slave_updates= 0;
-my_bool opt_replicate_annotate_rows_events= 0;
+my_bool opt_replicate_annotate_row_events= 0;
char *opt_slave_skip_errors;
/*
@@ -500,6 +500,11 @@ my_decimal decimal_zero;
*/
ulong max_long_data_size;
+/* Limits for internal temporary tables (MyISAM or Aria) */
+uint internal_tmp_table_max_key_length;
+uint internal_tmp_table_max_key_segments;
+
+bool max_user_connections_checking=0;
/**
Limit of the total number of prepared statements in the server.
Is necessary to protect the server against out-of-memory attacks.
@@ -1389,7 +1394,7 @@ static void close_connections(void)
if (tmp->slave_thread)
continue;
- tmp->killed= THD::KILL_CONNECTION;
+ tmp->killed= KILL_SERVER_HARD;
MYSQL_CALLBACK(thread_scheduler, post_kill_notification, (tmp));
mysql_mutex_lock(&tmp->LOCK_thd_data);
if (tmp->mysys_var)
@@ -1449,7 +1454,7 @@ static void close_connections(void)
tmp->thread_id,
(tmp->main_security_ctx.user ?
tmp->main_security_ctx.user : ""));
- close_connection(tmp);
+ close_connection(tmp,ER_SERVER_SHUTDOWN);
}
#endif
DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
@@ -2335,6 +2340,16 @@ void close_connection(THD *thd, uint sql_errno)
if (sql_errno)
net_send_error(thd, sql_errno, ER_DEFAULT(sql_errno), NULL);
+ 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,
+ (sql_errno ? ER(sql_errno) : "CLOSE_CONNECTION"));
+ }
+
thd->disconnect();
MYSQL_CONNECTION_DONE((int) sql_errno, thd->thread_id);
@@ -2503,6 +2518,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);
}
@@ -2567,24 +2583,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
@@ -2798,6 +2796,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);
@@ -2842,20 +2842,29 @@ 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"
@@ -2865,8 +2874,7 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
fprintf(stderr, "\nConnection ID (thread ID): %lu\n", (ulong) thd->thread_id);
fprintf(stderr, "Status: %s\n", kreason);
fprintf(stderr, "Optimizer switch: ");
-
- ulonglong optsw= global_system_variables.optimizer_switch;
+ ulonglong optsw= thd->variables.optimizer_switch;
for (uint i= 0; optimizer_switch_names[i+1]; i++, optsw >>= 1)
{
if (i)
@@ -3218,7 +3226,7 @@ void my_message_sql(uint error, const char *str, myf MyFlags)
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);
DBUG_ASSERT(error != 0);
@@ -3250,7 +3258,7 @@ void my_message_sql(uint error, const char *str, myf MyFlags)
/* When simulating OOM, skip writing to error log to avoid mtr errors */
DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_VOID_RETURN;);
- if (!thd || (MyFlags & ME_NOREFRESH))
+ if (!thd || thd->log_all_errors || (MyFlags & ME_NOREFRESH))
(*func)("%s: %s", my_progname_short, str); /* purecov: inspected */
DBUG_VOID_RETURN;
}
@@ -4336,11 +4344,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_log_basename, ln);
}
if (ln == buf)
{
@@ -4497,6 +4507,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 ?
@@ -5446,7 +5461,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= mysql_thread_create(key_thread_one_connection,
&thd->real_id, &connection_attrib,
handle_one_connection,
@@ -5457,7 +5472,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
mysql_mutex_unlock(&LOCK_thread_count);
mysql_mutex_lock(&LOCK_connection_count);
@@ -5469,7 +5484,7 @@ void create_thread_to_handle_connection(THD *thd)
my_snprintf(error_message_buff, sizeof(error_message_buff),
ER_THD(thd, ER_CANT_CREATE_THREAD), error);
net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff, NULL);
- close_connection(thd);
+ close_connection(thd, ER_OUT_OF_RESOURCES);
mysql_mutex_lock(&LOCK_thread_count);
delete thd;
mysql_mutex_unlock(&LOCK_thread_count);
@@ -6543,6 +6558,10 @@ struct my_option my_long_options[]=
&table_cache_size, &table_cache_size, 0, GET_ULONG,
REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
#ifndef DBUG_OFF
+ {"debug-assert-on-error", 0,
+ "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},
{"debug-assert-if-crashed-table", 0,
"Do an assert in handler::print_error() if we get a crashed table",
&debug_assert_if_crashed_table, &debug_assert_if_crashed_table,
@@ -7969,6 +7988,19 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
my_disable_thr_alarm= opt_thread_alarm == 0;
my_default_record_cache_size=global_system_variables.read_buff_size;
+ /*
+ 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;
+
global_system_variables.long_query_time= (ulonglong)
(global_system_variables.long_query_time_double * 1e6);
@@ -8012,6 +8044,8 @@ static int get_options(int *argc_ptr, char ***argv_ptr)
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= global_system_variables.max_user_connections != 0;
return 0;
}
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 7b760c911d0..658d578a995 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -161,7 +161,7 @@ extern my_bool allow_slave_start;
extern LEX_CSTRING reason_slave_blocked;
extern ulong slave_trans_retries;
extern uint slave_net_timeout;
-extern uint max_user_connections;
+extern int max_user_connections;
extern ulong what_to_log,flush_time;
extern ulong max_prepared_stmt_count, prepared_stmt_count;
extern ulong open_files_limit;
@@ -534,6 +534,11 @@ extern char *opt_log_basename;
extern my_bool opt_master_verify_checksum;
extern my_bool opt_slave_sql_verify_checksum;
extern ulong binlog_checksum_options;
+extern bool max_user_connections_checking;
+extern ulong opt_binlog_dbug_fsync_sleep;
+
+extern uint internal_tmp_table_max_key_length;
+extern uint internal_tmp_table_max_key_segments;
extern uint volatile global_disable_checkpoint;
extern my_bool opt_help, opt_thread_alarm;
diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc
index cee96d88438..12a732176a5 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 9a61317b1a7..2a922541f72 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1164,10 +1164,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
@@ -1191,7 +1191,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++)
{
@@ -1202,7 +1202,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;
@@ -1238,22 +1238,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);
@@ -8473,9 +8470,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) ||
@@ -9170,6 +9167,13 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
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;
}
diff --git a/sql/opt_range.h b/sql/opt_range.h
index a52f3c2cd3a..cf8da1acb0d 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -375,6 +375,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
@@ -475,6 +481,7 @@ public:
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
+ virtual void replace_handler(handler *new_file) { file= new_file; }
QUICK_SELECT_I *make_reverse(uint used_key_parts_arg);
private:
/* Default copy ctor used by QUICK_SELECT_DESC */
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index c1fe8de51a4..0aa6fb7e913 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -209,6 +209,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
@@ -339,10 +407,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
@@ -352,7 +420,6 @@ 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() */
@@ -381,62 +448,17 @@ 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
- select_lex->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;
if (!in_subs->is_registered_semijoin)
{
@@ -456,17 +478,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_INJECTED | SUBS_MAXMIN_ENGINE) :
- 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
@@ -560,6 +583,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()) !=
@@ -825,14 +858,14 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
in_subq->unit->first_select()->join->table_count >= MAX_TABLES)
break;
if (convert_subq_to_sj(join, in_subq))
- DBUG_RETURN(TRUE);
+ 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);
+ goto restore_arena_and_fail;
}
if (remove_item)
{
@@ -841,7 +874,7 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
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:
@@ -877,12 +910,6 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
do_fix_fields))
DBUG_RETURN(TRUE);
in_subq->substitution= NULL;
-#if 0
- /*
- Don't do the following, because the simplify_join() call is after this
- call, and that call will save to prep_wher/prep_on_expr.
- */
-
/*
If this is a prepared statement, repeat the above operation for
prep_where (or prep_on_expr). Subquery-to-semijoin conversion is
@@ -893,21 +920,26 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
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,
+ /*
+ 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);
}
-#endif
/*
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++;
}
@@ -915,6 +947,11 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
thd->restore_active_arena(arena, &backup);
join->select_lex->sj_subselects.empty();
DBUG_RETURN(FALSE);
+
+restore_arena_and_fail:
+ if (arena)
+ thd->restore_active_arena(arena, &backup);
+ DBUG_RETURN(TRUE);
}
@@ -985,7 +1022,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;
@@ -1009,9 +1045,15 @@ 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* el1, Item_in_subselect* el2,
@@ -1214,7 +1256,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 */
@@ -1388,8 +1430,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;
@@ -1760,6 +1803,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
@@ -2134,6 +2180,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)
{
@@ -2640,6 +2697,7 @@ ulonglong get_bound_sj_equalities(TABLE_LIST *sj_nest,
{
res |= 1ULL << i;
}
+ i++;
}
return res;
}
@@ -2936,6 +2994,11 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
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 */
@@ -2984,6 +3047,9 @@ 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;
@@ -3320,7 +3386,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");
@@ -3401,8 +3467,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 */
{
/*
@@ -3819,6 +3883,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;
@@ -3854,7 +3920,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
if (j != join->const_tables && js_tab->use_quick != 2 &&
j <= no_jbuf_after &&
((js_tab->type == JT_ALL && join_cache_level != 0) ||
- (join_cache_level > 4 && (tab->type == JT_REF ||
+ (join_cache_level > 2 && (tab->type == JT_REF ||
tab->type == JT_EQ_REF))))
{
/* Looks like we'll be using join buffer */
@@ -4444,8 +4510,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);
@@ -4455,8 +4521,8 @@ 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;
@@ -4480,20 +4546,6 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
if (outer_join && outer_join->table_count > 0)
{
/*
- The index of the last JOIN_TAB in the outer JOIN where in_subs is
- attached (pushed to).
- */
- uint max_outer_join_tab_idx;
- /*
- 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 join_tab_idx remains MAX_TABLES. Such predicates
- are evaluated for each complete row of the outer join.
- */
- max_outer_join_tab_idx= (in_subs->get_join_tab_idx() == MAX_TABLES) ?
- outer_join->table_count - 1:
- in_subs->get_join_tab_idx();
- /*
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
@@ -4505,7 +4557,7 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
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_join->get_partial_cost_and_fanout(max_outer_join_tab_idx,
+ outer_join->get_partial_cost_and_fanout(in_subs->get_join_tab_idx(),
table_map(-1),
&dummy,
&outer_lookup_keys);
@@ -4574,9 +4626,9 @@ bool JOIN::choose_subquery_plan(table_map join_tables)
/* 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",
@@ -4597,7 +4649,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())
{
/*
@@ -4605,11 +4657,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)
@@ -4634,23 +4685,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. Cleanup 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;
}
@@ -4720,7 +4766,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_sum.cc b/sql/opt_sum.cc
index bcc8a42efc6..5962e7de706 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -631,6 +631,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo,
/* Condition doesn't restrict the used table */
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)
@@ -677,6 +679,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 9ab6e0e84d2..3de73c3d4cc 100644
--- a/sql/opt_table_elimination.cc
+++ b/sql/opt_table_elimination.cc
@@ -587,10 +587,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) |
@@ -694,6 +692,8 @@ eliminate_tables_for_list(JOIN *join, List<TABLE_LIST> *join_list,
{
table_map outside_used_tables= tables_used_elsewhere |
tables_used_on_left;
+ if (on_expr)
+ outside_used_tables |= on_expr->used_tables();
if (tbl->nested_join)
{
/* This is "... LEFT JOIN (join_nest) ON cond" */
diff --git a/sql/records.cc b/sql/records.cc
index a2bb49f9792..1e74e6d7f30 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -71,7 +71,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;
@@ -181,7 +180,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 &&
@@ -304,9 +302,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;
}
}
@@ -365,7 +363,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);
@@ -388,7 +386,7 @@ static int rr_index_first(READ_RECORD *info)
static int rr_index_last(READ_RECORD *info)
{
- int tmp= info->file->ha_index_last(info->record);
+ int tmp= info->table->file->ha_index_last(info->record);
info->read_record= rr_index_desc;
if (tmp)
tmp= rr_handle_error(info, tmp);
@@ -414,7 +412,7 @@ static int rr_index_last(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;
@@ -439,7 +437,7 @@ static int rr_index(READ_RECORD *info)
static int rr_index_desc(READ_RECORD *info)
{
- int tmp= info->file->ha_index_prev(info->record);
+ int tmp= info->table->file->ha_index_prev(info->record);
if (tmp)
tmp= rr_handle_error(info, tmp);
return tmp;
@@ -449,7 +447,7 @@ static int rr_index_desc(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
@@ -474,7 +472,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 ||
@@ -525,7 +523,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 */
@@ -658,7 +656,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);
@@ -689,7 +687,7 @@ static int rr_cmp(uchar *a,uchar *b)
if (a[4] != b[4])
return (int) a[4] - (int) b[4];
if (a[5] != b[5])
- return (int) a[1] - (int) b[5];
+ return (int) a[5] - (int) b[5];
if (a[6] != b[6])
return (int) a[6] - (int) b[6];
return (int) a[7] - (int) b[7];
diff --git a/sql/records.h b/sql/records.h
index 27e861cbd1e..57467d665d4 100644
--- a/sql/records.h
+++ b/sql/records.h
@@ -48,7 +48,7 @@ struct READ_RECORD
typedef int (*Setup_func)(struct st_join_table*);
TABLE *table; /* Head-form */
- handler *file;
+ //handler *file;
TABLE **forms; /* head and ref forms */
Unlock_row_func unlock_row;
Read_func read_record;
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index 3aa9a4f3488..8ff70dff825 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -455,14 +455,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;
}
/**
@@ -476,7 +476,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.
*/
@@ -484,7 +484,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/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index ed9a05f3d5f..e1c16b31b14 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -6554,3 +6554,7 @@ ER_QUERY_CACHE_IS_GLOBALY_DISABLED
eng "Query cache is globally disabled and you can't enable it only for this session"
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 96e9beedc5b..bd6e9aa69f9 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -650,7 +650,8 @@ terminate_slave_thread(THD *thd,
int err __attribute__((unused))= pthread_kill(thd->real_id, thr_client_alarm);
DBUG_ASSERT(err != EINVAL);
#endif
- thd->awake(THD::NOT_KILLED);
+ thd->awake(NOT_KILLED);
+
mysql_mutex_unlock(&thd->LOCK_thd_data);
/*
@@ -1189,6 +1190,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;
@@ -2266,7 +2269,7 @@ static int request_dump(THD *thd, 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;
if (RUN_HOOK(binlog_relay_io,
@@ -3363,11 +3366,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;
mysql_mutex_lock(&LOCK_thread_count);
threads.append(thd);
mysql_mutex_unlock(&LOCK_thread_count);
diff --git a/sql/slave.h b/sql/slave.h
index 6c1305e2ee0..7bee83af744 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -122,7 +122,7 @@ 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 char *opt_slave_skip_errors;
-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 af864989abd..56827d410b7 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -34,7 +34,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,
@@ -46,7 +46,8 @@ create_string(THD *thd, String *buf,
ulonglong sql_mode);
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,
ulonglong sql_mode, const char *params, const char *returns,
const char *body, st_sp_chistics &chistics,
const char *definer, longlong created, longlong modified,
@@ -475,7 +476,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");
@@ -528,7 +530,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;
@@ -797,7 +800,8 @@ Bad_db_error_handler::handle_condition(THD *thd,
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,
ulonglong sql_mode, const char *params, const char *returns,
const char *body, st_sp_chistics &chistics,
const char *definer, longlong created, longlong modified,
@@ -966,7 +970,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;
@@ -984,7 +988,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);
@@ -1236,7 +1241,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;
@@ -1317,7 +1322,8 @@ 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;
@@ -1326,7 +1332,8 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
MDL_key::FUNCTION : MDL_key::PROCEDURE;
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);
@@ -1590,7 +1597,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)
{
sp_head *sp;
@@ -1646,8 +1653,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 ?
@@ -1876,7 +1883,7 @@ bool sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
*/
void sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
- sp_name *rt, char rt_type)
+ sp_name *rt, enum stored_procedure_type rt_type)
{
MDL_key key((rt_type == TYPE_ENUM_FUNCTION) ? MDL_key::FUNCTION :
MDL_key::PROCEDURE,
@@ -2014,7 +2021,7 @@ int sp_cache_routine(THD *thd, Sroutine_hash_entry *rt,
char qname_buff[NAME_LEN*2+1+1];
sp_name name(&rt->mdl_request.key, qname_buff);
MDL_key::enum_mdl_namespace mdl_type= rt->mdl_request.key.mdl_namespace();
- int type= ((mdl_type == MDL_key::FUNCTION) ?
+ stored_procedure_type type= ((mdl_type == MDL_key::FUNCTION) ?
TYPE_ENUM_FUNCTION : TYPE_ENUM_PROCEDURE);
/*
@@ -2049,7 +2056,7 @@ int sp_cache_routine(THD *thd, Sroutine_hash_entry *rt,
@retval non-0 Error while loading routine from mysql,proc table.
*/
-int sp_cache_routine(THD *thd, int type, sp_name *name,
+int sp_cache_routine(THD *thd, enum stored_procedure_type type, sp_name *name,
bool lookup_only, sp_head **sp)
{
int ret= 0;
@@ -2060,7 +2067,6 @@ int sp_cache_routine(THD *thd, int type, sp_name *name,
DBUG_ASSERT(type == TYPE_ENUM_FUNCTION || type == TYPE_ENUM_PROCEDURE);
-
*sp= sp_cache_lookup(spc, name);
if (lookup_only)
@@ -2128,7 +2134,7 @@ int sp_cache_routine(THD *thd, int type, sp_name *name,
*/
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,
@@ -2221,7 +2227,7 @@ create_string(THD *thd, String *buf,
sp_head *
sp_load_for_information_schema(THD *thd, TABLE *proc_table, String *db,
- String *name, ulong sql_mode, int type,
+ String *name, ulong sql_mode, stored_procedure_type type,
const char *returns, const char *params,
bool *free_sp_head)
{
diff --git a/sql/sp.h b/sql/sp.h
index a06759663a7..3353132346b 100644
--- a/sql/sp.h
+++ b/sql/sp.h
@@ -36,6 +36,17 @@ struct TABLE_LIST;
typedef struct st_hash HASH;
template <typename T> class SQL_I_List;
+/*
+ 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,
+ TYPE_ENUM_PROXY=4
+};
/* Tells what SP_DEFAULT_ACCESS should be mapped to */
#define SP_DEFAULT_ACCESS_MAPPING SP_CONTAINS_SQL
@@ -97,7 +108,7 @@ sp_drop_db_routines(THD *thd, char *db);
bool lock_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);
int
@@ -106,23 +117,24 @@ sp_cache_routine(THD *thd, Sroutine_hash_entry *rt,
int
-sp_cache_routine(THD *thd, int type, sp_name *name,
+sp_cache_routine(THD *thd, stored_procedure_type type, sp_name *name,
bool lookup_only, sp_head **sp);
bool
sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any);
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);
/**
@@ -166,7 +178,7 @@ public:
Procedures for handling sets of stored routines used by statement or routine.
*/
void sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
- sp_name *rt, char rt_type);
+ sp_name *rt, stored_procedure_type rt_type);
bool sp_add_used_routine(Query_tables_list *prelocking_ctx, Query_arena *arena,
const MDL_key *key, TABLE_LIST *belong_to_view);
void sp_remove_not_own_routines(Query_tables_list *prelocking_ctx);
@@ -188,7 +200,7 @@ TABLE *open_proc_table_for_read(THD *thd, Open_tables_backup *backup);
sp_head *
sp_load_for_information_schema(THD *thd, TABLE *proc_table, String *db,
- String *name, ulong sql_mode, int type,
+ String *name, ulong sql_mode, stored_procedure_type type,
const char *returns, const char *params,
bool *free_sp_head);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index f8802acb75b..e82f1b92312 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1505,7 +1505,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
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
@@ -1940,7 +1940,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
thd->variables.option_bits= 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, FALSE, errcode);
if (mysql_bin_log.write(&qinfo) &&
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 5442d5d84b4..96e119f23bc 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -29,7 +29,7 @@
#include "my_global.h" /* NO_EMBEDDED_ACCESS_CHECKS */
#include "sql_class.h" // THD, set_var.h: THD
#include "set_var.h" // Item
-
+#include "sp.h"
#include <stddef.h>
/**
@@ -37,12 +37,6 @@
@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
-#define TYPE_ENUM_PROXY 4
Item_result
sp_map_result_type(enum enum_field_types type);
@@ -164,8 +158,7 @@ public:
HAS_SQLCOM_FLUSH= 2048
};
- /** 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/sp_rcontext.cc b/sql/sp_rcontext.cc
index 74bee6e856c..6fe4be989db 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -419,7 +419,7 @@ sp_rcontext::activate_handler(THD *thd,
/* Reset error state. */
thd->clear_error();
- thd->killed= THD::NOT_KILLED; // Some errors set thd->killed
+ thd->killed= NOT_KILLED; // Some errors set thd->killed
// (e.g. "bad data").
/* Return IP of the activated SQL handler. */
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 7a453bc6090..e4aa41b30ab 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -2420,7 +2420,7 @@ static int replace_user_table(THD *thd, TABLE *table, 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;
@@ -5169,7 +5169,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)
{
@@ -5177,7 +5178,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);
}
}
@@ -5359,13 +5360,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());
@@ -9097,11 +9098,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 ||
- global_system_variables.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),
@@ -9114,7 +9120,7 @@ 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 ||
- global_system_variables.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 */
@@ -9340,39 +9346,6 @@ static struct st_mysql_auth old_password_handler=
old_password_authenticate
};
-mysql_declare_plugin(mysql_password)
-{
- MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
- &native_password_handler, /* type descriptor */
- native_password_plugin_name.str, /* Name */
- "R.J.Silk, Sergei Golubchik", /* Author */
- "Native MySQL authentication", /* Description */
- PLUGIN_LICENSE_GPL, /* License */
- NULL, /* Init function */
- NULL, /* Deinit function */
- 0x0100, /* Version (1.0) */
- NULL, /* status variables */
- NULL, /* system variables */
- NULL, /* config options */
- 0, /* flags */
-},
-{
- MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
- &old_password_handler, /* type descriptor */
- old_password_plugin_name.str, /* Name */
- "R.J.Silk, Sergei Golubchik", /* Author */
- "Old MySQL-4.0 authentication", /* Description */
- PLUGIN_LICENSE_GPL, /* License */
- NULL, /* Init function */
- NULL, /* Deinit function */
- 0x0100, /* Version (1.0) */
- NULL, /* status variables */
- NULL, /* system variables */
- NULL, /* config options */
- 0, /* flags */
-}
-mysql_declare_plugin_end;
-
maria_declare_plugin(mysql_password)
{
MYSQL_AUTHENTICATION_PLUGIN, /* type constant */
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 892757d77fe..2411c9c33ea 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -65,7 +65,7 @@ bool
No_such_table_error_handler::handle_condition(THD *,
uint sql_errno,
const char*,
- MYSQL_ERROR::enum_warning_level,
+ MYSQL_ERROR::enum_warning_level level,
const char*,
MYSQL_ERROR ** cond_hdl)
{
@@ -76,7 +76,8 @@ No_such_table_error_handler::handle_condition(THD *,
return TRUE;
}
- m_unhandled_errors++;
+ if (level == MYSQL_ERROR::WARN_LEVEL_ERROR)
+ m_unhandled_errors++;
return FALSE;
}
@@ -982,7 +983,7 @@ static void kill_delayed_threads_for_table(TABLE_SHARE *share)
if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
! in_use->killed)
{
- in_use->killed= THD::KILL_CONNECTION;
+ in_use->killed= KILL_SYSTEM_THREAD;
mysql_mutex_lock(&in_use->mysys_var->mutex);
if (in_use->mysys_var->current_cond)
{
@@ -6718,11 +6719,25 @@ 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);
@@ -8544,7 +8559,6 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
{
SELECT_LEX *select_lex= thd->lex->current_select;
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
@@ -8581,7 +8595,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";
@@ -8595,11 +8608,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,
@@ -8615,8 +8628,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))
@@ -8640,7 +8653,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())
{
@@ -9093,7 +9105,7 @@ bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use,
if ((in_use->system_thread & SYSTEM_THREAD_DELAYED_INSERT) &&
!in_use->killed)
{
- in_use->killed= THD::KILL_CONNECTION;
+ in_use->killed= KILL_SYSTEM_THREAD;
mysql_mutex_lock(&in_use->mysys_var->mutex);
if (in_use->mysys_var->current_cond)
mysql_cond_broadcast(in_use->mysys_var->current_cond);
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 452cc0b02b8..e3c9ecc1a36 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -498,11 +498,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 "/"
@@ -4453,7 +4454,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 e1ff29e0b24..259e5f2fd4f 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -282,7 +282,7 @@ bool Foreign_key::validate(List<Create_field> &table_fields)
*/
void thd_set_killed(THD *thd)
{
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_CONNECTION;
}
/**
@@ -726,7 +726,7 @@ THD::THD()
:Statement(&main_lex, &main_mem_root, STMT_CONVENTIONAL_EXECUTION,
/* statement id */ 0),
rli_fake(0),
- in_sub_stmt(0),
+ in_sub_stmt(0), log_all_errors(0),
binlog_unsafe_warning_flags(0),
binlog_table_maps(0),
table_map_for_update(0),
@@ -1058,7 +1058,7 @@ MYSQL_ERROR* THD::raise_condition(uint sql_errno,
push_warning and strict SQL_MODE case.
*/
level= MYSQL_ERROR::WARN_LEVEL_ERROR;
- killed= THD::KILL_BAD_DATA;
+ killed= KILL_BAD_DATA;
}
switch (level)
@@ -1521,17 +1521,27 @@ void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
@note Do always call this while holding LOCK_thd_data.
*/
-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: %p current_thd: %p", this, current_thd));
THD_CHECK_SENTRY(this);
mysql_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");
+ }
+
/* Set the 'killed' flag of 'this', which is the target THD object. */
killed= state_to_set;
- if (state_to_set != THD::KILL_QUERY)
+ if (state_to_set >= KILL_CONNECTION || state_to_set == NOT_KILLED)
{
#ifdef SIGNAL_WITH_VIO_CLOSE
if (this != current_thd)
@@ -1652,7 +1662,7 @@ void THD::disconnect()
mysql_mutex_lock(&LOCK_thd_data);
- killed= THD::KILL_CONNECTION;
+ killed= KILL_CONNECTION;
#ifdef SIGNAL_WITH_VIO_CLOSE
/*
@@ -1673,6 +1683,37 @@ void THD::disconnect()
/*
+ 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
*/
@@ -2912,26 +2953,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()
@@ -2939,13 +2986,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()
@@ -2958,13 +3008,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)
@@ -3697,11 +3750,15 @@ void THD::restore_backup_open_tables_state(Open_tables_backup *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;
}
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 284a9d9e42e..d842aa39045 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -398,6 +398,36 @@ typedef enum enum_diag_condition_item_name
*/
extern const LEX_STRING Diag_condition_item_names[];
+/* 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;
@@ -483,7 +513,7 @@ typedef struct system_variables
ulong log_slow_rate_limit;
ulong binlog_format; ///< binlog format for this thd (see enum_binlog_format)
ulong progress_report_time;
- my_bool binlog_annotate_rows_events;
+ my_bool binlog_annotate_row_events;
my_bool binlog_direct_non_trans_update;
my_bool sql_log_bin;
ulong completion_type;
@@ -1664,19 +1694,12 @@ public:
uint in_sub_stmt;
/* 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;
/*
@@ -2128,14 +2151,6 @@ public:
condition. For details see the implementation of awake(),
especially the "broadcast" part.
*/
- 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 */
@@ -2334,7 +2349,7 @@ public:
}
void close_active_vio();
#endif
- void awake(THD::killed_state state_to_set);
+ void awake(killed_state state_to_set);
/** Disconnect the associated communication endpoint. */
void disconnect();
@@ -2646,18 +2661,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()
@@ -3587,9 +3597,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);
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 5dde1818c27..6ab6f3237d7 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -126,9 +126,12 @@ int check_for_max_user_connections(THD *thd, USER_CONN *uc)
DBUG_ENTER("check_for_max_user_connections");
mysql_mutex_lock(&LOCK_user_conn);
+
+ /* Root is not affected by the value of max_user_connections */
if (global_system_variables.max_user_connections &&
!uc->user_resources.user_conn &&
- global_system_variables.max_user_connections < (uint) uc->connections)
+ global_system_variables.max_user_connections < (uint) uc->connections &&
+ !(thd->security_ctx->master_access & SUPER_ACL))
{
my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user);
goto end;
@@ -224,7 +227,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;
@@ -253,7 +256,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;
@@ -265,7 +268,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;
@@ -1112,7 +1115,7 @@ void prepare_new_connection_state(THD* thd)
execute_init_command(thd, &opt_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",
@@ -1174,7 +1177,7 @@ bool thd_is_connection_alive(THD *thd)
NET *net= &thd->net;
if (!net->error &&
net->vio != 0 &&
- !(thd->killed == THD::KILL_CONNECTION))
+ thd->killed < KILL_CONNECTION)
return TRUE;
return FALSE;
}
@@ -1184,6 +1187,8 @@ void do_handle_one_connection(THD *thd_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 (MYSQL_CALLBACK_ELSE(thread_scheduler, init_new_connection_thread, (), 0))
{
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 8013d2bd6e2..2301dae5fdf 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -32,6 +32,7 @@
#include "sql_base.h" // lock_table_names, tdc_remove_table
#include "sql_handler.h" // mysql_ha_rm_tables
#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 a70f00a439c..efce55cc18a 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -63,7 +63,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
order_list->first : NULL);
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;
THD::enum_binlog_query_type query_type= THD::ROW_QUERY_TYPE;
DBUG_ENTER("mysql_delete");
@@ -379,7 +379,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()))
{
@@ -424,8 +424,8 @@ 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
storage engine does not inject the rows itself, we replicate
@@ -870,7 +870,7 @@ void multi_delete::abort_result_set()
*/
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(),
@@ -1019,7 +1019,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 */
@@ -1027,7 +1027,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");
@@ -1050,7 +1050,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, FALSE, errcode) &&
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index f8327ccee04..70c66d6cf29 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1026,7 +1026,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:
@@ -1040,7 +1040,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 (was_insert_delayed && table_list->lock_type == TL_WRITE)
{
/* Binlog INSERT DELAYED as INSERT without DELAYED. */
@@ -2136,7 +2136,7 @@ bool delayed_get_table(THD *thd, MDL_request *grl_protection_request,
/*
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,
@@ -2522,7 +2522,7 @@ void kill_delayed_threads(void)
Delayed_insert *di;
while ((di= it++))
{
- di->thd.killed= THD::KILL_CONNECTION;
+ di->thd.killed= KILL_CONNECTION;
mysql_mutex_lock(&di->thd.LOCK_thd_data);
if (di->thd.mysys_var)
{
@@ -2660,7 +2660,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_CONNECTION : NOT_KILLED;
mysql_mutex_unlock(&LOCK_thread_count);
mysql_thread_set_psi_id(thd->thread_id);
@@ -2782,7 +2782,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
#endif
#endif
if (error == ETIMEDOUT || error == ETIME)
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_CONNECTION;
}
/* We can't lock di->mutex and mysys_var->mutex at the same time */
mysql_mutex_unlock(&di->mutex);
@@ -2809,7 +2809,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
if (! (thd->lock= mysql_lock_tables(thd, &di->table, 1, 0)))
{
/* Fatal error */
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_CONNECTION;
}
mysql_cond_broadcast(&di->cond_client);
}
@@ -2818,7 +2818,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
if (di->handle_inserts())
{
/* Some fatal error */
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_CONNECTION;
}
}
di->status=0;
@@ -2851,7 +2851,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
}
di->table=0;
- thd->killed= THD::KILL_CONNECTION; // If error
+ thd->killed= KILL_CONNECTION; // If error
mysql_mutex_unlock(&di->mutex);
close_thread_tables(thd); // Free the table
@@ -2937,7 +2937,7 @@ bool Delayed_insert::handle_inserts(void)
max_rows= delayed_insert_limit;
if (thd.killed || table->s->has_old_version())
{
- thd.killed= THD::KILL_CONNECTION;
+ thd.killed= KILL_SYSTEM_THREAD;
max_rows= ULONG_MAX; // Do as much as possible
}
@@ -3550,7 +3550,7 @@ bool select_insert::send_eof()
bool const trans_table= table->file->has_transactions();
ulonglong id, row_count;
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()));
@@ -3591,7 +3591,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 (thd->binlog_query(THD::ROW_QUERY_TYPE,
thd->query(), thd->query_length(),
trans_table, FALSE, FALSE, errcode))
@@ -3670,7 +3670,7 @@ void select_insert::abort_result_set() {
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 */
(void) thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(),
thd->query_length(),
@@ -4061,7 +4061,7 @@ select_create::binlog_show_create_table(TABLE **tables, uint count)
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);
result= thd->binlog_query(THD::STMT_QUERY_TYPE,
query.ptr(), query.length(),
/* is_trans */ TRUE,
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
index b0fdb7a1c42..76d01b076f0 100644
--- a/sql/sql_join_cache.cc
+++ b/sql/sql_join_cache.cc
@@ -226,8 +226,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++;
@@ -621,7 +619,12 @@ void JOIN_CACHE::create_remaining_fields()
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++;
}
@@ -1298,6 +1301,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;
}
@@ -1307,6 +1311,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);
}
@@ -1323,6 +1328,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;
}
@@ -1349,6 +1355,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*);
@@ -1358,6 +1365,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;
}
@@ -1368,12 +1376,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;
@@ -1388,6 +1398,7 @@ 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;
@@ -1403,11 +1414,22 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
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;
}
}
@@ -1426,6 +1448,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;
}
@@ -1799,6 +1822,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;
@@ -2022,6 +2052,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;
@@ -2103,7 +2134,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);
}
@@ -2165,10 +2197,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.
@@ -2242,7 +2275,7 @@ finish:
rc= error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
finish2:
join_tab_scan->close();
- return rc;
+ DBUG_RETURN(rc);
}
@@ -2324,6 +2357,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
@@ -2341,16 +2375,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);
}
@@ -2375,16 +2411,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,
@@ -2397,7 +2437,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
@@ -2411,13 +2451,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);
}
@@ -2452,10 +2491,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));
@@ -2485,7 +2525,7 @@ enum_nested_loop_state JOIN_CACHE::join_null_complements(bool skip_last)
}
finish:
- return rc;
+ DBUG_RETURN(rc);
}
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index f3dfd95815e..a9d542756fb 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -25,8 +25,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"
static int lex_one_token(void *arg, void *yythd);
@@ -503,6 +503,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;
/*
@@ -1499,39 +1500,39 @@ int lex_one_token(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)
{
@@ -3455,18 +3456,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);
@@ -3474,7 +3476,7 @@ void st_select_lex::remove_table_from_list(TABLE_LIST *table)
{
if (tl == table)
{
- ti.remove();
+ ti.replace(tbl_list);
break;
}
}
@@ -3579,8 +3581,6 @@ bool SELECT_LEX::merge_subquery(THD *thd, TABLE_LIST *derived,
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 ||
@@ -3596,18 +3596,14 @@ bool SELECT_LEX::merge_subquery(THD *thd, TABLE_LIST *derived,
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;
}
@@ -3648,10 +3644,33 @@ void SELECT_LEX::update_used_tables()
{
TABLE_LIST *tl;
List_iterator<TABLE_LIST> ti(leaf_tables);
+
while ((tl= ti++))
{
- TABLE_LIST *embedding;
- embedding= tl;
+ 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;
@@ -3680,6 +3699,7 @@ void SELECT_LEX::update_used_tables()
embedding= tl->embedding;
}
}
+
if (join->conds)
{
join->conds->update_used_tables();
@@ -3862,6 +3882,47 @@ bool st_select_lex::save_prep_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 bbc91c2f987..c776dfc5a8c 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -802,6 +802,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 '*' */
@@ -990,7 +997,7 @@ public:
bool handle_derived(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(THD *thd, TABLE_LIST *derived, st_select_lex *subq_lex,
@@ -1009,6 +1016,7 @@ public:
bool save_leaf_tables(THD *thd);
bool save_prep_leaf_tables(THD *thd);
+ bool is_merged_child_of(st_select_lex *ancestor);
/*
For MODE_ONLY_FULL_GROUP_BY we need to maintain two flags:
@@ -2377,6 +2385,9 @@ struct LEX: public Query_tables_list
USER_RESOURCES mqh;
LEX_RESET_SLAVE reset_slave_info;
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 5441fec5f63..894edc4516d 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -314,6 +314,26 @@ public:
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:
@@ -492,6 +512,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 6f84f68eeaa..bc926118723 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -179,7 +179,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= THD::NOT_KILLED;
+ killed_state killed_status;
bool is_concurrent;
#endif
char *db = table_list->db; // This is never null
@@ -529,11 +529,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
/*
@@ -577,8 +577,8 @@ 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 */
if (thd->transaction.stmt.modified_non_trans_table)
@@ -630,7 +630,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,
is_concurrent,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 54b1e854ac1..714542ab0af 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -118,7 +118,8 @@
"FUNCTION" : "PROCEDURE")
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
-static void sql_kill(THD *thd, ulong id, bool only_kill_query);
+static void sql_kill(THD *thd, ulong id, killed_state state);
+static void sql_kill_user(THD *thd, LEX_USER *user, killed_state state);
static bool execute_show_status(THD *, TABLE_LIST *);
static bool execute_rename_table(THD *, TABLE_LIST *, TABLE_LIST *);
@@ -1362,7 +1363,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:
@@ -1443,6 +1444,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
MYSQL_COMMAND_DONE(res);
}
+
+ /* Check that some variables are reset properly */
+ DBUG_ASSERT(thd->abort_on_warning == 0);
DBUG_RETURN(error);
}
@@ -3653,8 +3657,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 "
@@ -3662,13 +3664,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
@@ -3740,7 +3749,17 @@ end_with_restore_list:
}
/* Disconnect the current client connection. */
if (tx_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");
+ }
+ }
my_ok(thd);
break;
}
@@ -3770,7 +3789,7 @@ end_with_restore_list:
}
/* Disconnect the current client connection. */
if (tx_release)
- thd->killed= THD::KILL_CONNECTION;
+ thd->killed= KILL_CONNECTION;
my_ok(thd);
break;
}
@@ -4035,7 +4054,8 @@ create_sp_error:
case SQLCOM_ALTER_FUNCTION:
{
int sp_result;
- int type= (lex->sql_command == SQLCOM_ALTER_PROCEDURE ?
+ enum stored_procedure_type type;
+ type= (lex->sql_command == SQLCOM_ALTER_PROCEDURE ?
TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
if (check_routine_access(thd, ALTER_PROC_ACL, lex->spname->m_db.str,
@@ -4112,7 +4132,8 @@ create_sp_error:
#endif
int sp_result;
- int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
+ enum stored_procedure_type type;
+ type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
char *db= lex->spname->m_db.str;
char *name= lex->spname->m_name.str;
@@ -4199,7 +4220,7 @@ create_sp_error:
{
#ifndef DBUG_OFF
sp_head *sp;
- int type= (lex->sql_command == SQLCOM_SHOW_PROC_CODE ?
+ stored_procedure_type type= (lex->sql_command == SQLCOM_SHOW_PROC_CODE ?
TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
if (sp_cache_routine(thd, type, lex->spname, FALSE, &sp))
@@ -4445,9 +4466,9 @@ finish:
if (! thd->stmt_da->is_set())
thd->send_kill_message();
}
- if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
+ if (thd->killed < KILL_CONNECTION)
{
- thd->killed= THD::NOT_KILLED;
+ thd->killed= NOT_KILLED;
thd->mysys_var->abort= 0;
}
if (thd->is_error() || (thd->variables.option_bits & OPTION_MASTER_SQL_ERROR))
@@ -4518,7 +4539,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, TRUE, 0)))
{
if (lex->describe)
@@ -5418,7 +5438,6 @@ void THD::reset_for_next_command(bool calculate_userstat)
thd->query_plan_flags= QPLAN_INIT;
thd->query_plan_fsort_passes= 0;
- thd->thd_marker.emb_on_expr_nest= NULL;
thd->reset_current_stmt_binlog_format_row();
thd->binlog_unsafe_warning_flags= 0;
@@ -5485,6 +5504,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;
@@ -6508,12 +6528,13 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
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));
+
mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
I_List_iterator<THD> it(threads);
while ((tmp=it++))
@@ -6544,12 +6565,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
@@ -6561,6 +6586,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));
+
+ mysql_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))
+ {
+ mysql_mutex_unlock(&LOCK_thread_count);
+ DBUG_RETURN(ER_KILL_DENIED_ERROR);
+ }
+ if (!threads_to_kill.push_back(tmp, tmp->mem_root))
+ mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
+ }
+ }
+ mysql_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);
+ mysql_mutex_unlock(&ptr->LOCK_thd_data);
+ (*rows)++;
+ }
+ }
+ DBUG_RETURN(0);
+}
+
+
/*
kills a thread and sends response
@@ -6572,10 +6667,10 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
*/
static
-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)))
{
if (! thd->killed)
my_ok(thd);
@@ -6585,6 +6680,24 @@ void sql_kill(THD *thd, ulong id, bool only_kill_query)
}
+static
+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_parse.h b/sql/sql_parse.h
index 2c31f71af53..4510ebe94e2 100644
--- a/sql/sql_parse.h
+++ b/sql/sql_parse.h
@@ -50,8 +50,6 @@ bool parse_sql(THD *thd,
Parser_state *parser_state,
Object_creation_ctx *creation_ctx);
-uint kill_one_thread(THD *thd, ulong id, bool only_kill_query);
-
void free_items(Item *item);
void cleanup_items(Item *item);
diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc
index 06ead26414c..3024d9d2e46 100644
--- a/sql/sql_plugin.cc
+++ b/sql/sql_plugin.cc
@@ -3449,6 +3449,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)
@@ -3610,6 +3623,8 @@ 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_option= PLUGIN_OFF;
+ if (!my_strcasecmp(&my_charset_latin1, tmp->name.str, "feedback"))
+ plugin_load_option= PLUGIN_OFF;
for (opt= tmp->plugin->system_vars; opt && *opt; opt++)
count+= 2; /* --{plugin}-{optname} and --plugin-{plugin}-{optname} */
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index ef6dd519d5d..f35d336fd65 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1504,7 +1504,6 @@ static int mysql_test_select(Prepared_statement *stmt,
goto error;
thd->lex->used_tables= 0; // Updated by setup_fields
- thd->thd_marker.emb_on_expr_nest= 0;
/*
JOIN::prepare calls
diff --git a/sql/sql_priv.h b/sql/sql_priv.h
index 33c5881d4f4..30c72d603f4 100644
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@ -207,7 +207,11 @@ enabled by default, add OPTIMIZER_SWITCH_MATERIALIZATION
OPTIMIZER_SWITCH_PARTIAL_MATCH_TABLE_SCAN|\
OPTIMIZER_SWITCH_JOIN_CACHE_INCREMENTAL | \
OPTIMIZER_SWITCH_JOIN_CACHE_HASHED | \
- OPTIMIZER_SWITCH_JOIN_CACHE_BKA)
+ OPTIMIZER_SWITCH_JOIN_CACHE_BKA | \
+ 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
use strictly more than 64 bits by adding one more define above, you should
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 91c78944205..16977d89cd6 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1505,9 +1505,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()
@@ -1539,7 +1539,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);
mysql_mutex_unlock(&tmp->LOCK_thd_data);
}
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 5499806db81..4ce278c98ef 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -190,14 +190,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);
@@ -714,6 +714,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->non_agg_field_used() &&
select_lex->agg_func_used())
{
@@ -839,7 +843,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;
@@ -928,9 +932,6 @@ 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();
@@ -990,6 +991,8 @@ 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;
@@ -1118,7 +1121,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,
@@ -2424,7 +2427,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)
@@ -2451,6 +2453,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)))
@@ -2581,7 +2584,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)
{
@@ -2611,7 +2614,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,
@@ -2619,7 +2624,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",
@@ -3004,6 +3009,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;
@@ -3191,7 +3197,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,
@@ -3329,12 +3335,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);
@@ -3356,6 +3367,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
if (table->key_info[key].flags & HA_NOSAME)
{
if (const_ref == eq_part &&
+ !has_expensive_keyparts &&
!((outer_join & table->map) &&
(*s->on_expr_ref)->is_expensive()))
{ // Found everything for ref.
@@ -3836,7 +3848,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)))
{
@@ -5266,7 +5280,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;
}
}
@@ -5430,13 +5444,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 */
@@ -6136,7 +6151,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)
@@ -6146,14 +6161,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;
/*
@@ -6163,6 +6178,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;
@@ -6175,19 +6191,17 @@ void JOIN::get_partial_cost_and_fanout(uint end_tab_idx,
}
for (tab= first_depth_first_tab(this), i= const_tables;
- (i <= end_tab_idx && 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;
}
@@ -6201,8 +6215,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;
@@ -6216,6 +6240,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;
@@ -6648,6 +6675,16 @@ 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
@@ -6661,13 +6698,9 @@ void JOIN_TAB::calc_used_field_length(bool max_fl)
}
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;
@@ -6704,7 +6737,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=
@@ -7176,6 +7209,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;
@@ -7309,7 +7343,8 @@ static bool are_tables_local(JOIN_TAB *jtab, table_map used_tables)
except the const tables.
*/
table_map local_tables= jtab->emb_sj_nest->nested_join->used_tables |
- jtab->join->const_table_map;
+ jtab->join->const_table_map |
+ OUTER_REF_TABLE_BIT;
return !test(used_tables & ~local_tables);
}
@@ -7426,7 +7461,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);
@@ -7990,7 +8026,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,
@@ -8009,7 +8045,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);
@@ -8037,7 +8073,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;
@@ -8181,7 +8217,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 */
@@ -8354,7 +8390,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
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);
@@ -8400,10 +8436,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
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);
@@ -8484,17 +8520,17 @@ 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= keyuse->keypart;
uint parts= 0;
uint i= 0;
- for ( ; i < count && keyno < keys; )
+ for ( ; i < count && key_count < keys; )
{
do
{
- keyuse->key= keyno;
+ keyuse->key= table->s->keys;
keyuse->keypart_map= (key_part_map) (1 << parts);
keyuse++;
i++;
@@ -8508,14 +8544,14 @@ bool generate_derived_keys_for_table(KEYUSE *keyuse, uint count, uint keys)
}
else
{
- if (table->add_tmp_key(keyno, parts,
+ 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;
prev_part= keyuse->keypart;
}
@@ -8542,12 +8578,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;
@@ -8560,11 +8607,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;
}
}
@@ -8595,12 +8644,13 @@ 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);
- if (table->s->keys)
+ 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);
}
}
@@ -8729,7 +8779,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();
}
@@ -9063,8 +9113,17 @@ 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() &&
+ if (tab->is_inner_table_of_semijoin() &&
!join->allowed_semijoin_with_cache)
goto no_join_cache;
if (tab->is_inner_table_of_outer_join() &&
@@ -9144,6 +9203,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;
@@ -9208,7 +9270,10 @@ uint check_join_cache_usage(JOIN_TAB *tab,
no_join_cache:
if (tab->type != JT_ALL && tab->is_ref_for_hash_join())
+ {
tab->type= JT_ALL;
+ tab->ref.key_parts= 0;
+ }
revise_cache_usage(tab);
return 0;
}
@@ -9389,7 +9454,6 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
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
@@ -9435,9 +9499,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 */
@@ -9447,7 +9511,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:
@@ -9462,7 +9526,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:
@@ -9671,7 +9735,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();
table= NULL;
DBUG_VOID_RETURN;
@@ -9744,6 +9807,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;
}
@@ -9819,6 +9884,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.
@@ -13954,6 +14035,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]);
@@ -14077,6 +14159,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 */
@@ -14094,6 +14177,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.
@@ -14371,6 +14455,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;
@@ -14389,9 +14480,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;
}
@@ -14566,7 +14657,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;
}
@@ -15097,10 +15189,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);
@@ -15929,7 +16023,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],
@@ -16114,7 +16208,7 @@ join_init_quick_read_record(JOIN_TAB *tab)
int read_first_record_seq(JOIN_TAB *tab)
{
- 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);
}
@@ -16181,7 +16275,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)
@@ -16202,7 +16295,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;
@@ -16220,7 +16313,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)
@@ -16238,7 +16330,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;
}
@@ -16267,7 +16359,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;
}
@@ -16849,13 +16941,8 @@ 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) ||
@@ -16937,7 +17024,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)
{
@@ -16951,7 +17038,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)
@@ -17917,8 +18004,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]
*/
@@ -17971,14 +18060,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:
@@ -17990,6 +18076,7 @@ use_filesort:
}
if (orig_cond_saved)
tab->set_cond(orig_cond);
+
DBUG_RETURN(0);
}
@@ -19887,7 +19974,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;
@@ -19896,15 +19982,20 @@ 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)
{
- Item *new_cond= and_conds(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->select->pre_idx_push_select_cond= new_cond;
+ join_tab->pre_idx_push_select_cond=
+ join_tab->select->pre_idx_push_select_cond= new_cond;
}
join_tab->set_select_cond(cond, __LINE__);
}
@@ -20699,9 +20790,13 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
length= (longlong10_to_str(key_len, keylen_str_buf, 10) -
keylen_str_buf);
tmp3.append(keylen_str_buf, length, cs);
+/*<<<<<<< TREE
}
if ((is_hj || tab->type==JT_RANGE || tab->type == JT_INDEX_MERGE) &&
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))
{
@@ -21577,6 +21672,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();
+ }
}
@@ -21604,6 +21721,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++);
+ }
}
@@ -21613,7 +21738,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
@@ -21657,6 +21783,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))
@@ -21690,6 +21818,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 d87504f719c..4b5e2903c1d 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -143,6 +143,7 @@ typedef struct st_table_ref
bool tmp_table_index_lookup_init(THD *thd, KEY *tmp_key, Item_iterator &it,
bool value, uint skip= 0);
+ bool is_access_triggered();
} TABLE_REF;
@@ -284,7 +285,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;
@@ -343,6 +343,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;
@@ -385,19 +388,14 @@ typedef struct st_join_table {
return (is_using_loose_index_scan() &&
((QUICK_GROUP_MIN_MAX_SELECT *)select->quick)->is_agg_distinct());
}
- 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;
}
+ bool is_inner_table_of_semijoin()
+ {
+ return emb_sj_nest != NULL;
+ }
bool is_inner_table_of_outer_join()
{
return first_inner != NULL;
@@ -674,6 +672,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()
{
@@ -699,6 +698,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();
@@ -1152,7 +1152,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 a65a2e40577..b7c3a29cace 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1218,7 +1218,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 |
@@ -1908,7 +1908,8 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
mysql_mutex_lock(&tmp->LOCK_thd_data);
if ((mysys_var= tmp->mysys_var))
mysql_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);
thd_info->state_info= thread_state_info(tmp);
if (mysys_var)
mysql_mutex_unlock(&mysys_var->mutex);
@@ -2037,7 +2038,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
if ((mysys_var= tmp->mysys_var))
mysql_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,
@@ -2385,7 +2387,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) *(uint*) value, buff, 10);
break;
case SHOW_HAVE:
{
@@ -5058,7 +5060,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
String sp_name(sp_name_buff, sizeof(sp_name_buff), cs);
String definer(definer_buff, sizeof(definer_buff), cs);
sp_head *sp;
- uint routine_type;
+ stored_procedure_type routine_type;
bool free_sp_head;
DBUG_ENTER("store_schema_params");
@@ -5069,7 +5071,7 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_DB], &sp_db);
get_field(thd->mem_root, proc_table->field[MYSQL_PROC_FIELD_NAME], &sp_name);
get_field(thd->mem_root,proc_table->field[MYSQL_PROC_FIELD_DEFINER],&definer);
- routine_type= (uint) proc_table->field[MYSQL_PROC_MYSQL_TYPE]->val_int();
+ routine_type= (stored_procedure_type) proc_table->field[MYSQL_PROC_MYSQL_TYPE]->val_int();
if (!full_access)
full_access= !strcmp(sp_user, definer.ptr());
@@ -7471,11 +7473,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;
}
}
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 3f3d140dad8..9f24ed45842 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -661,6 +661,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 9ab01736f66..99cac9f40e7 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -274,7 +274,7 @@ int mysql_update(THD *thd,
SELECT_LEX *select_lex= &thd->lex->select_lex;
ulonglong id;
List<Item> all_fields;
- THD::killed_state killed_status= THD::NOT_KILLED;
+ killed_state killed_status= NOT_KILLED;
DBUG_ENTER("mysql_update");
if (open_tables(thd, &table_list, &table_count, 0))
@@ -843,9 +843,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 &&
@@ -908,7 +908,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(),
@@ -2052,7 +2052,7 @@ void multi_update::abort_result_set()
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(),
@@ -2265,7 +2265,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");
@@ -2280,7 +2280,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
@@ -2310,7 +2310,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, FALSE, errcode))
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index c09b39c2450..94dffad822e 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -30,8 +30,8 @@
#include "sql_acl.h" // *_ACL, check_grant
#include "sql_select.h"
#include "parse_file.h"
-#include "sp.h"
#include "sp_head.h"
+#include "sp.h"
#include "sp_cache.h"
#include "datadict.h" // dd_frm_type()
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d82936c87a9..64aa42fa337 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -788,10 +788,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.
@@ -1015,6 +1015,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
@@ -1292,6 +1293,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
@@ -1476,7 +1478,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 <m_yes_no_unk>
opt_chain opt_release
@@ -1511,7 +1513,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
signal_allowed_expr
%type <item_num>
@@ -10415,6 +10417,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); }
@@ -11854,19 +11862,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 */
@@ -12997,6 +13027,7 @@ keyword_sp:
| GRANTS {}
| GLOBAL_SYM {}
| HASH_SYM {}
+ | HARD_SYM {}
| HOSTS_SYM {}
| HOUR_SYM {}
| IDENTIFIED_SYM {}
@@ -13134,6 +13165,7 @@ keyword_sp:
| SHUTDOWN {}
| SLOW {}
| SNAPSHOT_SYM {}
+ | SOFT_SYM {}
| SOUNDS_SYM {}
| SOURCE_SYM {}
| SQL_CACHE_SYM {}
@@ -14242,7 +14274,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 347cb97e152..8aeb41f7a1e 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -183,8 +183,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.
@@ -217,7 +220,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/sys_vars.cc b/sql/sys_vars.cc
index 37dfb95bc6f..6314a296b33 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -929,7 +929,8 @@ static Sys_var_mybool Sys_log_queries_not_using_indexes(
static Sys_var_ulong Sys_log_warnings(
"log_warnings",
- "Log some not critical warnings to the general log file",
+ "Log some not critical warnings to the general log file."
+ "Value can be between 0 and 11. Higher values mean more verbosity",
SESSION_VAR(log_warnings),
CMD_LINE(OPT_ARG, 'W'),
VALID_RANGE(0, ULONG_MAX), DEFAULT(1), BLOCK_SIZE(1));
@@ -1234,14 +1235,28 @@ static Sys_var_ulong Sys_max_sp_recursion_depth(
SESSION_VAR(max_sp_recursion_depth), CMD_LINE(OPT_ARG),
VALID_RANGE(0, 255), DEFAULT(0), BLOCK_SIZE(1));
+
+static bool if_checking_enabled(sys_var *self, THD *thd, set_var *var)
+{
+ if (session_readonly(self, thd, var))
+ return true;
+
+ if (!max_user_connections_checking)
+ {
+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--max-user-connections=0");
+ return true;
+ }
+
+ return false;
+}
// non-standard session_value_ptr() here
static Sys_var_max_user_conn Sys_max_user_connections(
"max_user_connections",
"The maximum number of active connections for a single user "
"(0 = no limit)",
SESSION_VAR(max_user_connections), CMD_LINE(REQUIRED_ARG),
- VALID_RANGE(0, UINT_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD,
- NOT_IN_BINLOG, ON_CHECK(session_readonly));
+ VALID_RANGE(0, INT_MAX), DEFAULT(0), BLOCK_SIZE(1), NO_MUTEX_GUARD,
+ NOT_IN_BINLOG, ON_CHECK(if_checking_enabled));
static Sys_var_ulong Sys_max_tmp_tables(
"max_tmp_tables",
@@ -3341,18 +3356,18 @@ static Sys_var_mybool Sys_userstat(
CMD_LINE(OPT_ARG), DEFAULT(FALSE));
static Sys_var_mybool Sys_binlog_annotate_row_events(
- "binlog_annotate_rows_events",
+ "binlog_annotate_row_events",
"Tells the master to annotate RBR events with the statement that "
"caused these events",
- SESSION_VAR(binlog_annotate_rows_events), CMD_LINE(OPT_ARG),
+ SESSION_VAR(binlog_annotate_row_events), CMD_LINE(OPT_ARG),
DEFAULT(FALSE));
#ifdef HAVE_REPLICATION
-static Sys_var_mybool Sys_replicate_annotate_rows_events(
- "replicate_annotate_rows_events",
+static Sys_var_mybool Sys_replicate_annotate_row_events(
+ "replicate_annotate_row_events",
"Tells the slave to write annotate rows events recieved from the master "
"to its own binary log. Ignored if log_slave_updates is not set",
- READ_ONLY GLOBAL_VAR(opt_replicate_annotate_rows_events),
+ READ_ONLY GLOBAL_VAR(opt_replicate_annotate_row_events),
CMD_LINE(OPT_ARG), DEFAULT(0));
#endif
@@ -3417,3 +3432,12 @@ static Sys_var_session_special Sys_in_transaction(
VALID_RANGE(0, 1), BLOCK_SIZE(1), NO_MUTEX_GUARD,
NOT_IN_BINLOG, ON_CHECK(0), ON_UPDATE(0), ON_READ(in_transaction));
+#ifndef DBUG_OFF
+static Sys_var_ulong Sys_debug_binlog_fsync_sleep(
+ "debug_binlog_fsync_sleep",
+ "Extra sleep (in microseconds) to add to binlog fsync(), for debugging",
+ GLOBAL_VAR(opt_binlog_dbug_fsync_sleep),
+ CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
+#endif
+
diff --git a/sql/sys_vars.h b/sql/sys_vars.h
index f152c944a3e..653c0d94dbe 100644
--- a/sql/sys_vars.h
+++ b/sql/sys_vars.h
@@ -70,6 +70,21 @@
#define GET_HA_ROWS GET_ULONG
#endif
+/*
+ special assert for sysvars. Tells the name of the variable,
+ and fails even in non-debug builds.
+
+ It is supposed to be used *only* in Sys_var* constructors,
+ and has name_arg hard-coded to prevent incorrect usage.
+*/
+#define SYSVAR_ASSERT(X) \
+ while(!(X)) \
+ { \
+ fprintf(stderr, "Sysvar '%s' failed '%s'\n", name_arg, #X); \
+ DBUG_ABORT(); \
+ exit(255); \
+ }
+
enum charset_enum {IN_SYSTEM_CHARSET, IN_FS_CHARSET};
static const char *bool_values[3]= {"OFF", "ON", 0};
@@ -123,12 +138,12 @@ public:
if (max_var_ptr())
*max_var_ptr()= max_val;
global_var(T)= def_val;
- DBUG_ASSERT(size == sizeof(T));
- DBUG_ASSERT(min_val < max_val);
- DBUG_ASSERT(min_val <= def_val);
- DBUG_ASSERT(max_val >= def_val);
- DBUG_ASSERT(block_size > 0);
- DBUG_ASSERT(def_val % block_size == 0);
+ SYSVAR_ASSERT(size == sizeof(T));
+ SYSVAR_ASSERT(min_val < max_val);
+ SYSVAR_ASSERT(min_val <= def_val);
+ SYSVAR_ASSERT(max_val >= def_val);
+ SYSVAR_ASSERT(block_size > 0);
+ SYSVAR_ASSERT(def_val % block_size == 0);
}
bool do_check(THD *thd, set_var *var)
{
@@ -271,8 +286,8 @@ public:
{
option.var_type= GET_ENUM;
global_var(ulong)= def_val;
- DBUG_ASSERT(def_val < typelib.count);
- DBUG_ASSERT(size == sizeof(ulong));
+ SYSVAR_ASSERT(def_val < typelib.count);
+ SYSVAR_ASSERT(size == sizeof(ulong));
}
bool session_update(THD *thd, set_var *var)
{
@@ -318,9 +333,9 @@ public:
{
option.var_type= GET_BOOL;
global_var(my_bool)= def_val;
- DBUG_ASSERT(def_val < 2);
- DBUG_ASSERT(getopt.arg_type == OPT_ARG || getopt.id == -1);
- DBUG_ASSERT(size == sizeof(my_bool));
+ SYSVAR_ASSERT(def_val < 2);
+ SYSVAR_ASSERT(getopt.arg_type == OPT_ARG || getopt.id == -1);
+ SYSVAR_ASSERT(size == sizeof(my_bool));
}
bool session_update(THD *thd, set_var *var)
{
@@ -379,8 +394,8 @@ public:
*/
option.var_type= (flags & ALLOCATED) ? GET_STR_ALLOC : GET_STR;
global_var(const char*)= def_val;
- DBUG_ASSERT(scope() == GLOBAL);
- DBUG_ASSERT(size == sizeof(char *));
+ SYSVAR_ASSERT(scope() == GLOBAL);
+ SYSVAR_ASSERT(size == sizeof(char *));
}
void cleanup()
{
@@ -537,7 +552,7 @@ public:
on_check_func, on_update_func, deprecated_version, substitute)
{
global_var(LEX_STRING).length= strlen(def_val);
- DBUG_ASSERT(size == sizeof(LEX_STRING));
+ SYSVAR_ASSERT(size == sizeof(LEX_STRING));
*const_cast<SHOW_TYPE*>(&show_val_type)= SHOW_LEX_STRING;
}
bool global_update(THD *thd, set_var *var)
@@ -665,7 +680,7 @@ public:
option.var_type|= GET_ASK_ADDR;
option.value= (uchar**)1; // crash me, please
keycache_var(dflt_key_cache, off)= def_val;
- DBUG_ASSERT(scope() == GLOBAL);
+ SYSVAR_ASSERT(scope() == GLOBAL);
}
bool global_update(THD *thd, set_var *var)
{
@@ -825,10 +840,10 @@ public:
option.min_value= (longlong) double2ulonglong(min_val);
option.max_value= (longlong) double2ulonglong(max_val);
global_var(double)= (double)option.def_value;
- DBUG_ASSERT(min_val < max_val);
- DBUG_ASSERT(min_val <= def_val);
- DBUG_ASSERT(max_val >= def_val);
- DBUG_ASSERT(size == sizeof(double));
+ SYSVAR_ASSERT(min_val < max_val);
+ SYSVAR_ASSERT(min_val <= def_val);
+ SYSVAR_ASSERT(max_val >= def_val);
+ SYSVAR_ASSERT(size == sizeof(double));
}
bool do_check(THD *thd, set_var *var)
{
@@ -928,11 +943,11 @@ public:
{
option.var_type= GET_FLAGSET;
global_var(ulonglong)= def_val;
- DBUG_ASSERT(typelib.count > 1);
- DBUG_ASSERT(typelib.count <= 65);
- DBUG_ASSERT(def_val < MAX_SET(typelib.count));
- DBUG_ASSERT(strcmp(values[typelib.count-1], "default") == 0);
- DBUG_ASSERT(size == sizeof(ulonglong));
+ SYSVAR_ASSERT(typelib.count > 1);
+ SYSVAR_ASSERT(typelib.count <= 65);
+ SYSVAR_ASSERT(def_val < MAX_SET(typelib.count));
+ SYSVAR_ASSERT(strcmp(values[typelib.count-1], "default") == 0);
+ SYSVAR_ASSERT(size == sizeof(ulonglong));
}
bool do_check(THD *thd, set_var *var)
{
@@ -1039,10 +1054,10 @@ public:
{
option.var_type= GET_SET;
global_var(ulonglong)= def_val;
- DBUG_ASSERT(typelib.count > 0);
- DBUG_ASSERT(typelib.count <= 64);
- DBUG_ASSERT(def_val <= MAX_SET(typelib.count));
- DBUG_ASSERT(size == sizeof(ulonglong));
+ SYSVAR_ASSERT(typelib.count > 0);
+ SYSVAR_ASSERT(typelib.count <= 64);
+ SYSVAR_ASSERT(def_val <= MAX_SET(typelib.count));
+ SYSVAR_ASSERT(size == sizeof(ulonglong));
}
bool do_check(THD *thd, set_var *var)
{
@@ -1145,8 +1160,8 @@ public:
plugin_type(plugin_type_arg)
{
option.var_type= GET_STR;
- DBUG_ASSERT(size == sizeof(plugin_ref));
- DBUG_ASSERT(getopt.id == -1); // force NO_CMD_LINE
+ SYSVAR_ASSERT(size == sizeof(plugin_ref));
+ SYSVAR_ASSERT(getopt.id == -1); // force NO_CMD_LINE
}
bool do_check(THD *thd, set_var *var)
{
@@ -1256,7 +1271,7 @@ public:
lock, binlog_status_arg, on_check_func, on_update_func,
deprecated_version, substitute)
{
- DBUG_ASSERT(scope() == ONLY_SESSION);
+ SYSVAR_ASSERT(scope() == ONLY_SESSION);
option.var_type= GET_NO_ARG;
}
bool do_check(THD *thd, set_var *var)
@@ -1352,9 +1367,9 @@ public:
reverse_semantics= my_count_bits(bitmask_arg) > 1;
bitmask= reverse_semantics ? ~bitmask_arg : bitmask_arg;
set(global_var_ptr(), def_val);
- DBUG_ASSERT(def_val < 2);
- DBUG_ASSERT(getopt.id == -1); // force NO_CMD_LINE
- DBUG_ASSERT(size == sizeof(ulonglong));
+ SYSVAR_ASSERT(def_val < 2);
+ SYSVAR_ASSERT(getopt.id == -1); // force NO_CMD_LINE
+ SYSVAR_ASSERT(size == sizeof(ulonglong));
}
bool session_update(THD *thd, set_var *var)
{
@@ -1422,8 +1437,8 @@ public:
deprecated_version, substitute),
read_func(read_func_arg), update_func(update_func_arg)
{
- DBUG_ASSERT(scope() == ONLY_SESSION);
- DBUG_ASSERT(getopt.id == -1); // NO_CMD_LINE, because the offset is fake
+ SYSVAR_ASSERT(scope() == ONLY_SESSION);
+ SYSVAR_ASSERT(getopt.id == -1); // NO_CMD_LINE, because the offset is fake
}
bool session_update(THD *thd, set_var *var)
{ return update_func(thd, var); }
@@ -1472,8 +1487,8 @@ public:
deprecated_version, substitute),
read_func(read_func_arg), update_func(update_func_arg)
{
- DBUG_ASSERT(scope() == ONLY_SESSION);
- DBUG_ASSERT(getopt.id == -1); // NO_CMD_LINE, because the offset is fake
+ SYSVAR_ASSERT(scope() == ONLY_SESSION);
+ SYSVAR_ASSERT(getopt.id == -1); // NO_CMD_LINE, because the offset is fake
}
bool session_update(THD *thd, set_var *var)
{ return update_func(thd, var); }
@@ -1525,13 +1540,13 @@ public:
lock, binlog_status_arg, on_check_func, on_update_func,
deprecated_version, substitute)
{
- DBUG_ASSERT(scope() == GLOBAL);
- DBUG_ASSERT(getopt.id == -1);
- DBUG_ASSERT(lock == 0);
- DBUG_ASSERT(binlog_status_arg == VARIABLE_NOT_IN_BINLOG);
- DBUG_ASSERT(is_readonly());
- DBUG_ASSERT(on_update == 0);
- DBUG_ASSERT(size == sizeof(enum SHOW_COMP_OPTION));
+ SYSVAR_ASSERT(scope() == GLOBAL);
+ SYSVAR_ASSERT(getopt.id == -1);
+ SYSVAR_ASSERT(lock == 0);
+ SYSVAR_ASSERT(binlog_status_arg == VARIABLE_NOT_IN_BINLOG);
+ SYSVAR_ASSERT(is_readonly());
+ SYSVAR_ASSERT(on_update == 0);
+ SYSVAR_ASSERT(size == sizeof(enum SHOW_COMP_OPTION));
}
bool do_check(THD *thd, set_var *var) {
DBUG_ASSERT(FALSE);
@@ -1603,8 +1618,8 @@ public:
thus all struct command-line options should be added manually
to my_long_options in mysqld.cc
*/
- DBUG_ASSERT(getopt.id == -1);
- DBUG_ASSERT(size == sizeof(void *));
+ SYSVAR_ASSERT(getopt.id == -1);
+ SYSVAR_ASSERT(size == sizeof(void *));
}
bool do_check(THD *thd, set_var *var)
{ return false; }
@@ -1665,8 +1680,8 @@ public:
lock, binlog_status_arg, on_check_func, on_update_func,
deprecated_version, substitute)
{
- DBUG_ASSERT(getopt.id == -1);
- DBUG_ASSERT(size == sizeof(Time_zone *));
+ SYSVAR_ASSERT(getopt.id == -1);
+ SYSVAR_ASSERT(size == sizeof(Time_zone *));
}
bool do_check(THD *thd, set_var *var)
{
diff --git a/sql/table.cc b/sql/table.cc
index a157dbeb15a..07fae7329c8 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1068,14 +1068,13 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
#endif
next_chunk+= 5 + partition_info_str_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++)
@@ -5571,10 +5570,11 @@ void 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
@@ -5582,9 +5582,11 @@ void TABLE::mark_virtual_columns_for_write(bool insert_fl)
bool TABLE::alloc_keys(uint key_count)
{
- key_info= s->key_info= (KEY*) alloc_root(&mem_root, sizeof(KEY)*key_count);
- s->keys= 0;
- 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);
}
@@ -5729,7 +5731,7 @@ void TABLE::use_index(int key_to_save)
/* Drop all keys; */
i= 0;
- s->keys= (key_to_save < 0) ? 0 : 1;
+ s->keys= i;
}
/*
@@ -6094,7 +6096,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/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 50b7bf9f5d1..0b58afc23c9 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -156,10 +156,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,
/*
@@ -397,7 +403,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;
}
@@ -405,6 +411,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,
@@ -423,8 +431,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;
}
@@ -1018,8 +1029,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();
}
@@ -2151,13 +2161,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;
}
thd->set_query(query_backup);
DBUG_RETURN(error);
@@ -2480,9 +2494,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)
@@ -2542,6 +2553,14 @@ void ha_maria::drop_table(const char *name)
}
+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");
@@ -2641,7 +2660,7 @@ int ha_maria::external_lock(THD *thd, int lock_type)
changes to commit (rollback shouldn't be tested).
*/
DBUG_ASSERT(!thd->stmt_da->is_sent ||
- thd->killed == THD::KILL_CONNECTION);
+ thd->killed == KILL_CONNECTION);
/* autocommit ? rollback a transaction */
#ifdef MARIA_CANNOT_ROLLBACK
if (ma_commit(trn))
@@ -3484,7 +3503,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
@@ -3519,6 +3538,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),
@@ -3552,6 +3572,7 @@ static void update_checkpoint_interval(MYSQL_THD thd,
ma_checkpoint_init(*(ulong *)var_ptr= (ulong)(*(long *)save));
}
+
/**
@brief Updates group commit mode
*/
@@ -3729,9 +3750,6 @@ Item *ha_maria::idx_cond_push(uint keyno_arg, Item* idx_cond_arg)
return NULL;
}
-
-
-
struct st_mysql_storage_engine maria_storage_engine=
{ MYSQL_HANDLERTON_INTERFACE_VERSION };
diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h
index 39c23c8d1b6..dba0aeaa20e 100644
--- a/storage/maria/ha_maria.h
+++ b/storage/maria/ha_maria.h
@@ -78,6 +78,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 483a7dd5c12..76049a54238 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -286,7 +286,7 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file,
*/
{
pgcache_page_no_t last_bitmap_page;
- ulong blocks, bytes;
+ pgcache_page_no_t blocks, bytes;
last_bitmap_page= *last_page - *last_page % bitmap->pages_covered;
blocks= *last_page - last_bitmap_page;
@@ -1415,7 +1415,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, UNINIT_VAR(best_prefix_area_size), best_suffix_area_size;
+ uint best_area_size, UNINIT_VAR(best_prefix_area_size);
uint page, size;
ulonglong UNINIT_VAR(best_prefix_bits);
DBUG_ENTER("allocate_full_pages");
@@ -1491,7 +1491,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)
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 2d2a770ba82..371325594af 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -5004,7 +5004,8 @@ 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;
+ uint field_lengths __attribute__ ((unused));
uchar *extents, *end;
DBUG_ENTER("read_row_extent_info");
@@ -5039,6 +5040,10 @@ static my_bool read_row_extent_info(MARIA_HA *info, uchar *buff,
}
info->cur_row.extents_count= row_extents;
+ /*
+ field_lengths looks unused but get_key_length will
+ increment data, which is required as data it's used later.
+ */
if (share->base.max_field_lengths)
get_key_length(field_lengths, data);
@@ -5327,7 +5332,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");
@@ -5457,7 +5461,6 @@ 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(info->scan.bitmap_page >= info->scan.max_page))
{
DBUG_PRINT("info", ("Found end of file"));
@@ -6737,11 +6740,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;
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 7f686c28532..4d60b4cafe5 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -2343,7 +2343,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 */
@@ -2363,6 +2363,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);
@@ -5660,7 +5668,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 */
@@ -5673,7 +5682,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;
@@ -5741,7 +5750,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);
@@ -5852,7 +5860,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;
@@ -5869,7 +5877,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)
diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c
index dd188501f4e..addb014969a 100644
--- a/storage/maria/ma_checkpoint.c
+++ b/storage/maria/ma_checkpoint.c
@@ -534,8 +534,9 @@ filter_flush_file_evenly(enum pagecache_page_type type,
risk could be that while a checkpoint happens no LRD flushing happens.
*/
-static uint maria_checkpoint_min_activity= 2*1024*1024;
-
+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)
{
@@ -576,53 +577,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
- maria_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) < maria_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;
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 5be819f341b..2173d2cac8f 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -621,7 +621,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;
diff --git a/storage/maria/ma_dynrec.c b/storage/maria/ma_dynrec.c
index 70ecac318cc..c1c0a8e9729 100644
--- a/storage/maria/ma_dynrec.c
+++ b/storage/maria/ma_dynrec.c
@@ -1734,14 +1734,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 *UNINIT_VAR(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
if (info->lock_type == F_UNLCK)
{
@@ -1750,8 +1755,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;
diff --git a/storage/maria/ma_ft_update.c b/storage/maria/ma_ft_update.c
index 3e47f09c1fa..99748c65ebf 100644
--- a/storage/maria/ma_ft_update.c
+++ b/storage/maria/ma_ft_update.c
@@ -363,7 +363,7 @@ my_bool _ma_ft_convert_to_ft2(MARIA_HA *info, MARIA_KEY *key)
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))
+ if (_ma_ck_real_write_btree(info, &tmp_key, &root, SEARCH_SAME))
DBUG_RETURN(1);
}
diff --git a/storage/maria/ma_info.c b/storage/maria/ma_info.c
index 361ee41f2c8..fdd9ba7d2c6 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 920f5a08013..9c794501022 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_loghandler.c b/storage/maria/ma_loghandler.c
index f437bf1399f..b3e4acb2995 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -2612,14 +2612,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;
+ TRANSLOG_ADDRESS addr __attribute__((unused))= (buffer->offset + i);
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,
(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)
@@ -6568,16 +6566,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;
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index d545ed76592..82e6e30839b 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -469,7 +469,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));
@@ -1861,7 +1861,7 @@ int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share, const char *org_name,
}
info->dfile.file= share->bitmap.file.file=
- mysql_file_open(key_file_dfile, share->data_file_name.str,
+ mysql_file_open(key_file_dfile, data_name,
share->mode | O_SHARE, MYF(MY_WME));
return info->dfile.file >= 0 ? 0 : 1;
}
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index b0ad778a4f2..893e393a79a 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -3216,9 +3216,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;
}
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/maria_def.h b/storage/maria/maria_def.h
index cd3294e8975..25c09e8de33 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -738,7 +738,7 @@ struct st_maria_handler
{ length=mi_uint2korr((key)+1)+3; } \
}
-#define maria_max_key_length() ((maria_block_size - MAX_KEYPAGE_HEADER_SIZE)/3 - 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)
@@ -817,6 +817,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 *);
diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c
index 4480dabbcad..481b77a2cc6 100644
--- a/storage/maria/maria_pack.c
+++ b/storage/maria/maria_pack.c
@@ -3051,7 +3051,6 @@ static int mrg_rrnd(PACK_MRG_INFO *info,uchar *buf)
{
int error;
MARIA_HA *isam_info;
- my_off_t filepos;
if (!info->current)
{
@@ -3076,7 +3075,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/trnman.c b/storage/maria/trnman.c
index 0f02976dbb4..0734e12cbe4 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 fd3e3f909ce..ba7c8d324f0 100644
--- a/storage/maria/unittest/CMakeLists.txt
+++ b/storage/maria/unittest/CMakeLists.txt
@@ -13,7 +13,6 @@
# 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(aria myisam mytap mysys dbug strings ${ZLIB_LIBRARY})
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 25020e76c7f..8fde949189b 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -146,14 +146,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) -
@@ -178,7 +180,7 @@ static void mi_check_print_msg(HA_CHECK *param, const char* msg_type,
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", msgbuf);
+ sql_print_error("%s.%s: %s", param->db_name, param->table_name, msgbuf);
if (param->need_print_msg_lock)
mysql_mutex_unlock(&param->print_msg_mutex);
@@ -579,6 +581,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);
}
@@ -640,7 +643,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 |
@@ -1581,7 +1583,10 @@ 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);
+ 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];
@@ -1599,6 +1604,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(query_backup);
DBUG_RETURN(error);
@@ -1858,9 +1864,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);
@@ -1892,6 +1895,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 0de25c6d355..c3c236ad4fe 100644
--- a/storage/myisam/ha_myisam.h
+++ b/storage/myisam/ha_myisam.h
@@ -76,7 +76,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 10c0567e508..05fd9af9079 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -938,7 +938,7 @@ static uint isam_key_length(MI_INFO *info, register MI_KEYDEF *keyinfo)
int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend)
{
int error,got_error,flag;
- uint key,UNINIT_VAR(left_length),b_type,field;
+ uint key, UNINIT_VAR(left_length), b_type;
ha_rows records,del_blocks;
my_off_t used,empty,pos,splits,UNINIT_VAR(start_recpos),
del_length,link_used,start_block;
@@ -946,7 +946,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");
@@ -970,21 +969,6 @@ int chk_data_link(HA_CHECK *param, MI_INFO *info, my_bool extend)
got_error=error=0;
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++)
- {
- if (info->s->rec[field].base_type == FIELD_BLOB ||
- info->s->rec[field].base_type == FIELD_VARCHAR)
- {
- static_row_size=0;
- break;
- }
- }
- }
-
pos=my_b_tell(&param->read_cache);
bzero((char*) key_checksum, info->s->base.keys * sizeof(key_checksum[0]));
while (pos < info->state->data_file_length)
@@ -1343,7 +1327,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)
{
@@ -1536,6 +1520,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))
{
@@ -1678,7 +1664,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;
@@ -1907,7 +1893,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)
@@ -2216,7 +2202,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");
@@ -2232,12 +2218,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,
@@ -2249,7 +2238,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;
@@ -2419,7 +2408,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. */
@@ -2448,7 +2440,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;
}
}
@@ -2478,7 +2473,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;
@@ -2550,6 +2545,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;
@@ -2645,6 +2642,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;
@@ -3077,6 +3077,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;
@@ -3111,7 +3113,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,
@@ -3228,7 +3236,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:
@@ -3314,6 +3327,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;
@@ -3375,6 +3390,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;
@@ -3415,7 +3431,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;
@@ -3449,6 +3469,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
@@ -3530,8 +3551,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);
@@ -3557,6 +3576,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;
}
@@ -3628,6 +3648,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 */
}
@@ -3686,7 +3707,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;
diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c
index 5906c9dc70a..9270ee4fbb8 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 72be3d2f810..6f27b1bc0d2 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -1719,6 +1719,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/sort.c b/storage/myisam/sort.c
index cc05121f164..da65ddb7be6 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/ndb/plug.in b/storage/ndb/plug.in
index 04e618923e4..349c0660a1c 100644
--- a/storage/ndb/plug.in
+++ b/storage/ndb/plug.in
@@ -2,7 +2,6 @@ sinclude(storage/ndb/ndb_configure.m4)
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/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 1aec6426c8a..f574dbd362a 100644
--- a/storage/pbxt/src/ha_pbxt.cc
+++ b/storage/pbxt/src/ha_pbxt.cc
@@ -1596,7 +1596,7 @@ static int pbxt_rollback(handlerton *hton, THD *thd, bool all)
if (!all)
self->st_stat_trans = FALSE;
}
- return 0;
+ return err;
}
#ifdef DRIZZLED
@@ -2904,11 +2904,9 @@ 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;
my_bitmap_map *old_map;
old_map = mx_tmp_use_all_columns(table, table->read_set);
- nr = table->found_next_number_field->val_int();
ha_set_auto_increment(pb_open_tab, table->found_next_number_field);
mx_tmp_restore_column_map(table, old_map);
}
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 7fd94aeaef7..f04138bd10f 100644
--- a/storage/pbxt/src/myxt_xt.cc
+++ b/storage/pbxt/src/myxt_xt.cc
@@ -836,7 +836,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
@@ -849,7 +852,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++)
@@ -1027,7 +1032,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 */
@@ -1512,7 +1518,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;
@@ -1892,7 +1898,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/restart_xt.cc b/storage/pbxt/src/restart_xt.cc
index 162ec90d754..54454ac92c5 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 443fc3ee193..7c243d26f9b 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 1addf487153..9e3261bc8e0 100644
--- a/storage/pbxt/src/thread_xt.cc
+++ b/storage/pbxt/src/thread_xt.cc
@@ -488,8 +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;
}
@@ -1178,7 +1178,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 ce94b675af4..8abff2003be 100644
--- a/storage/sphinx/ha_sphinx.cc
+++ b/storage/sphinx/ha_sphinx.cc
@@ -705,7 +705,7 @@ static int sphinx_done_func ( void * )
pthread_mutex_destroy ( &sphinx_mutex );
}
- SPH_RET(0);
+ SPH_RET(error);
}
diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c
index f6ef44e5b5c..20876e73da0 100644
--- a/storage/xtradb/btr/btr0cur.c
+++ b/storage/xtradb/btr/btr0cur.c
@@ -3598,7 +3598,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 */
@@ -3618,9 +3618,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/dict/dict0dict.c b/storage/xtradb/dict/dict0dict.c
index 1ad540f47ab..e1b29fa02b0 100644
--- a/storage/xtradb/dict/dict0dict.c
+++ b/storage/xtradb/dict/dict0dict.c
@@ -484,10 +484,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;
@@ -509,7 +511,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 7cf212d28ae..e0a4f77ddd6 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -122,11 +122,6 @@ static mysql_cond_t commit_cond;
static mysql_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
@@ -2305,14 +2300,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;
+ }
}
/*****************************************************************//**
@@ -2367,7 +2372,7 @@ ha_innobase::init_table_handle_for_HANDLER(void)
we???? */
prebuilt->used_in_HANDLER = TRUE;
- reset_template(prebuilt);
+ reset_template();
}
/*********************************************************************//**
@@ -4525,8 +4530,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]));
}
@@ -5088,44 +5093,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 = DATA_MBMINLEN(col->mbminmaxlen);
+ templ->mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen);
+ 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) {
@@ -5142,7 +5273,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) {
@@ -5159,21 +5290,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) {
@@ -5181,160 +5304,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++) {
- const dict_col_t* col = &index->table->cols[innodb_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(
- col, 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]);
-
- templ->mysql_null_bit_mask = (ulint) field->null_bit;
- } else {
- templ->mysql_null_bit_mask = 0;
- }
+ prebuilt->idx_cond = this;
+ } else {
+ /* No index condition pushdown */
+ prebuilt->idx_cond = NULL;
- templ->mysql_col_offset = (ulint)
- get_field_offset(table, field);
+ for (i = 0, sql_idx = 0; i < n_stored_fields; i++, sql_idx++) {
+ const Field* field;
- 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 = col->mtype;
- templ->mysql_type = (ulint)field->type();
+ while (!table->field[sql_idx]->stored_in_db) {
+ sql_idx++;
+ }
- 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(col->prtype);
- templ->mbminlen = dict_col_get_mbminlen(col);
- templ->mbmaxlen = dict_col_get_mbmaxlen(col);
- templ->is_unsigned = col->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;
}
}
@@ -5597,7 +5766,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);
@@ -6298,8 +6467,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) {
@@ -6514,7 +6682,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);
}
@@ -7439,7 +7607,7 @@ ha_innobase::create(
if (srv_file_per_table
&& !mysqld_embedded
- && (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
+ && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
if ((name[1] == ':')
|| (name[0] == '\\' && name[1] == '\\')) {
@@ -8908,7 +9076,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) {
@@ -9463,12 +9631,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;
@@ -9514,14 +9677,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. */
@@ -9571,7 +9728,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
@@ -9679,7 +9836,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) {
@@ -9855,7 +10012,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;
@@ -12637,39 +12794,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 f368d08f954..628ba536eb9 100644
--- a/storage/xtradb/handler/ha_innodb.h
+++ b/storage/xtradb/handler/ha_innodb.h
@@ -227,27 +227,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 d99177e0330..28d4413b568 100644
--- a/storage/xtradb/include/dict0dict.h
+++ b/storage/xtradb/include/dict0dict.h
@@ -884,13 +884,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 b03f5117295..4ec82220ffb 100644
--- a/storage/xtradb/include/dict0dict.ic
+++ b/storage/xtradb/include/dict0dict.ic
@@ -694,6 +694,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 02e7712df58..61ec644796b 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -256,6 +256,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/row0mysql.h b/storage/xtradb/include/row0mysql.h
index a75aea1d046..69e59ae120f 100644
--- a/storage/xtradb/include/row0mysql.h
+++ b/storage/xtradb/include/row0mysql.h
@@ -558,6 +558,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
@@ -596,16 +600,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 (*idx_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. */
@@ -803,16 +797,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 */
- /*----------------------*/
- idx_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/os/os0file.c b/storage/xtradb/os/os0file.c
index ee8ee34ea49..8fe8bab5d9a 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -3915,7 +3915,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;
@@ -4655,7 +4655,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/row/row0sel.c b/storage/xtradb/row/row0sel.c
index 1d91b1f4b53..ef5e30ea16d 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
@@ -2667,144 +2669,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(rec) */
- 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++) {
+ if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) {
- 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;
+ mem_heap_t* heap;
+ /* Copy an externally stored field to a temporary heap */
- if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) {
+ ut_a(!prebuilt->trx->has_search_latch);
+ ut_ad(field_no == templ->clust_rec_field_no);
- /* Copy an externally stored field to the temporary
- heap */
+ if (UNIV_UNLIKELY(templ->type == DATA_BLOB)) {
+ if (prebuilt->blob_heap == NULL) {
+ prebuilt->blob_heap = mem_heap_create(
+ UNIV_PAGE_SIZE);
+ }
- ut_a(!prebuilt->trx->has_search_latch);
+ heap = prebuilt->blob_heap;
+ } else {
+ 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);
- }
+ /* NOTE: if we are retrieving a big BLOB, we may
+ already run out of memory in the next call, which
+ causes an assert */
- heap = prebuilt->blob_heap;
- } else {
- extern_field_heap
- = mem_heap_create(UNIV_PAGE_SIZE);
+ data = btr_rec_copy_externally_stored_field(
+ rec, offsets,
+ dict_table_zip_size(prebuilt->table),
+ field_no, &len, heap);
- heap = 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. */
- /* 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);
- }
-
- 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);
-
- if (UNIV_UNLIKELY(templ->type == DATA_BLOB)
- && len != UNIV_SQL_NULL) {
+ ut_a(prebuilt->trx->isolation_level
+ == TRX_ISO_READ_UNCOMMITTED);
+ return(FALSE);
+ }
- /* 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. */
+ ut_a(len != UNIV_SQL_NULL);
- if (prebuilt->blob_heap == NULL) {
- prebuilt->blob_heap = mem_heap_create(
- UNIV_PAGE_SIZE);
- }
+ row_sel_field_store_in_mysql_format(
+ mysql_rec + templ->mysql_col_offset,
+ templ, data, len);
- 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,
@@ -2815,6 +2769,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);
}
}
@@ -3185,31 +3218,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(rec) */
- 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
@@ -3229,46 +3250,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;
-
- 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);
- }
+ memcpy(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
+ mysql_rec, prebuilt->mysql_row_len);
- 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);
}
@@ -3346,6 +3335,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
@@ -3410,10 +3474,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;
+ ibool problematic_use = FALSE;
rec_offs_init(offsets_);
@@ -3715,10 +3777,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
@@ -3729,13 +3805,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);
@@ -3747,6 +3822,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);
@@ -3849,8 +3925,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"
@@ -4321,6 +4398,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);
@@ -4331,19 +4418,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:
@@ -4402,8 +4477,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;
}
}
}
@@ -4448,38 +4542,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
@@ -4543,6 +4630,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;
}
@@ -4576,15 +4676,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
@@ -4592,14 +4687,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)) {
@@ -4620,16 +4711,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
@@ -4638,8 +4724,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;
}
}
@@ -4657,7 +4741,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
@@ -4681,7 +4764,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;
@@ -4692,6 +4774,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/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/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/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>